firebase-tools 15.13.0 → 15.14.1-main.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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ALLOWED_DEPLOY_METHODS = exports.DEFAULT_DEPLOY_METHOD = exports.DEFAULT_LOCATION = void 0;
4
- exports.DEFAULT_LOCATION = "us-central1";
4
+ exports.DEFAULT_LOCATION = "us-east4";
5
5
  exports.DEFAULT_DEPLOY_METHOD = "github";
6
6
  exports.ALLOWED_DEPLOY_METHODS = [{ name: "Deploy using github", value: "github" }];
package/lib/command.js CHANGED
@@ -111,22 +111,23 @@ class Command {
111
111
  });
112
112
  }
113
113
  const duration = Math.floor((process.uptime() - start) * 1000);
114
- const trackSuccess = (0, track_1.trackGA4)("command_execution", {
115
- command_name: this.name,
116
- result: "success",
117
- interactive: (0, utils_1.getInheritedOption)(options, "nonInteractive") ? "false" : "true",
118
- }, duration);
119
- if (!isEmulator) {
120
- await (0, utils_1.withTimeout)(5000, trackSuccess);
121
- }
122
- else {
123
- await (0, utils_1.withTimeout)(5000, Promise.all([
124
- trackSuccess,
125
- (0, track_1.trackEmulator)("command_success", {
114
+ try {
115
+ const trackSuccess = (0, track_1.trackGA4)("command_execution", {
116
+ command_name: this.name,
117
+ result: "success",
118
+ interactive: (0, utils_1.getInheritedOption)(options, "nonInteractive") ? "false" : "true",
119
+ }, duration);
120
+ const tracks = [trackSuccess];
121
+ if (isEmulator) {
122
+ tracks.push((0, track_1.trackEmulator)("command_success", {
126
123
  command_name: this.name,
127
124
  duration,
128
- }),
129
- ]));
125
+ }));
126
+ }
127
+ await (0, utils_1.withTimeout)(1000, Promise.all(tracks));
128
+ }
129
+ catch (gaErr) {
130
+ logger_1.logger.debug("Analytics tracking failed during success path:", gaErr);
130
131
  }
131
132
  process.exit();
132
133
  })
@@ -140,20 +141,25 @@ class Command {
140
141
  });
141
142
  }
142
143
  const duration = Math.floor((process.uptime() - start) * 1000);
143
- await (0, utils_1.withTimeout)(5000, Promise.all([
144
- (0, track_1.trackGA4)("command_execution", {
144
+ try {
145
+ const trackError = (0, track_1.trackGA4)("command_execution", {
145
146
  command_name: this.name,
146
147
  result: "error",
147
148
  interactive: (0, utils_1.getInheritedOption)(options, "nonInteractive") ? "false" : "true",
148
- }, duration),
149
- isEmulator
150
- ? (0, track_1.trackEmulator)("command_error", {
149
+ }, duration);
150
+ const tracks = [trackError];
151
+ if (isEmulator) {
152
+ tracks.push((0, track_1.trackEmulator)("command_error", {
151
153
  command_name: this.name,
152
154
  duration,
153
- error_type: err.exit === 1 ? "user" : "unexpected",
154
- })
155
- : Promise.resolve(),
156
- ]));
155
+ error_type: err?.exit === 1 ? "user" : "unexpected",
156
+ }));
157
+ }
158
+ await (0, utils_1.withTimeout)(1000, Promise.all(tracks));
159
+ }
160
+ catch (gaErr) {
161
+ logger_1.logger.debug("Analytics tracking failed during error path:", gaErr);
162
+ }
157
163
  client.errorOut(err);
158
164
  });
159
165
  });
@@ -178,6 +184,13 @@ class Command {
178
184
  if ((0, utils_1.getInheritedOption)(options, "config")) {
179
185
  options.configPath = (0, utils_1.getInheritedOption)(options, "config");
180
186
  }
187
+ const onlyOption = (0, utils_1.getInheritedOption)(options, "only");
188
+ if (onlyOption) {
189
+ options.only = onlyOption
190
+ .split(/[\s,]+/)
191
+ .filter(Boolean)
192
+ .join(",");
193
+ }
181
194
  try {
182
195
  options.config = config_1.Config.load(options);
183
196
  }
@@ -169,7 +169,9 @@ async function prepare(context, options, payload) {
169
169
  const exportType = backend.someEndpoint(wantBackend, (e) => e.platform === "run")
170
170
  ? "tar.gz"
171
171
  : "zip";
172
- const packagedSource = await (0, prepareFunctionsUpload_1.prepareFunctionsUpload)(options.config.projectDir, sourceDir, localCfg, [...schPathSet], undefined, { exportType });
172
+ const isDart = supported.runtimeIsLanguage(wantBuilds[codebase].runtime, "dart");
173
+ const executablePaths = isDart ? ["bin/server"] : [];
174
+ const packagedSource = await (0, prepareFunctionsUpload_1.prepareFunctionsUpload)(options.config.projectDir, sourceDir, localCfg, [...schPathSet], undefined, { exportType, executablePaths });
173
175
  source.functionsSourceV2 = packagedSource?.pathToSource;
174
176
  source.functionsSourceV2Hash = packagedSource?.hash;
175
177
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getFunctionsConfig = getFunctionsConfig;
4
+ exports.addFilesToArchive = addFilesToArchive;
4
5
  exports.prepareFunctionsUpload = prepareFunctionsUpload;
5
6
  exports.convertToSortedKeyValueArray = convertToSortedKeyValueArray;
6
7
  const archiver = require("archiver");
@@ -45,6 +46,24 @@ async function pipeAsync(from, to) {
45
46
  to.on("error", reject);
46
47
  });
47
48
  }
