firebase-tools 13.3.1 → 13.4.1

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 (57) hide show
  1. package/lib/api.js +2 -1
  2. package/lib/apiv2.js +8 -3
  3. package/lib/commands/apphosting-backends-create.js +3 -3
  4. package/lib/commands/apphosting-backends-delete.js +3 -39
  5. package/lib/commands/apphosting-backends-get.js +4 -35
  6. package/lib/commands/apphosting-backends-list.js +17 -9
  7. package/lib/commands/apphosting-builds-create.js +4 -4
  8. package/lib/commands/apphosting-builds-get.js +2 -2
  9. package/lib/commands/apphosting-rollouts-create.js +3 -3
  10. package/lib/commands/apphosting-rollouts-list.js +2 -2
  11. package/lib/commands/firestore-backups-delete.js +44 -0
  12. package/lib/commands/firestore-backups-get.js +25 -0
  13. package/lib/commands/firestore-backups-list.js +34 -0
  14. package/lib/commands/firestore-backups-schedules-create.js +67 -0
  15. package/lib/commands/firestore-backups-schedules-delete.js +46 -0
  16. package/lib/commands/firestore-backups-schedules-list.js +28 -0
  17. package/lib/commands/firestore-backups-schedules-update.js +33 -0
  18. package/lib/commands/firestore-databases-create.js +4 -2
  19. package/lib/commands/firestore-databases-delete.js +4 -2
  20. package/lib/commands/firestore-databases-get.js +3 -1
  21. package/lib/commands/firestore-databases-list.js +3 -1
  22. package/lib/commands/firestore-databases-restore.js +42 -0
  23. package/lib/commands/firestore-databases-update.js +4 -2
  24. package/lib/commands/firestore-indexes-list.js +5 -3
  25. package/lib/commands/firestore-locations.js +3 -1
  26. package/lib/commands/index.js +10 -0
  27. package/lib/deploy/extensions/v2FunctionHelper.js +2 -1
  28. package/lib/deploy/functions/backend.js +5 -1
  29. package/lib/deploy/functions/build.js +9 -6
  30. package/lib/deploy/functions/ensure.js +2 -2
  31. package/lib/deploy/functions/prepare.js +5 -9
  32. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +2 -1
  33. package/lib/emulator/downloadableEmulators.js +3 -3
  34. package/lib/ensureApiEnabled.js +8 -6
  35. package/lib/extensions/extensionsHelper.js +2 -2
  36. package/lib/extensions/secretsUtils.js +2 -1
  37. package/lib/fetchWebSetup.js +2 -1
  38. package/lib/firestore/api-sort.js +23 -1
  39. package/lib/firestore/api-types.js +6 -1
  40. package/lib/firestore/api.js +18 -115
  41. package/lib/firestore/backupUtils.js +30 -0
  42. package/lib/firestore/pretty-print.js +184 -0
  43. package/lib/frameworks/index.js +6 -2
  44. package/lib/frameworks/next/constants.js +35 -1
  45. package/lib/frameworks/next/index.js +25 -3
  46. package/lib/frameworks/next/utils.js +20 -1
  47. package/lib/functions/secrets.js +1 -1
  48. package/lib/gcp/apphosting.js +2 -3
  49. package/lib/gcp/auth.js +5 -2
  50. package/lib/gcp/firestore.js +75 -1
  51. package/lib/gcp/storage.js +1 -1
  52. package/lib/hosting/api.js +12 -1
  53. package/lib/init/features/apphosting/index.js +12 -7
  54. package/lib/init/features/database.js +2 -1
  55. package/lib/init/features/extensions/index.js +2 -1
  56. package/lib/init/features/functions/index.js +3 -2
  57. package/package.json +2 -1
@@ -12,9 +12,11 @@ const prompt_1 = require("../prompt");
12
12
  const api_1 = require("../api");
13
13
  const error_1 = require("../error");
14
14
  const apiv2_1 = require("../apiv2");
15
+ const pretty_print_1 = require("./pretty-print");
15
16
  class FirestoreApi {
16
17
  constructor() {
17
18
  this.apiClient = new apiv2_1.Client({ urlPrefix: api_1.firestoreOrigin, apiVersion: "v1" });
19
+ this.printer = new pretty_print_1.PrettyPrint();
18
20
  }
19
21
  async deploy(options, indexes, fieldOverrides, databaseId = "(default)") {
20
22
  const spec = this.upgradeOldSpec({
@@ -49,7 +51,7 @@ class FirestoreApi {
49
51
  }
50
52
  else if (!options.force) {
51
53
  const indexesString = indexesToDelete
52
- .map((x) => this.prettyIndexString(x, false))
54
+ .map((x) => this.printer.prettyIndexString(x, false))
53
55
  .join("\n\t");
54
56
  utils.logLabeledBullet("firestore", `The following indexes are defined in your project but are not present in your firestore indexes file:\n\t${indexesString}`);
55
57
  }
@@ -86,7 +88,7 @@ class FirestoreApi {
86
88
  }
87
89
  else if (!options.force) {
88
90
  const indexesString = fieldOverridesToDelete
89
- .map((x) => this.prettyFieldString(x))
91
+ .map((x) => this.printer.prettyFieldString(x))
90
92
  .join("\n\t");
91
93
  utils.logLabeledBullet("firestore", `The following field overrides are defined in your project but are not present in your firestore indexes file:\n\t${indexesString}`);
92
94
  }
@@ -145,7 +147,7 @@ class FirestoreApi {
145
147
  return [];
146
148
  }
147
149
  return fields.filter((field) => {
148
- return field.name.indexOf("__default__") < 0;
150
+ return !field.name.includes("__default__");
149
151
  });
150
152
  }
151
153
  makeIndexSpec(indexes, fields) {
@@ -184,64 +186,6 @@ class FirestoreApi {
184
186
  fieldOverrides: sortedFields,
185
187
  };
186
188
  }
187
- prettyPrintIndexes(indexes) {
188
- if (indexes.length === 0) {
189
- logger_1.logger.info("None");
190
- return;
191
- }
192
- const sortedIndexes = indexes.sort(sort.compareApiIndex);
193
- sortedIndexes.forEach((index) => {
194
- logger_1.logger.info(this.prettyIndexString(index));
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)], ["Point In Time Recovery", clc.yellow(database.pointInTimeRecoveryEnablement)], ["Earliest Version Time", clc.yellow(database.earliestVersionTime)], ["Version Retention Period", clc.yellow(database.versionRetentionPeriod)]);
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
- }
235
- printFieldOverrides(fields) {
236
- if (fields.length === 0) {
237
- logger_1.logger.info("None");
238
- return;
239
- }
240
- const sortedFields = fields.sort(sort.compareApiField);
241
- sortedFields.forEach((field) => {
242
- logger_1.logger.info(this.prettyFieldString(field));
243
- });
244
- }
245
189
  validateSpec(spec) {
246
190
  validator.assertHas(spec, "indexes");
247
191
  spec.indexes.forEach((index) => {
@@ -391,7 +335,7 @@ class FirestoreApi {
391
335
  return index.order || index.arrayConfig;
392
336
  });
393
337
  for (const mode of fieldModes) {
394
- if (specModes.indexOf(mode) < 0) {
338
+ if (!specModes.includes(mode)) {
395
339
  return false;
396
340
  }
397
341
  }
@@ -507,60 +451,19 @@ class FirestoreApi {
507
451
  }
508
452
  return database;
509
453
  }
510
- prettyIndexString(index, includeState = true) {
511
- let result = "";
512
- if (index.state && includeState) {
513
- const stateMsg = `[${index.state}] `;
514
- if (index.state === types.State.READY) {
515
- result += clc.green(stateMsg);
516
- }
517
- else if (index.state === types.State.CREATING) {
518
- result += clc.yellow(stateMsg);
519
- }
520
- else {
521
- result += clc.red(stateMsg);
522
- }
523
- }
524
- const nameInfo = util.parseIndexName(index.name);
525
- result += clc.cyan(`(${nameInfo.collectionGroupId})`);
526
- result += " -- ";
527
- index.fields.forEach((field) => {
528
- if (field.fieldPath === "__name__") {
529
- return;
530
- }
531
- const orderOrArrayConfig = field.order ? field.order : field.arrayConfig;
532
- result += `(${field.fieldPath},${orderOrArrayConfig}) `;
533
- });
534
- return result;
535
- }
536
- prettyDatabaseString(database) {
537
- return clc.yellow(database.name);
538
- }
539
- prettyFieldString(field) {
540
- let result = "";
541
- const parsedName = util.parseFieldName(field.name);
542
- result +=
543
- "[" +
544
- clc.cyan(parsedName.collectionGroupId) +
545
- "." +
546
- clc.yellow(parsedName.fieldPath) +
547
- "] --";
548
- const fieldIndexes = field.indexConfig.indexes || [];
549
- if (fieldIndexes.length > 0) {
550
- fieldIndexes.forEach((index) => {
551
- const firstField = index.fields[0];
552
- const mode = firstField.order || firstField.arrayConfig;
553
- result += ` (${mode})`;
554
- });
555
- }
556
- else {
557
- result += " (no indexes)";
558
- }
559
- const fieldTtl = field.ttlConfig;
560
- if (fieldTtl) {
561
- result += ` TTL(${fieldTtl.state})`;
454
+ async restoreDatabase(project, databaseId, backupName) {
455
+ const url = `/projects/${project}/databases:restore`;
456
+ const payload = {
457
+ databaseId,
458
+ backup: backupName,
459
+ };
460
+ const options = { queryParams: { databaseId: databaseId } };
461
+ const res = await this.apiClient.post(url, payload, options);
462
+ const database = res.body.response;
463
+ if (!database) {
464
+ throw new error_1.FirebaseError("Not found");
562
465
  }
563
- return result;
466
+ return database;
564
467
  }
565
468
  }
566
469
  exports.FirestoreApi = FirestoreApi;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateRetention = exports.Duration = exports.DURATION_REGEX = void 0;
4
+ const error_1 = require("../error");
5
+ exports.DURATION_REGEX = /^(\d+)([hdmw])$/;
6
+ var Duration;
7
+ (function (Duration) {
8
+ Duration[Duration["MINUTE"] = 60] = "MINUTE";
9
+ Duration[Duration["HOUR"] = 3600] = "HOUR";
10
+ Duration[Duration["DAY"] = 86400] = "DAY";
11
+ Duration[Duration["WEEK"] = 604800] = "WEEK";
12
+ })(Duration = exports.Duration || (exports.Duration = {}));
13
+ const DURATIONS = {
14
+ m: Duration.MINUTE,
15
+ h: Duration.HOUR,
16
+ d: Duration.DAY,
17
+ w: Duration.WEEK,
18
+ };
19
+ function calculateRetention(flag) {
20
+ const match = exports.DURATION_REGEX.exec(flag);
21
+ if (!match) {
22
+ throw new error_1.FirebaseError(`"retention" flag must be a duration string (e.g. 24h, 2w, or 7d)`);
23
+ }
24
+ const d = parseInt(match[1], 10) * DURATIONS[match[2]];
25
+ if (isNaN(d)) {
26
+ throw new error_1.FirebaseError(`Failed to parse provided retention time "${flag}"`);
27
+ }
28
+ return d;
29
+ }
30
+ exports.calculateRetention = calculateRetention;
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PrettyPrint = void 0;
4
+ const clc = require("colorette");
5
+ const Table = require("cli-table");
6
+ const sort = require("./api-sort");
7
+ const types = require("./api-types");
8
+ const logger_1 = require("../logger");
9
+ const util = require("./util");
10
+ class PrettyPrint {
11
+ prettyPrintIndexes(indexes) {
12
+ if (indexes.length === 0) {
13
+ logger_1.logger.info("None");
14
+ return;
15
+ }
16
+ const sortedIndexes = indexes.sort(sort.compareApiIndex);
17
+ sortedIndexes.forEach((index) => {
18
+ logger_1.logger.info(this.prettyIndexString(index));
19
+ });
20
+ }
21
+ prettyPrintDatabases(databases) {
22
+ if (databases.length === 0) {
23
+ logger_1.logger.info("No databases found.");
24
+ return;
25
+ }
26
+ const sortedDatabases = databases.sort(sort.compareApiDatabase);
27
+ const table = new Table({
28
+ head: ["Database Name"],
29
+ colWidths: [Math.max(...sortedDatabases.map((database) => database.name.length + 5), 20)],
30
+ });
31
+ table.push(...sortedDatabases.map((database) => [this.prettyDatabaseString(database)]));
32
+ logger_1.logger.info(table.toString());
33
+ }
34
+ prettyPrintDatabase(database) {
35
+ const table = new Table({
36
+ head: ["Field", "Value"],
37
+ colWidths: [25, Math.max(50, 5 + database.name.length)],
38
+ });
39
+ 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)], ["Point In Time Recovery", clc.yellow(database.pointInTimeRecoveryEnablement)], ["Earliest Version Time", clc.yellow(database.earliestVersionTime)], ["Version Retention Period", clc.yellow(database.versionRetentionPeriod)]);
40
+ logger_1.logger.info(table.toString());
41
+ }
42
+ prettyPrintBackups(backups) {
43
+ if (backups.length === 0) {
44
+ logger_1.logger.info("No backups found.");
45
+ return;
46
+ }
47
+ const sortedBackups = backups.sort(sort.compareApiBackup);
48
+ const table = new Table({
49
+ head: ["Backup Name", "Database Name", "Snapshot Time", "State"],
50
+ colWidths: [
51
+ Math.max(...sortedBackups.map((backup) => backup.name.length + 5), 20),
52
+ Math.max(...sortedBackups.map((backup) => backup.database.length + 5), 20),
53
+ 30,
54
+ 10,
55
+ ],
56
+ });
57
+ table.push(...sortedBackups.map((backup) => [
58
+ this.prettyBackupString(backup),
59
+ this.prettyDatabaseString(backup.database || ""),
60
+ backup.snapshotTime,
61
+ backup.state,
62
+ ]));
63
+ logger_1.logger.info(table.toString());
64
+ }
65
+ prettyPrintBackupSchedules(backupSchedules, databaseId) {
66
+ if (backupSchedules.length === 0) {
67
+ logger_1.logger.info(`No backup schedules for database ${databaseId} found.`);
68
+ return;
69
+ }
70
+ const sortedBackupSchedules = backupSchedules.sort(sort.compareApiBackupSchedule);
71
+ sortedBackupSchedules.forEach((schedule) => this.prettyPrintBackupSchedule(schedule));
72
+ }
73
+ prettyPrintBackupSchedule(backupSchedule) {
74
+ const table = new Table({
75
+ head: ["Field", "Value"],
76
+ colWidths: [25, Math.max(50, 5 + backupSchedule.name.length)],
77
+ });
78
+ table.push(["Name", clc.yellow(backupSchedule.name)], ["Create Time", clc.yellow(backupSchedule.createTime)], ["Last Update Time", clc.yellow(backupSchedule.updateTime)], ["Retention", clc.yellow(backupSchedule.retention)], ["Recurrence", this.prettyRecurrenceString(backupSchedule)]);
79
+ logger_1.logger.info(table.toString());
80
+ }
81
+ prettyRecurrenceString(backupSchedule) {
82
+ if (backupSchedule.dailyRecurrence) {
83
+ return clc.yellow("DAILY");
84
+ }
85
+ else if (backupSchedule.weeklyRecurrence) {
86
+ return clc.yellow(`WEEKLY (${backupSchedule.weeklyRecurrence.day})`);
87
+ }
88
+ return "";
89
+ }
90
+ prettyPrintBackup(backup) {
91
+ const table = new Table({
92
+ head: ["Field", "Value"],
93
+ colWidths: [25, Math.max(50, 5 + backup.name.length, 5 + backup.database.length)],
94
+ });
95
+ table.push(["Name", clc.yellow(backup.name)], ["Database", clc.yellow(backup.database)], ["Database UID", clc.yellow(backup.databaseUid)], ["State", clc.yellow(backup.state)], ["Snapshot Time", clc.yellow(backup.snapshotTime)], ["Expire Time", clc.yellow(backup.expireTime)], ["Stats", clc.yellow(backup.stats)]);
96
+ logger_1.logger.info(table.toString());
97
+ }
98
+ prettyPrintLocations(locations) {
99
+ if (locations.length === 0) {
100
+ logger_1.logger.info("No Locations Available");
101
+ return;
102
+ }
103
+ const table = new Table({
104
+ head: ["Display Name", "LocationId"],
105
+ colWidths: [20, 30],
106
+ });
107
+ table.push(...locations
108
+ .sort(sort.compareLocation)
109
+ .map((location) => [location.displayName, location.locationId]));
110
+ logger_1.logger.info(table.toString());
111
+ }
112
+ printFieldOverrides(fields) {
113
+ if (fields.length === 0) {
114
+ logger_1.logger.info("None");
115
+ return;
116
+ }
117
+ const sortedFields = fields.sort(sort.compareApiField);
118
+ sortedFields.forEach((field) => {
119
+ logger_1.logger.info(this.prettyFieldString(field));
120
+ });
121
+ }
122
+ prettyIndexString(index, includeState = true) {
123
+ let result = "";
124
+ if (index.state && includeState) {
125
+ const stateMsg = `[${index.state}] `;
126
+ if (index.state === types.State.READY) {
127
+ result += clc.green(stateMsg);
128
+ }
129
+ else if (index.state === types.State.CREATING) {
130
+ result += clc.yellow(stateMsg);
131
+ }
132
+ else {
133
+ result += clc.red(stateMsg);
134
+ }
135
+ }
136
+ const nameInfo = util.parseIndexName(index.name);
137
+ result += clc.cyan(`(${nameInfo.collectionGroupId})`);
138
+ result += " -- ";
139
+ index.fields.forEach((field) => {
140
+ if (field.fieldPath === "__name__") {
141
+ return;
142
+ }
143
+ const orderOrArrayConfig = field.order ? field.order : field.arrayConfig;
144
+ result += `(${field.fieldPath},${orderOrArrayConfig}) `;
145
+ });
146
+ return result;
147
+ }
148
+ prettyBackupString(backup) {
149
+ return clc.yellow(backup.name || "");
150
+ }
151
+ prettyBackupScheduleString(backupSchedule) {
152
+ return clc.yellow(backupSchedule.name || "");
153
+ }
154
+ prettyDatabaseString(database) {
155
+ return clc.yellow(typeof database === "string" ? database : database.name);
156
+ }
157
+ prettyFieldString(field) {
158
+ let result = "";
159
+ const parsedName = util.parseFieldName(field.name);
160
+ result +=
161
+ "[" +
162
+ clc.cyan(parsedName.collectionGroupId) +
163
+ "." +
164
+ clc.yellow(parsedName.fieldPath) +
165
+ "] --";
166
+ const fieldIndexes = field.indexConfig.indexes || [];
167
+ if (fieldIndexes.length > 0) {
168
+ fieldIndexes.forEach((index) => {
169
+ const firstField = index.fields[0];
170
+ const mode = firstField.order || firstField.arrayConfig;
171
+ result += ` (${mode})`;
172
+ });
173
+ }
174
+ else {
175
+ result += " (no indexes)";
176
+ }
177
+ const fieldTtl = field.ttlConfig;
178
+ if (fieldTtl) {
179
+ result += ` TTL(${fieldTtl.state})`;
180
+ }
181
+ return result;
182
+ }
183
+ }
184
+ exports.PrettyPrint = PrettyPrint;
@@ -32,6 +32,7 @@ const projectPath_1 = require("../projectPath");
32
32
  const logger_1 = require("../logger");
33
33
  const frameworks_1 = require("./frameworks");
34
34
  Object.defineProperty(exports, "WebFrameworks", { enumerable: true, get: function () { return frameworks_1.WebFrameworks; } });
35
+ const fetchWebSetup_1 = require("../fetchWebSetup");
35
36
  async function discover(dir, warn = true) {
36
37
  const allFrameworkTypes = [
37
38
  ...new Set(Object.values(frameworks_1.WebFrameworks).map(({ type }) => type)),
@@ -149,12 +150,15 @@ async function prepareFrameworks(purpose, targetNames, context, options, emulato
149
150
  });
150
151
  let firebaseConfig = null;
151
152
  if (usesFirebaseJsSdk) {
152
- const sites = await (0, api_1.listSites)(project);
153
+ const isDemoProject = constants_1.Constants.isDemoProject(project);
154
+ const sites = isDemoProject ? (0, api_1.listDemoSites)(project) : await (0, api_1.listSites)(project);
153
155
  const selectedSite = sites.find((it) => it.name && it.name.split("/").pop() === site);
154
156
  if (selectedSite) {
155
157
  const { appId } = selectedSite;
156
158
  if (appId) {
157
- firebaseConfig = await (0, apps_1.getAppConfig)(appId, apps_1.AppPlatform.WEB);
159
+ firebaseConfig = isDemoProject
160
+ ? (0, fetchWebSetup_1.constructDefaultWebSetup)(project)
161
+ : await (0, apps_1.getAppConfig)(appId, apps_1.AppPlatform.WEB);
158
162
  firebaseDefaults || (firebaseDefaults = {});
159
163
  firebaseDefaults.config = firebaseConfig;
160
164
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ESBUILD_VERSION = 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.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;
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";
@@ -9,4 +9,38 @@ exports.PAGES_MANIFEST = "pages-manifest.json";
9
9
  exports.PRERENDER_MANIFEST = "prerender-manifest.json";
10
10
  exports.ROUTES_MANIFEST = "routes-manifest.json";
11
11
  exports.APP_PATHS_MANIFEST = "app-paths-manifest.json";
12
+ exports.SERVER_REFERENCE_MANIFEST = "server-reference-manifest.json";
12
13
  exports.ESBUILD_VERSION = "0.19.2";
14
+ const WEBPACK_LAYERS_NAMES = {
15
+ shared: "shared",
16
+ reactServerComponents: "rsc",
17
+ serverSideRendering: "ssr",
18
+ actionBrowser: "action-browser",
19
+ api: "api",
20
+ middleware: "middleware",
21
+ edgeAsset: "edge-asset",
22
+ appPagesBrowser: "app-pages-browser",
23
+ appMetadataRoute: "app-metadata-route",
24
+ appRouteHandler: "app-route-handler",
25
+ };
26
+ exports.WEBPACK_LAYERS = Object.assign(Object.assign({}, WEBPACK_LAYERS_NAMES), { GROUP: {
27
+ server: [
28
+ WEBPACK_LAYERS_NAMES.reactServerComponents,
29
+ WEBPACK_LAYERS_NAMES.actionBrowser,
30
+ WEBPACK_LAYERS_NAMES.appMetadataRoute,
31
+ WEBPACK_LAYERS_NAMES.appRouteHandler,
32
+ ],
33
+ nonClientServerTarget: [
34
+ WEBPACK_LAYERS_NAMES.middleware,
35
+ WEBPACK_LAYERS_NAMES.api,
36
+ ],
37
+ app: [
38
+ WEBPACK_LAYERS_NAMES.reactServerComponents,
39
+ WEBPACK_LAYERS_NAMES.actionBrowser,
40
+ WEBPACK_LAYERS_NAMES.appMetadataRoute,
41
+ WEBPACK_LAYERS_NAMES.appRouteHandler,
42
+ WEBPACK_LAYERS_NAMES.serverSideRendering,
43
+ WEBPACK_LAYERS_NAMES.appPagesBrowser,
44
+ WEBPACK_LAYERS_NAMES.shared,
45
+ ],
46
+ } });
@@ -114,9 +114,10 @@ async function build(dir, target, context) {
114
114
  source: (0, utils_2.cleanEscapedChars)(source),
115
115
  headers,
116
116
  }));
117
- const [appPathsManifest, appPathRoutesManifest] = await Promise.all([
117
+ const [appPathsManifest, appPathRoutesManifest, serverReferenceManifest] = await Promise.all([
118
118
  (0, utils_1.readJSON)((0, path_1.join)(dir, distDir, "server", constants_2.APP_PATHS_MANIFEST)).catch(() => undefined),
119
119
  (0, utils_1.readJSON)((0, path_1.join)(dir, distDir, constants_2.APP_PATH_ROUTES_MANIFEST)).catch(() => undefined),
120
+ (0, utils_1.readJSON)((0, path_1.join)(dir, distDir, "server", constants_2.SERVER_REFERENCE_MANIFEST)).catch(() => undefined),
120
121
  ]);
121
122
  if (appPathRoutesManifest) {
122
123
  const headersFromMetaFiles = await (0, utils_2.getHeadersFromMetaFiles)(dir, distDir, baseUrl, appPathRoutesManifest);
@@ -131,6 +132,12 @@ async function build(dir, target, context) {
131
132
  reasonsForBackend.add(`non-static component ${key}`);
132
133
  }
133
134
  }
135
+ if (serverReferenceManifest) {
136
+ const routesWithServerAction = (0, utils_2.getRoutesWithServerAction)(serverReferenceManifest, appPathRoutesManifest);
137
+ for (const key of routesWithServerAction) {
138
+ reasonsForBackend.add(`route with server action ${key}`);
139
+ }
140
+ }
134
141
  }
135
142
  const isEveryRedirectSupported = nextJsRedirects
136
143
  .filter((it) => !it.internal)
@@ -212,12 +219,13 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir, _, context) {
212
219
  await (0, fs_extra_1.copy)(publicPath, (0, path_1.join)(destDir, basePath));
213
220
  }
214
221
  await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, distDir, "static"), (0, path_1.join)(destDir, basePath, "_next", "static"));
215
- const [middlewareManifest, prerenderManifest, routesManifest, pagesManifest, appPathRoutesManifest,] = await Promise.all([
222
+ const [middlewareManifest, prerenderManifest, routesManifest, pagesManifest, appPathRoutesManifest, serverReferenceManifest,] = await Promise.all([
216
223
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, "server", constants_2.MIDDLEWARE_MANIFEST)),
217
224
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, constants_2.PRERENDER_MANIFEST)),
218
225
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, constants_2.ROUTES_MANIFEST)),
219
226
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, "server", constants_2.PAGES_MANIFEST)),
220
227
  (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, constants_2.APP_PATH_ROUTES_MANIFEST)).catch(() => ({})),