49
+ async function addFilesToArchive(archive, files, sourceDir, executablePaths) {
50
+ const hashes = [];
51
+ for (const file of files) {
52
+ const name = path.relative(sourceDir, file.name);
53
+ const normalizedName = name.split(path.sep).join("/");
54
+ const fileHash = await (0, hash_1.getSourceHash)(file.name);
55
+ hashes.push(fileHash);
56
+ let mode = file.mode;
57
+ if (executablePaths?.includes(normalizedName)) {
58
+ mode = 0o755;
59
+ }
60
+ archive.file(file.name, {
61
+ name: normalizedName,
62
+ mode,
63
+ });
64
+ }
65
+ return hashes;
66
+ }
48
67
  async function packageSource(projectDir, sourceDir, config, additionalSources, runtimeConfig, options) {
49
68
  const exportType = options?.exportType || "zip";
50
69
  const postfix = `.${exportType}`;
@@ -60,15 +79,7 @@ async function packageSource(projectDir, sourceDir, config, additionalSources, r
60
79
  ignore.push("firebase-debug.log", "firebase-debug.*.log", CONFIG_DEST_FILE);
61
80
  try {
62
81
  const files = await fsAsync.readdirRecursive({ path: sourceDir, ignore: ignore });
63
- for (const file of files) {
64
- const name = path.relative(sourceDir, file.name);
65
- const fileHash = await (0, hash_1.getSourceHash)(file.name);
66
- hashes.push(fileHash);
67
- archive.file(file.name, {
68
- name,
69
- mode: file.mode,
70
- });
71
- }
82
+ hashes.push(...(await addFilesToArchive(archive, files, sourceDir, options?.executablePaths)));
72
83
  for (const name of additionalSources) {
73
84
  const absPath = utils.resolveWithin(projectDir, name);
74
85
  if (!fs.existsSync(absPath)) {
@@ -18,6 +18,7 @@ const error_1 = require("../../../error");
18
18
  const getProjectNumber_1 = require("../../../getProjectNumber");
19
19
  const extensions_1 = require("../../extensions");
20
20
  const artifacts = require("../../../functions/artifacts");
21
+ const supported_1 = require("../runtimes/supported");
21
22
  async function release(context, options, payload) {
22
23
  if (context.extensions && payload.extensions) {
23
24
  await (0, extensions_1.release)(context.extensions, options, payload.extensions);
@@ -88,6 +89,10 @@ async function release(context, options, payload) {
88
89
  reporter.printErrors(summary);
89
90
  const wantBackend = backend.merge(...Object.values(payload.functions).map((p) => p.wantBackend));
90
91
  printTriggerUrls(wantBackend, projectNumber);
92
+ if (backend.someEndpoint(wantBackend, (endpoint) => (0, supported_1.runtimeIsLanguage)(endpoint.runtime, "dart"))) {
93
+ utils.logLabeledBullet("functions", "Dart functions may not yet be visible in the Firebase Console. " +
94
+ `View them in the Cloud Console at https://console.cloud.google.com/run/services?project=${context.projectId}`);
95
+ }
91
96
  await setupArtifactCleanupPolicies(options, options.projectId, Object.keys(wantBackend.endpoints));
92
97
  const allErrors = summary.results.filter((r) => r.error).map((r) => r.error);
93
98
  if (allErrors.length) {
@@ -13,12 +13,14 @@ const error_1 = require("../../../../error");
13
13
  const utils_1 = require("../../../../utils");
14
14
  const registry_1 = require("../../../../emulator/registry");
15
15
  const types_1 = require("../../../../emulator/types");
16
+ const experiments = require("../../../../experiments");
16
17
  async function tryCreateDelegate(context) {
17
18
  const pubspecYamlPath = path.join(context.sourceDir, "pubspec.yaml");
18
19
  if (!(await (0, util_1.promisify)(fs.exists)(pubspecYamlPath))) {
19
20
  logger_1.logger.debug("Customer code is not Dart code.");
20
21
  return;
21
22
  }
23
+ experiments.assertEnabled("dartfunctions", "use Dart functions");
22
24
  const runtime = context.runtime ?? supported.latest("dart");
23
25
  if (!supported.isRuntime(runtime)) {
24
26
  throw new error_1.FirebaseError(`Runtime ${runtime} is not a valid Dart runtime`);
@@ -7,13 +7,10 @@ const python = require("./python");
7
7
  const validate = require("../validate");
8
8
  const error_1 = require("../../../error");
9
9
  const supported = require("./supported");
10
- const experiments = require("../../../experiments");
11
10
  const factories = [
12
11
  node.tryCreateDelegate,
13
12
  python.tryCreateDelegate,
14
- (ctx) => experiments.isEnabled("functionsrunapionly")
15
- ? dart.tryCreateDelegate(ctx)
16
- : Promise.resolve(undefined),
13
+ dart.tryCreateDelegate,
17
14
  ];
18
15
  async function getRuntimeDelegate(context) {
19
16
  const { projectDir, sourceDir, runtime } = context;
@@ -16,7 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.isRuntime = isRuntime;
18
18
  exports.runtimeIsLanguage = runtimeIsLanguage;
19
- exports.isLanguageRuntime = isLanguageRuntime;
20
19
  exports.latest = latest;
21
20
  exports.isDecommissioned = isDecommissioned;
22
21
  exports.guardVersionSupport = guardVersionSupport;
@@ -28,9 +27,6 @@ function isRuntime(maybe) {
28
27
  return maybe in types_1.RUNTIMES;
29
28
  }
30
29
  function runtimeIsLanguage(runtime, language) {
31
- return runtime.startsWith(language);
32
- }
33
- function isLanguageRuntime(runtime, language) {
34
30
  return !!runtime && runtime.startsWith(language);
35
31
  }
36
32
  function latest(language, runtimes = Object.keys(types_1.RUNTIMES)) {
@@ -5,11 +5,12 @@ exports.isAILogicEvent = isAILogicEvent;
5
5
  const backend = require("../backend");
6
6
  const error_1 = require("../../../error");
7
7
  const ailogicApi = require("../../../gcp/ailogic");
8
- exports.AI_LOGIC_BEFORE_GENERATE_CONTENT = "firebase.vertexai.v1beta.beforeGenerateContent";
9
- exports.AI_LOGIC_AFTER_GENERATE_CONTENT = "firebase.vertexai.v1beta.afterGenerateContent";
8
+ const ailogic_1 = require("../../../gcp/ailogic");
9
+ Object.defineProperty(exports, "AI_LOGIC_BEFORE_GENERATE_CONTENT", { enumerable: true, get: function () { return ailogic_1.AI_LOGIC_BEFORE_GENERATE_CONTENT; } });
10
+ Object.defineProperty(exports, "AI_LOGIC_AFTER_GENERATE_CONTENT", { enumerable: true, get: function () { return ailogic_1.AI_LOGIC_AFTER_GENERATE_CONTENT; } });
10
11
  exports.AI_LOGIC_EVENTS = [
11
- exports.AI_LOGIC_BEFORE_GENERATE_CONTENT,
12
- exports.AI_LOGIC_AFTER_GENERATE_CONTENT,
12
+ ailogic_1.AI_LOGIC_BEFORE_GENERATE_CONTENT,
13
+ ailogic_1.AI_LOGIC_AFTER_GENERATE_CONTENT,
13
14
  ];
14
15
  function isAILogicEvent(endpoint) {
15
16
  if (!backend.isBlockingTriggered(endpoint)) {
@@ -124,8 +124,8 @@ const EVENT_SERVICE_MAPPING = {
124
124
  "google.cloud.firestore.document.v1.updated.withAuthContext": firestoreService,
125
125
  "google.cloud.firestore.document.v1.deleted.withAuthContext": firestoreService,
126
126
  "google.firebase.dataconnect.connector.v1.mutationExecuted": dataconnectService,
127
- "firebase.vertexai.v1beta.beforeGenerateContent": aiLogicService,
128
- "firebase.vertexai.v1beta.afterGenerateContent": aiLogicService,
127
+ "google.firebase.ailogic.v1.beforeGenerate": aiLogicService,
128
+ "google.firebase.ailogic.v1.afterGenerate": aiLogicService,
129
129
  };
130
130
  function serviceForEndpoint(endpoint) {
131
131
  if (backend.isEventTriggered(endpoint)) {
@@ -55,7 +55,13 @@ function endpointsAreValid(wantBackend) {
55
55
  validateTimeoutConfig(endpoints);
56
56
  for (const ep of endpoints) {
57
57
  validateScheduledTimeout(ep);
58
- (0, services_1.serviceForEndpoint)(ep).validateTrigger(ep, wantBackend);
58
+ const service = (0, services_1.serviceForEndpoint)(ep);
59
+ if (backend.isBlockingTriggered(ep)) {
60
+ if (service.name === "noop") {
61
+ throw new error_1.FirebaseError(`Unrecognized blocking trigger type: ${ep.blockingTrigger.eventType}. Please update your CLI with ${clc.bold("npm install -g firebase-tools@latest")}.`, { exit: 1 });
62
+ }
63
+ }
64
+ service.validateTrigger(ep, wantBackend);
59
65
  }
60
66
  const gcfV1WithConcurrency = matchingIds(endpoints, (endpoint) => (endpoint.concurrency || 1) !== 1 && endpoint.platform === "gcfv1");
61
67
  if (gcfV1WithConcurrency.length) {
@@ -419,10 +419,20 @@ async function startAll(options, showUI = true, runningTestScript = false) {
419
419
  const firestoreLogger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FIRESTORE);
420
420
  const firestoreAddr = legacyGetFirstAddr(types_1.Emulators.FIRESTORE);
421
421
  const websocketPort = legacyGetFirstAddr("firestore.websocket").port;
422
+ const prodEdition = options.config.data.firestore?.edition;
423
+ const emulatorEdition = options.config.src.emulators?.firestore?.edition;
424
+ if (prodEdition !== emulatorEdition) {
425
+ firestoreLogger.logLabeled("WARN", "firestore", `The edition configured in your firebase.json#firestore and firebase.json#emulators.firestore do not match. The latter will be used to start up the Firestore emulator.`);
426
+ }
427
+ const edition = (emulatorEdition || prodEdition || "standard").toLowerCase();
428
+ if (edition !== "standard" && edition !== "enterprise") {
429
+ throw new error_1.FirebaseError("The Firestore emulator edition must be either 'standard' or 'enterprise'.", { exit: 1 });
430
+ }
422
431
  const args = {
423
432
  host: firestoreAddr.host,
424
433
  port: firestoreAddr.port,
425
434
  websocket_port: websocketPort,
435
+ "database-edition": edition,
426
436
  project_id: projectId,
427
437
  auto_download: true,
428
438
  };
@@ -472,6 +482,7 @@ async function startAll(options, showUI = true, runningTestScript = false) {
472
482
  }
473
483
  const firestoreEmulator = new firestoreEmulator_1.FirestoreEmulator(args);
474
484
  await startEmulator(firestoreEmulator);
485
+ firestoreLogger.logLabeled("SUCCESS", types_1.Emulators.FIRESTORE, `Firestore Emulator was started in ${edition} edition.`);
475
486
  firestoreLogger.logLabeled("SUCCESS", types_1.Emulators.FIRESTORE, `Firestore Emulator UI websocket is running on ${websocketPort}.`);
476
487
  }
477
488
  if (listenForEmulator.database) {
@@ -54,36 +54,36 @@
54
54
  },
55
55
  "dataconnect": {
56
56
  "darwin": {
57
- "version": "3.3.1",
58
- "expectedSize": 32105392,
59
- "expectedChecksum": "dfe6ff725864c37889c238aac24be304",
60
- "expectedChecksumSHA256": "1ccfebb4c0ff85f0503b907aa589658774bb6d4fac0180c3fa6bdff3a865090d",
61
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-amd64-v3.3.1",
62
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.3.1"
57
+ "version": "3.4.1",
58
+ "expectedSize": 32274112,
59
+ "expectedChecksum": "ccd7e0be14784f6ac6f6b2102180e062",
60
+ "expectedChecksumSHA256": "2ae6cb5c5da239d272f29b1f14c4630a45ed8e841f8eadd330189dc821fb93bd",
61
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-amd64-v3.4.1",
62
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.1"
63
63
  },
64
64
  "darwin_arm64": {
65
- "version": "3.3.1",
66
- "expectedSize": 30287922,
67
- "expectedChecksum": "59af3cb51c78e8114d634afea811f8cc",
68
- "expectedChecksumSHA256": "75bde31d15c4cc14de7071ff50cdd0d8fb644491e0c9ee3c1da82fdaf8d976a9",
69
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-arm64-v3.3.1",
70
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.3.1"
65
+ "version": "3.4.1",
66
+ "expectedSize": 30437282,
67
+ "expectedChecksum": "ea76099299d6f50862d9a0bb194bb921",
68
+ "expectedChecksumSHA256": "ec51f9bcc0668ca25713c57385d2f12a2776ee64170dcdd861968be30925c7be",
69
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-macos-arm64-v3.4.1",
70
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.1"
71
71
  },
72
72
  "win32": {
73
- "version": "3.3.1",
74
- "expectedSize": 32148992,
75
- "expectedChecksum": "3205dc92bbc7edb4c5821641486dc70c",
76
- "expectedChecksumSHA256": "fa7796077728414b0682f6ccf1df0fc7b2f56bb590f1e62698dbb7c1ddaf0fb0",
77
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-amd64-v3.3.1",
78
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.3.1.exe"
73
+ "version": "3.4.1",
74
+ "expectedSize": 32315904,
75
+ "expectedChecksum": "2d433690efb1e7931d0d5ab4fe5a6d25",
76
+ "expectedChecksumSHA256": "7d8ecff49ac0492569c855badbabd5b1600a2ff63814900a1bbea8b16d96d76a",
77
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-windows-amd64-v3.4.1",
78
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.1.exe"
79
79
  },
80
80
  "linux": {
81
- "version": "3.3.1",
82
- "expectedSize": 31264952,
83
- "expectedChecksum": "85ffdef78810e0074ac94c453a200daa",
84
- "expectedChecksumSHA256": "f232e03165c28f72bc99dfbd2dde1bcaf8298045817b60d72d407da7dae9e9f1",
85
- "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-amd64-v3.3.1",
86
- "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.3.1"
81
+ "version": "3.4.1",
82
+ "expectedSize": 31432888,
83
+ "expectedChecksum": "8e11775e6df3d5dbe583f1f346f299f6",
84
+ "expectedChecksumSHA256": "7124f38854f72c7aa0daff91439825725cb31db138bc1c15976ca97aa27837c4",
85
+ "remoteUrl": "https://storage.googleapis.com/firemat-preview-drop/emulator/dataconnect-emulator-linux-amd64-v3.4.1",
86
+ "downloadPathRelativeToCacheDir": "dataconnect-emulator-3.4.1"
87
87
  }
88
88
  }
89
89
  }
@@ -199,6 +199,7 @@ const Commands = {
199
199
  "host",
200
200
  "rules",
201
201
  "websocket_port",
202
+ "database-edition",
202
203
  "functions_emulator",
203
204
  "seed_from_export",
204
205
  "project_id",
@@ -232,7 +232,7 @@ class FunctionsEmulator {
232
232
  "Content-Type": "application/json",
233
233
  "Content-Length": `${reqBody.length}`,
234
234
  };
235
- const isDart = (0, supported_1.isLanguageRuntime)(record.backend.runtime, "dart");
235
+ const isDart = (0, supported_1.runtimeIsLanguage)(record.backend.runtime, "dart");
236
236
  const path = isDart ? `/${trigger.entryPoint}` : `/`;
237
237
  return new Promise((resolve, reject) => {
238
238
  const req = http.request({
@@ -271,7 +271,7 @@ class FunctionsEmulator {
271
271
  for (const backend of this.staticBackends) {
272
272
  this.logger.logLabeled("BULLET", "functions", `Watching "${backend.functionsDir}" for Cloud Functions...`);
273
273
  await this.loadTriggers(backend, true);
274
- const isDart = (0, supported_1.isLanguageRuntime)(backend.runtime, "dart");
274
+ const isDart = (0, supported_1.runtimeIsLanguage)(backend.runtime, "dart");
275
275
  if (isDart) {
276
276
  const runtimeDelegateContext = {
277
277
  projectId: this.args.projectId,
@@ -1168,10 +1168,10 @@ class FunctionsEmulator {
1168
1168
  const runtimeEnv = this.getRuntimeEnvs(backend, trigger);
1169
1169
  const secretEnvs = await this.resolveSecretEnvs(backend, trigger);
1170
1170
  let runtime;
1171
- if ((0, supported_1.isLanguageRuntime)(backend.runtime, "python")) {
1171
+ if ((0, supported_1.runtimeIsLanguage)(backend.runtime, "python")) {
1172
1172
  runtime = await this.startPython(backend, { ...runtimeEnv, ...secretEnvs });
1173
1173
  }
1174
- else if ((0, supported_1.isLanguageRuntime)(backend.runtime, "dart")) {
1174
+ else if ((0, supported_1.runtimeIsLanguage)(backend.runtime, "dart")) {
1175
1175
  runtime = await this.startDart(backend, { ...runtimeEnv, ...secretEnvs });
1176
1176
  }
1177
1177
  else {
@@ -1242,8 +1242,7 @@ class FunctionsEmulator {
1242
1242
  this.logger.log("DEBUG", `[functions] Runtime ready! Sending request!`);
1243
1243
  const url = new url_1.URL(`${req.protocol}://${req.hostname}${req.url}`);
1244
1244
  let path = `${url.pathname}${url.search}`.replace(new RegExp(`\/${this.args.projectId}\/[^\/]*\/${req.params.trigger_name}\/?`), "/");
1245
- const isDart = (0, supported_1.isLanguageRuntime)(record.backend.runtime, "dart");
1246
- if (isDart) {
1245
+ if ((0, supported_1.runtimeIsLanguage)(record.backend.runtime, "dart")) {
1247
1246
  const isBackgroundRoute = req.url.startsWith("/functions/projects/");
1248
1247
  if (isBackgroundRoute || path === "/") {
1249
1248
  path = `/${trigger.entryPoint}`;
@@ -231,7 +231,7 @@ class RuntimeWorkerPool {
231
231
  if (this.mode === types_1.FunctionsExecutionMode.SEQUENTIAL) {
232
232
  return "~shared~";
233
233
  }
234
- if ((0, supported_1.isLanguageRuntime)(runtime, "dart")) {
234
+ if ((0, supported_1.runtimeIsLanguage)(runtime, "dart")) {
235
235
  return "~dart-shared~";
236
236
  }
237
237
  return triggerId || "~diagnostic~";
@@ -74,6 +74,11 @@ exports.ALL_EXPERIMENTS = experiments({
74
74
  public: false,
75
75
  default: false,
76
76
  },
77
+ dartfunctions: {
78
+ shortDescription: "Enable Dart Functions.",
79
+ public: false,
80
+ default: false,
81
+ },
77
82
  emulatoruisnapshot: {
78
83
  shortDescription: "Load pre-release versions of the emulator UI",
79
84
  },
@@ -169,7 +174,7 @@ exports.ALL_EXPERIMENTS = experiments({
169
174
  },
170
175
  fdcrealtime: {
171
176
  shortDescription: "Enable Firebase Data Connect realtime feature.",
172
- default: false,
177
+ default: true,
173
178
  public: false,
174
179
  },
175
180
  });
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WEBPACK_LAYERS = exports.ESBUILD_VERSION = exports.CONFIG_FILES = exports.SERVER_REFERENCE_MANIFEST = 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;
3
+ exports.WEBPACK_LAYERS = exports.ESBUILD_VERSION = exports.CONFIG_FILES = exports.SERVER_REFERENCE_MANIFEST = exports.APP_PATHS_MANIFEST = exports.ROUTES_MANIFEST = exports.PRERENDER_MANIFEST = exports.PAGES_MANIFEST = exports.FUNCTIONS_CONFIG_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";
7
7
  exports.MIDDLEWARE_MANIFEST = "middleware-manifest.json";
8
+ exports.FUNCTIONS_CONFIG_MANIFEST = "functions-config-manifest.json";
8
9
  exports.PAGES_MANIFEST = "pages-manifest.json";
9
10
  exports.PRERENDER_MANIFEST = "prerender-manifest.json";
10
11
  exports.ROUTES_MANIFEST = "routes-manifest.json";
@@ -255,16 +255,17 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir, _, context) {
255
255
  await (0, fs_extra_1.copy)(publicPath, (0, path_1.join)(destDir, basePath));
256
256
  }
257
257
  await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, distDir, "static"), (0, path_1.join)(destDir, basePath, "_next", "static"));
258
- const [middlewareManifest, prerenderManifest, routesManifest, pagesManifest, appPathRoutesManifest, serverReferenceManifest,] = await Promise.all([
258
+ const [middlewareManifest, prerenderManifest, routesManifest, pagesManifest, appPathRoutesManifest, serverReferenceManifest, functionsConfigManifest,] = await Promise.all([
259
259
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, "server", constants_2.MIDDLEWARE_MANIFEST)),
260
260
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, constants_2.PRERENDER_MANIFEST)),
261
261
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, constants_2.ROUTES_MANIFEST)),
262
262
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, "server", constants_2.PAGES_MANIFEST)),
263
263
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, constants_2.APP_PATH_ROUTES_MANIFEST)).catch(() => ({})),
264
264
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, "server", constants_2.SERVER_REFERENCE_MANIFEST)).catch(() => ({ node: {}, edge: {}, encryptionKey: "" })),
265
+ (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, "server", constants_2.FUNCTIONS_CONFIG_MANIFEST)).catch(() => ({ version: 0, functions: {} })),
265
266
  ]);
266
267
  const appPathRoutesEntries = Object.entries(appPathRoutesManifest);
267
- const middlewareMatcherRegexes = (0, utils_2.getMiddlewareMatcherRegexes)(middlewareManifest);
268
+ const middlewareMatcherRegexes = (0, utils_2.getMiddlewareMatcherRegexes)(middlewareManifest, functionsConfigManifest);
268
269
  const { redirects = [], rewrites = [], headers = [] } = routesManifest;
269
270
  const rewritesRegexesNotSupportedByHosting = (0, utils_2.getNextjsRewritesToUse)(rewrites)
270
271
  .filter((rewrite) => !(0, utils_2.isRewriteSupportedByHosting)(rewrite))
@@ -14,6 +14,8 @@ exports.hasUnoptimizedImage = hasUnoptimizedImage;
14
14
  exports.isUsingMiddleware = isUsingMiddleware;
15
15
  exports.isUsingImageOptimization = isUsingImageOptimization;
16
16
  exports.isUsingNextImageInAppDirectory = isUsingNextImageInAppDirectory;
17
+ exports.isUsingNextImageInServerComponent = isUsingNextImageInServerComponent;
18
+ exports.isUsingNextImageInClientComponent = isUsingNextImageInClientComponent;
17
19
  exports.isUsingAppDirectory = isUsingAppDirectory;
18
20
  exports.allDependencyNames = allDependencyNames;
19
21
  exports.getMiddlewareMatcherRegexes = getMiddlewareMatcherRegexes;
@@ -100,23 +102,33 @@ async function hasUnoptimizedImage(sourceDir, distDir) {
100
102
  }
101
103
  async function isUsingMiddleware(dir, isDevMode) {
102
104
  if (isDevMode) {
103
- const [middlewareJs, middlewareTs] = await Promise.all([
105
+ const middlewareFiles = await Promise.all([
104
106
  (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "middleware.js")),
105
107
  (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "middleware.ts")),
108
+ (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "proxy.js")),
109
+ (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "proxy.ts")),
110
+ (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "src", "middleware.js")),
111
+ (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "src", "middleware.ts")),
112
+ (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "src", "proxy.js")),
113
+ (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "src", "proxy.ts")),
106
114
  ]);
107
- return middlewareJs || middlewareTs;
115
+ return middlewareFiles.some((file) => file);
108
116
  }
109
117
  else {
110
118
  const middlewareManifest = await (0, utils_1.readJSON)((0, path_1.join)(dir, "server", constants_1.MIDDLEWARE_MANIFEST));
119
+ if (middlewareManifest.version === 3) {
120
+ const functionsConfigManifest = await (0, utils_1.readJSON)((0, path_1.join)(dir, "server", constants_1.FUNCTIONS_CONFIG_MANIFEST)).catch(() => undefined);
121
+ if ((functionsConfigManifest?.functions?.["/_middleware"]?.matchers || [])?.length > 0) {
122
+ return true;
123
+ }
124
+ }
111
125
  return Object.keys(middlewareManifest.middleware).length > 0;
112
126
  }
113
127
  }
114
128
  async function isUsingImageOptimization(projectDir, distDir) {
115
129
  let isNextImageImported = await usesNextImage(projectDir, distDir);
116
130
  if (!isNextImageImported && isUsingAppDirectory((0, path_1.join)(projectDir, distDir))) {
117
- if (await isUsingNextImageInAppDirectory(projectDir, distDir)) {
118
- isNextImageImported = true;
119
- }
131
+ isNextImageImported = await isUsingNextImageInAppDirectory(projectDir, distDir);
120
132
  }
121
133
  if (isNextImageImported) {
122
134
  const imagesManifest = await (0, utils_1.readJSON)((0, path_1.join)(projectDir, distDir, constants_1.IMAGES_MANIFEST));
@@ -124,7 +136,11 @@ async function isUsingImageOptimization(projectDir, distDir) {
124
136
  }
125
137
  return false;
126
138
  }
127
- async function isUsingNextImageInAppDirectory(projectDir, nextDir) {
139
+ async function isUsingNextImageInAppDirectory(projectDir, distDir) {
140
+ return ((await isUsingNextImageInServerComponent(projectDir, distDir)) ||
141
+ isUsingNextImageInClientComponent(projectDir, distDir));
142
+ }
143
+ async function isUsingNextImageInServerComponent(projectDir, nextDir) {
128
144
  const nextImagePath = ["node_modules", "next", "dist", "client", "image"];
129
145
  const nextImageString = utils_2.IS_WINDOWS
130
146
  ?
@@ -139,6 +155,16 @@ async function isUsingNextImageInAppDirectory(projectDir, nextDir) {
139
155
  }
140
156
  return false;
141
157
  }
158
+ async function isUsingNextImageInClientComponent(projectDir, distDir) {
159
+ const htmlFiles = await (0, glob_1.glob)((0, path_1.join)(projectDir, distDir, "server", "app", "**", "*.html"));
160
+ for (const filepath of htmlFiles) {
161
+ const contents = await (0, promises_1.readFile)(filepath, "utf-8");
162
+ if (contents.includes('data-nimg="')) {
163
+ return true;
164
+ }
165
+ }
166
+ return false;
167
+ }
142
168
  function isUsingAppDirectory(dir) {
143
169
  const appPathRoutesManifestPath = (0, path_1.join)(dir, constants_1.APP_PATH_ROUTES_MANIFEST);
144
170
  return (0, fsutils_1.fileExistsSync)(appPathRoutesManifestPath);
@@ -149,16 +175,28 @@ function allDependencyNames(mod) {
149
175
  const dependencyNames = Object.keys(mod.dependencies).reduce((acc, it) => [...acc, it, ...allDependencyNames(mod.dependencies[it])], []);
150
176
  return dependencyNames;
151
177
  }
152
- function getMiddlewareMatcherRegexes(middlewareManifest) {
178
+ function getMiddlewareMatcherRegexes(middlewareManifest, functionsConfigManifest) {
153
179
  const middlewareObjectValues = Object.values(middlewareManifest.middleware);
154
- let middlewareMatchers;
180
+ const middlewareMatchers = [];
155
181
  if (middlewareManifest.version === 1) {
156
- middlewareMatchers = middlewareObjectValues.map((page) => ({ regexp: page.regexp }));
182
+ middlewareMatchers.push(...middlewareObjectValues.map((page) => ({
183
+ regexp: page.regexp,
184
+ })));
157
185
  }
158
- else {
159
- middlewareMatchers = middlewareObjectValues
186
+ else if (middlewareManifest.version === 2) {
187
+ middlewareMatchers.push(...middlewareObjectValues
160
188
  .map((page) => page.matchers)
161
- .flat();
189
+ .flat());
190
+ }
191
+ else if (middlewareManifest.version === 3) {
192
+ if (functionsConfigManifest?.functions?.["/_middleware"]) {
193
+ middlewareMatchers.push(...(functionsConfigManifest.functions["/_middleware"].matchers || []));
194
+ }
195
+ else {
196
+ middlewareMatchers.push(...middlewareObjectValues
197
+ .map((page) => page.matchers)
198
+ .flat());
199
+ }
162
200
  }
163
201
  return middlewareMatchers.map((matcher) => new RegExp(matcher.regexp));
164
202
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CONVERTABLE_EVENTS = exports.DATACONNECT_EVENT = exports.FIREALERTS_EVENT = exports.FIRESTORE_EVENTS = exports.TEST_LAB_EVENT = exports.REMOTE_CONFIG_EVENT = exports.DATABASE_EVENTS = exports.FIREBASE_ALERTS_PUBLISH_EVENT = exports.STORAGE_EVENTS = exports.PUBSUB_PUBLISH_EVENT = void 0;
3
+ exports.AI_LOGIC_TRIGGERS_TO_EVENTS = exports.AI_LOGIC_EVENTS_TO_TRIGGER = exports.CONVERTABLE_EVENTS = exports.DATACONNECT_EVENT = exports.FIREALERTS_EVENT = exports.FIRESTORE_EVENTS = exports.TEST_LAB_EVENT = exports.REMOTE_CONFIG_EVENT = exports.DATABASE_EVENTS = exports.FIREBASE_ALERTS_PUBLISH_EVENT = exports.STORAGE_EVENTS = exports.PUBSUB_PUBLISH_EVENT = void 0;
4
+ const ailogic_1 = require("../../deploy/functions/services/ailogic");
4
5
  exports.PUBSUB_PUBLISH_EVENT = "google.cloud.pubsub.topic.v1.messagePublished";
5
6
  exports.STORAGE_EVENTS = [
6
7
  "google.cloud.storage.object.v1.finalized",
@@ -35,3 +36,11 @@ exports.CONVERTABLE_EVENTS = {
35
36
  "google.cloud.firestore.document.v1.deleted": "google.cloud.firestore.document.v1.deleted.withAuthContext",
36
37
  "google.cloud.firestore.document.v1.written": "google.cloud.firestore.document.v1.written.withAuthContext",
37
38
  };
39
+ exports.AI_LOGIC_EVENTS_TO_TRIGGER = {
40
+ [ailogic_1.AI_LOGIC_BEFORE_GENERATE_CONTENT]: "before-generate-content",
41
+ [ailogic_1.AI_LOGIC_AFTER_GENERATE_CONTENT]: "after-generate-content",
42
+ };
43
+ exports.AI_LOGIC_TRIGGERS_TO_EVENTS = {
44
+ "before-generate-content": ailogic_1.AI_LOGIC_BEFORE_GENERATE_CONTENT,
45
+ "after-generate-content": ailogic_1.AI_LOGIC_AFTER_GENERATE_CONTENT,
46
+ };