228
+ (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, "server", constants_2.SERVER_REFERENCE_MANIFEST)).catch(() => ({ node: {}, edge: {}, encryptionKey: "" })),
221
229
  ]);
222
230
  const appPathRoutesEntries = Object.entries(appPathRoutesManifest);
223
231
  const middlewareMatcherRegexes = (0, utils_2.getMiddlewareMatcherRegexes)(middlewareManifest);
@@ -240,10 +248,20 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir, _, context) {
240
248
  ...redirectsRegexesNotSupportedByHosting,
241
249
  ...headersRegexesNotSupportedByHosting,
242
250
  ];
251
+ const staticRoutesUsingServerActions = (0, utils_2.getRoutesWithServerAction)(serverReferenceManifest, appPathRoutesManifest);
243
252
  const pagesManifestLikePrerender = Object.fromEntries(Object.entries(pagesManifest)
244
253
  .filter(([, srcRoute]) => srcRoute.endsWith(".html"))
245
254
  .map(([path]) => {
246
- return [path, { srcRoute: null, initialRevalidateSeconds: false, dataRoute: "" }];
255
+ return [
256
+ path,
257
+ {
258
+ srcRoute: null,
259
+ initialRevalidateSeconds: false,
260
+ dataRoute: "",
261
+ experimentalPPR: false,
262
+ prefetchDataRoute: "",
263
+ },
264
+ ];
247
265
  }));
248
266
  const routesToCopy = Object.assign(Object.assign({}, prerenderManifest.routes), pagesManifestLikePrerender);
249
267
  await Promise.all(Object.entries(routesToCopy).map(async ([path, route]) => {
@@ -256,6 +274,10 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir, _, context) {
256
274
  logger_1.logger.debug(`skipping ${path} due to it matching an unsupported rewrite/redirect/header or middlware`);
257
275
  return;
258
276
  }
277
+ if (staticRoutesUsingServerActions.some((it) => path === it)) {
278
+ logger_1.logger.debug(`skipping ${path} due to server action`);
279
+ return;
280
+ }
259
281
  const appPathRoute = route.srcRoute && ((_a = appPathRoutesEntries.find(([, it]) => it === route.srcRoute)) === null || _a === void 0 ? void 0 : _a[0]);
260
282
  const contentDist = (0, path_1.join)(sourceDir, distDir, "server", appPathRoute ? "app" : "pages");
261
283
  const sourceParts = path.split("/").filter((it) => !!it);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasStaticAppNotFoundComponent = exports.getNextVersion = exports.getBuildId = exports.getHeadersFromMetaFiles = exports.getNonStaticServerComponents = exports.getNonStaticRoutes = exports.getMiddlewareMatcherRegexes = exports.allDependencyNames = exports.isUsingAppDirectory = exports.isUsingNextImageInAppDirectory = exports.isUsingImageOptimization = exports.isUsingMiddleware = exports.hasUnoptimizedImage = exports.usesNextImage = exports.usesAppDirRouter = exports.getNextjsRewritesToUse = exports.isHeaderSupportedByHosting = exports.isRedirectSupportedByHosting = exports.isRewriteSupportedByHosting = exports.cleanI18n = exports.cleanCustomRouteI18n = exports.cleanEscapedChars = exports.I18N_SOURCE = void 0;
3
+ exports.getRoutesWithServerAction = exports.hasStaticAppNotFoundComponent = exports.getNextVersion = exports.getBuildId = exports.getHeadersFromMetaFiles = exports.getNonStaticServerComponents = exports.getNonStaticRoutes = exports.getMiddlewareMatcherRegexes = exports.allDependencyNames = exports.isUsingAppDirectory = exports.isUsingNextImageInAppDirectory = exports.isUsingImageOptimization = exports.isUsingMiddleware = exports.hasUnoptimizedImage = exports.usesNextImage = exports.usesAppDirRouter = exports.getNextjsRewritesToUse = exports.isHeaderSupportedByHosting = exports.isRedirectSupportedByHosting = exports.isRewriteSupportedByHosting = exports.cleanI18n = exports.cleanCustomRouteI18n = exports.cleanEscapedChars = exports.I18N_SOURCE = void 0;
4
4
  const fs_1 = require("fs");
5
5
  const fs_extra_1 = require("fs-extra");
6
6
  const path_1 = require("path");
@@ -199,3 +199,22 @@ async function hasStaticAppNotFoundComponent(sourceDir, distDir) {
199
199
  return (0, fs_extra_1.pathExists)((0, path_1.join)(sourceDir, distDir, "server", "app", "_not-found.html"));
200
200
  }
201
201
  exports.hasStaticAppNotFoundComponent = hasStaticAppNotFoundComponent;
202
+ function getRoutesWithServerAction(serverReferenceManifest, appPathRoutesManifest) {
203
+ const routesWithServerAction = new Set();
204
+ for (const key of Object.keys(serverReferenceManifest)) {
205
+ if (key !== "edge" && key !== "node")
206
+ continue;
207
+ const edgeOrNode = serverReferenceManifest[key];
208
+ for (const actionId of Object.keys(edgeOrNode)) {
209
+ if (!edgeOrNode[actionId].layer)
210
+ continue;
211
+ for (const [route, type] of Object.entries(edgeOrNode[actionId].layer)) {
212
+ if (type === constants_1.WEBPACK_LAYERS.actionBrowser) {
213
+ routesWithServerAction.add(appPathRoutesManifest[route.replace("app", "")]);
214
+ }
215
+ }
216
+ }
217
+ }
218
+ return Array.from(routesWithServerAction);
219
+ }
220
+ exports.getRoutesWithServerAction = getRoutesWithServerAction;
@@ -44,7 +44,7 @@ function toUpperSnakeCase(key) {
44
44
  }
45
45
  function ensureApi(options) {
46
46
  const projectId = (0, projectUtils_1.needProjectId)(options);
47
- return ensureApiEnabled.ensure(projectId, "secretmanager.googleapis.com", "secretmanager", true);
47
+ return ensureApiEnabled.ensure(projectId, api_1.secretManagerOrigin, "secretmanager", true);
48
48
  }
49
49
  exports.ensureApi = ensureApi;
50
50
  async function ensureValidKey(key, options) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNextRolloutId = exports.ensureApiEnabled = exports.listLocations = exports.updateTraffic = exports.listRollouts = exports.createRollout = exports.createBuild = exports.listBuilds = exports.getBuild = exports.deleteBackend = exports.listBackends = exports.getBackend = exports.createBackend = exports.client = exports.API_VERSION = exports.API_HOST = void 0;
3
+ exports.getNextRolloutId = exports.ensureApiEnabled = exports.listLocations = exports.updateTraffic = exports.listRollouts = exports.createRollout = exports.createBuild = exports.listBuilds = exports.getBuild = exports.deleteBackend = exports.listBackends = exports.getBackend = exports.createBackend = exports.client = exports.API_VERSION = void 0;
4
4
  const proto = require("../gcp/proto");
5
5
  const apiv2_1 = require("../apiv2");
6
6
  const projectUtils_1 = require("../projectUtils");
@@ -9,7 +9,6 @@ const ensureApiEnabled_1 = require("../ensureApiEnabled");
9
9
  const deploymentTool = require("../deploymentTool");
10
10
  const error_1 = require("../error");
11
11
  const metaprogramming_1 = require("../metaprogramming");
12
- exports.API_HOST = new URL(api_1.apphostingOrigin).host;
13
12
  exports.API_VERSION = "v1alpha";
14
13
  exports.client = new apiv2_1.Client({
15
14
  urlPrefix: api_1.apphostingOrigin,
@@ -126,7 +125,7 @@ async function listLocations(projectId) {
126
125
  exports.listLocations = listLocations;
127
126
  async function ensureApiEnabled(options) {
128
127
  const projectId = (0, projectUtils_1.needProjectId)(options);
129
- return await (0, ensureApiEnabled_1.ensure)(projectId, exports.API_HOST, "app hosting", true);
128
+ return await (0, ensureApiEnabled_1.ensure)(projectId, api_1.apphostingOrigin, "app hosting", true);
130
129
  }
131
130
  exports.ensureApiEnabled = ensureApiEnabled;
132
131
  async function getNextRolloutId(projectId, location, backendId, counter) {
package/lib/gcp/auth.js CHANGED
@@ -5,12 +5,15 @@ const apiv2_1 = require("../apiv2");
5
5
  const api_1 = require("../api");
6
6
  const apiClient = new apiv2_1.Client({ urlPrefix: api_1.identityOrigin, auth: true });
7
7
  async function getAuthDomains(project) {
8
- const res = await apiClient.get(`/admin/v2/projects/${project}/config`);
8
+ const res = await apiClient.get(`/admin/v2/projects/${project}/config`, { headers: { "x-goog-user-project": project } });
9
9
  return res.body.authorizedDomains;
10
10
  }
11
11
  exports.getAuthDomains = getAuthDomains;
12
12
  async function updateAuthDomains(project, authDomains) {
13
- const res = await apiClient.patch(`/admin/v2/projects/${project}/config`, { authorizedDomains: authDomains }, { queryParams: { update_mask: "authorizedDomains" } });
13
+ const res = await apiClient.patch(`/admin/v2/projects/${project}/config`, { authorizedDomains: authDomains }, {
14
+ queryParams: { update_mask: "authorizedDomains" },
15
+ headers: { "x-goog-user-project": project },
16
+ });
14
17
  return res.body.authorizedDomains;
15
18
  }
16
19
  exports.updateAuthDomains = updateAuthDomains;