firebase-tools 11.15.0 → 11.16.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.
- package/lib/commands/database-push.js +5 -0
- package/lib/commands/database-remove.js +2 -1
- package/lib/commands/database-set.js +5 -0
- package/lib/commands/database-update.js +5 -0
- package/lib/database/remove.js +2 -2
- package/lib/database/removeRemote.js +7 -2
- package/lib/deploy/functions/build.js +3 -0
- package/lib/deploy/functions/prepare.js +21 -8
- package/lib/deploy/functions/release/fabricator.js +2 -2
- package/lib/deploy/functions/release/sourceTokenScraper.js +34 -7
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +2 -1
- package/lib/deploy/hosting/convertConfig.js +21 -7
- package/lib/deploy/hosting/prepare.js +16 -5
- package/lib/deploy/hosting/release.js +2 -2
- package/lib/dynamicImport.js +7 -10
- package/lib/emulator/auth/server.js +2 -3
- package/lib/emulator/download.js +2 -1
- package/lib/emulator/downloadableEmulators.js +65 -50
- package/lib/emulator/extensionsEmulator.js +1 -1
- package/lib/emulator/functionsEmulator.js +2 -1
- package/lib/emulator/functionsEmulatorShared.js +12 -1
- package/lib/emulator/functionsRuntimeWorker.js +9 -2
- package/lib/emulator/storage/apis/firebase.js +7 -27
- package/lib/emulator/storage/apis/gcloud.js +9 -33
- package/lib/emulator/storage/apis/shared.js +43 -0
- package/lib/emulator/storage/rules/config.js +9 -0
- package/lib/emulator/storage/upload.js +2 -2
- package/lib/experiments.js +1 -3
- package/lib/extensions/provisioningHelper.js +10 -4
- package/lib/frameworks/index.js +9 -4
- package/lib/frameworks/next/index.js +57 -17
- package/lib/serve/hosting.js +4 -4
- package/npm-shrinkwrap.json +600 -50
- package/package.json +2 -2
- package/templates/emulators/default_storage.rules +8 -0
- package/templates/init/functions/golang/functions.go +1 -1
- package/templates/init/functions/javascript/index.js +2 -2
- package/templates/init/functions/typescript/index.ts +1 -1
|
@@ -44,7 +44,7 @@ class ExtensionsEmulator {
|
|
|
44
44
|
if (!functionsEmulator) {
|
|
45
45
|
throw new error_1.FirebaseError("Extensions Emulator is running but Functions emulator is not. This should never happen.");
|
|
46
46
|
}
|
|
47
|
-
return functionsEmulator.getInfo();
|
|
47
|
+
return Object.assign(Object.assign({}, functionsEmulator.getInfo()), { name: this.getName() });
|
|
48
48
|
}
|
|
49
49
|
getName() {
|
|
50
50
|
return types_1.Emulators.EXTENSIONS;
|
|
@@ -137,10 +137,11 @@ class FunctionsEmulator {
|
|
|
137
137
|
method: req.method,
|
|
138
138
|
path: `/functions/projects/${projectId}/triggers/${triggerId}`,
|
|
139
139
|
headers: req.headers,
|
|
140
|
-
}
|
|
140
|
+
});
|
|
141
141
|
trigReq.on("error", reject);
|
|
142
142
|
trigReq.write(rawBody);
|
|
143
143
|
trigReq.end();
|
|
144
|
+
resolve();
|
|
144
145
|
});
|
|
145
146
|
});
|
|
146
147
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toBackendInfo = exports.getSecretLocalPath = exports.getSignatureType = exports.formatHost = exports.findModuleRoot = exports.waitForBody = exports.getServiceFromEventType = exports.getFunctionService = exports.getTemporarySocketPath = exports.getEmulatedTriggersFromDefinitions = exports.emulatedFunctionsByRegion = exports.emulatedFunctionsFromEndpoints = exports.prepareEndpoints = exports.eventServiceImplemented = exports.EmulatedTrigger = exports.HttpConstants = void 0;
|
|
3
|
+
exports.toBackendInfo = exports.getSecretLocalPath = exports.getSignatureType = exports.formatHost = exports.findModuleRoot = exports.waitForBody = exports.getServiceFromEventType = exports.getFunctionService = exports.getTemporarySocketPath = exports.getEmulatedTriggersFromDefinitions = exports.emulatedFunctionsByRegion = exports.emulatedFunctionsFromEndpoints = exports.prepareEndpoints = exports.eventServiceImplemented = exports.EmulatedTrigger = exports.HttpConstants = exports.EVENTARC_SOURCE_ENV = void 0;
|
|
4
4
|
const os = require("os");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const fs = require("fs");
|
|
@@ -20,6 +20,7 @@ const V2_EVENTS = [
|
|
|
20
20
|
...events.v2.STORAGE_EVENTS,
|
|
21
21
|
...events.v2.DATABASE_EVENTS,
|
|
22
22
|
];
|
|
23
|
+
exports.EVENTARC_SOURCE_ENV = "EVENTARC_CLOUD_EVENT_SOURCE";
|
|
23
24
|
class HttpConstants {
|
|
24
25
|
}
|
|
25
26
|
exports.HttpConstants = HttpConstants;
|
|
@@ -73,6 +74,16 @@ function emulatedFunctionsFromEndpoints(endpoints) {
|
|
|
73
74
|
};
|
|
74
75
|
def.availableMemoryMb = endpoint.availableMemoryMb || 256;
|
|
75
76
|
def.labels = endpoint.labels || {};
|
|
77
|
+
if (endpoint.platform === "gcfv1") {
|
|
78
|
+
def.labels[exports.EVENTARC_SOURCE_ENV] =
|
|
79
|
+
"cloudfunctions-emulated.googleapis.com" +
|
|
80
|
+
`/projects/${endpoint.project || "project"}/locations/${endpoint.region}/functions/${endpoint.id}`;
|
|
81
|
+
}
|
|
82
|
+
else if (endpoint.platform === "gcfv2") {
|
|
83
|
+
def.labels[exports.EVENTARC_SOURCE_ENV] =
|
|
84
|
+
"run-emulated.googleapis.com" +
|
|
85
|
+
`/projects/${endpoint.project || "project"}/locations/${endpoint.region}/services/${endpoint.id}`;
|
|
86
|
+
}
|
|
76
87
|
def.timeoutSeconds = endpoint.timeoutSeconds || 60;
|
|
77
88
|
def.secretEnvironmentVariables = endpoint.secretEnvironmentVariables || [];
|
|
78
89
|
def.platform = endpoint.platform;
|
|
@@ -9,6 +9,7 @@ const emulatorLogger_1 = require("./emulatorLogger");
|
|
|
9
9
|
const error_1 = require("../error");
|
|
10
10
|
var RuntimeWorkerState;
|
|
11
11
|
(function (RuntimeWorkerState) {
|
|
12
|
+
RuntimeWorkerState["CREATED"] = "CREATED";
|
|
12
13
|
RuntimeWorkerState["IDLE"] = "IDLE";
|
|
13
14
|
RuntimeWorkerState["BUSY"] = "BUSY";
|
|
14
15
|
RuntimeWorkerState["FINISHING"] = "FINISHING";
|
|
@@ -18,7 +19,7 @@ class RuntimeWorker {
|
|
|
18
19
|
constructor(key, runtime) {
|
|
19
20
|
this.stateEvents = new events_1.EventEmitter();
|
|
20
21
|
this.logListeners = [];
|
|
21
|
-
this._state = RuntimeWorkerState.
|
|
22
|
+
this._state = RuntimeWorkerState.CREATED;
|
|
22
23
|
this.id = uuid.v4();
|
|
23
24
|
this.key = key;
|
|
24
25
|
this.runtime = runtime;
|
|
@@ -58,6 +59,9 @@ class RuntimeWorker {
|
|
|
58
59
|
}
|
|
59
60
|
return lines[lines.length - 1];
|
|
60
61
|
}
|
|
62
|
+
readyForWork() {
|
|
63
|
+
this.state = RuntimeWorkerState.IDLE;
|
|
64
|
+
}
|
|
61
65
|
sendDebugMsg(debug) {
|
|
62
66
|
return new Promise((resolve, reject) => {
|
|
63
67
|
this.runtime.process.send(JSON.stringify(debug), (err) => {
|
|
@@ -138,7 +142,10 @@ class RuntimeWorker {
|
|
|
138
142
|
method: "GET",
|
|
139
143
|
path: "/__/health",
|
|
140
144
|
socketPath: this.runtime.socketPath,
|
|
141
|
-
}, () =>
|
|
145
|
+
}, () => {
|
|
146
|
+
this.readyForWork();
|
|
147
|
+
resolve();
|
|
148
|
+
})
|
|
142
149
|
.end();
|
|
143
150
|
req.on("error", (error) => {
|
|
144
151
|
reject(error);
|
|
@@ -4,9 +4,9 @@ exports.createFirebaseEndpoints = void 0;
|
|
|
4
4
|
const emulatorLogger_1 = require("../../emulatorLogger");
|
|
5
5
|
const types_1 = require("../../types");
|
|
6
6
|
const uuid = require("uuid");
|
|
7
|
-
const zlib_1 = require("zlib");
|
|
8
7
|
const metadata_1 = require("../metadata");
|
|
9
8
|
const express_1 = require("express");
|
|
9
|
+
const shared_1 = require("./shared");
|
|
10
10
|
const registry_1 = require("../../registry");
|
|
11
11
|
const multipart_1 = require("../multipart");
|
|
12
12
|
const errors_1 = require("../errors");
|
|
@@ -17,7 +17,7 @@ function createFirebaseEndpoints(emulator) {
|
|
|
17
17
|
const { storageLayer, uploadService } = emulator;
|
|
18
18
|
if (process.env.STORAGE_EMULATOR_DEBUG) {
|
|
19
19
|
firebaseStorageAPI.use((req, res, next) => {
|
|
20
|
-
console.log("--------------INCOMING REQUEST--------------");
|
|
20
|
+
console.log("--------------INCOMING FIREBASE REQUEST--------------");
|
|
21
21
|
console.log(`${req.method.toUpperCase()} ${req.path}`);
|
|
22
22
|
console.log("-- query:");
|
|
23
23
|
console.log(JSON.stringify(req.query, undefined, 2));
|
|
@@ -98,24 +98,7 @@ function createFirebaseEndpoints(emulator) {
|
|
|
98
98
|
metadata.addDownloadToken(true);
|
|
99
99
|
}
|
|
100
100
|
if (req.query.alt === "media") {
|
|
101
|
-
|
|
102
|
-
if (isGZipped) {
|
|
103
|
-
data = (0, zlib_1.gunzipSync)(data);
|
|
104
|
-
}
|
|
105
|
-
res.setHeader("Accept-Ranges", "bytes");
|
|
106
|
-
res.setHeader("Content-Type", metadata.contentType || "application/octet-stream");
|
|
107
|
-
res.setHeader("Content-Disposition", metadata.contentDisposition || "inline");
|
|
108
|
-
setObjectHeaders(res, metadata, { "Content-Encoding": isGZipped ? "identity" : undefined });
|
|
109
|
-
const byteRange = req.range(data.byteLength, { combine: true });
|
|
110
|
-
if (Array.isArray(byteRange) && byteRange.type === "bytes" && byteRange.length > 0) {
|
|
111
|
-
const range = byteRange[0];
|
|
112
|
-
res.setHeader("Content-Range", `${byteRange.type} ${range.start}-${range.end}/${data.byteLength}`);
|
|
113
|
-
res.status(206).end(data.slice(range.start, range.end + 1));
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
res.end(data);
|
|
117
|
-
}
|
|
118
|
-
return;
|
|
101
|
+
return (0, shared_1.sendFileBytes)(metadata, data, req, res);
|
|
119
102
|
}
|
|
120
103
|
return res.json(new metadata_1.OutgoingFirebaseMetadata(metadata));
|
|
121
104
|
});
|
|
@@ -215,7 +198,7 @@ function createFirebaseEndpoints(emulator) {
|
|
|
215
198
|
const upload = uploadService.startResumableUpload({
|
|
216
199
|
bucketId,
|
|
217
200
|
objectId,
|
|
218
|
-
|
|
201
|
+
metadata: req.body,
|
|
219
202
|
authorization: req.header("authorization"),
|
|
220
203
|
});
|
|
221
204
|
res.header("x-goog-upload-chunk-granularity", "10000");
|
|
@@ -330,7 +313,7 @@ function createFirebaseEndpoints(emulator) {
|
|
|
330
313
|
const upload = uploadService.multipartUpload({
|
|
331
314
|
bucketId,
|
|
332
315
|
objectId,
|
|
333
|
-
metadataRaw,
|
|
316
|
+
metadata: JSON.parse(metadataRaw),
|
|
334
317
|
dataRaw: dataRaw,
|
|
335
318
|
authorization: req.header("authorization"),
|
|
336
319
|
});
|
|
@@ -480,14 +463,11 @@ function createFirebaseEndpoints(emulator) {
|
|
|
480
463
|
return firebaseStorageAPI;
|
|
481
464
|
}
|
|
482
465
|
exports.createFirebaseEndpoints = createFirebaseEndpoints;
|
|
483
|
-
function setObjectHeaders(res, metadata
|
|
466
|
+
function setObjectHeaders(res, metadata) {
|
|
484
467
|
if (metadata.contentDisposition) {
|
|
485
468
|
res.setHeader("Content-Disposition", metadata.contentDisposition);
|
|
486
469
|
}
|
|
487
|
-
if (
|
|
488
|
-
res.setHeader("Content-Encoding", headerOverride["Content-Encoding"]);
|
|
489
|
-
}
|
|
490
|
-
else if (metadata.contentEncoding) {
|
|
470
|
+
if (metadata.contentEncoding) {
|
|
491
471
|
res.setHeader("Content-Encoding", metadata.contentEncoding);
|
|
492
472
|
}
|
|
493
473
|
if (metadata.cacheControl) {
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createCloudEndpoints = void 0;
|
|
4
4
|
const express_1 = require("express");
|
|
5
|
-
const zlib_1 = require("zlib");
|
|
6
5
|
const types_1 = require("../../types");
|
|
7
6
|
const metadata_1 = require("../metadata");
|
|
7
|
+
const shared_1 = require("./shared");
|
|
8
8
|
const registry_1 = require("../../registry");
|
|
9
9
|
const emulatorLogger_1 = require("../../emulatorLogger");
|
|
10
|
-
const crc_1 = require("../crc");
|
|
11
10
|
const multipart_1 = require("../multipart");
|
|
12
11
|
const upload_1 = require("../upload");
|
|
13
12
|
const errors_1 = require("../errors");
|
|
@@ -17,7 +16,7 @@ function createCloudEndpoints(emulator) {
|
|
|
17
16
|
const { adminStorageLayer, uploadService } = emulator;
|
|
18
17
|
if (process.env.STORAGE_EMULATOR_DEBUG) {
|
|
19
18
|
gcloudStorageAPI.use((req, res, next) => {
|
|
20
|
-
console.log("--------------INCOMING REQUEST--------------");
|
|
19
|
+
console.log("--------------INCOMING GCS REQUEST--------------");
|
|
21
20
|
console.log(`${req.method.toUpperCase()} ${req.path}`);
|
|
22
21
|
console.log("-- query:");
|
|
23
22
|
console.log(JSON.stringify(req.query, undefined, 2));
|
|
@@ -86,7 +85,7 @@ function createCloudEndpoints(emulator) {
|
|
|
86
85
|
throw err;
|
|
87
86
|
}
|
|
88
87
|
if (req.query.alt === "media") {
|
|
89
|
-
return sendFileBytes(getObjectResponse.metadata, getObjectResponse.data, req, res);
|
|
88
|
+
return (0, shared_1.sendFileBytes)(getObjectResponse.metadata, getObjectResponse.data, req, res);
|
|
90
89
|
}
|
|
91
90
|
return res.json(new metadata_1.CloudStorageObjectMetadata(getObjectResponse.metadata));
|
|
92
91
|
});
|
|
@@ -110,7 +109,7 @@ function createCloudEndpoints(emulator) {
|
|
|
110
109
|
}
|
|
111
110
|
return res.json(new metadata_1.CloudStorageObjectMetadata(updatedMetadata));
|
|
112
111
|
});
|
|
113
|
-
gcloudStorageAPI.get("/b/:bucketId/o", async (req, res) => {
|
|
112
|
+
gcloudStorageAPI.get(["/b/:bucketId/o", "/storage/v1/b/:bucketId/o"], async (req, res) => {
|
|
114
113
|
var _a;
|
|
115
114
|
let listResponse;
|
|
116
115
|
try {
|
|
@@ -228,10 +227,11 @@ function createCloudEndpoints(emulator) {
|
|
|
228
227
|
res.sendStatus(400);
|
|
229
228
|
return;
|
|
230
229
|
}
|
|
230
|
+
const contentType = req.header("x-upload-content-type");
|
|
231
231
|
const upload = uploadService.startResumableUpload({
|
|
232
232
|
bucketId: req.params.bucketId,
|
|
233
233
|
objectId: name,
|
|
234
|
-
|
|
234
|
+
metadata: Object.assign({ contentType }, req.body),
|
|
235
235
|
authorization: req.header("authorization"),
|
|
236
236
|
});
|
|
237
237
|
const uploadUrl = registry_1.EmulatorRegistry.url(types_1.Emulators.STORAGE, req);
|
|
@@ -256,6 +256,7 @@ function createCloudEndpoints(emulator) {
|
|
|
256
256
|
}
|
|
257
257
|
if (uploadType === "multipart") {
|
|
258
258
|
const contentTypeHeader = req.header("content-type") || req.header("x-upload-content-type");
|
|
259
|
+
const contentType = req.header("x-upload-content-type");
|
|
259
260
|
if (!contentTypeHeader) {
|
|
260
261
|
return res.sendStatus(400);
|
|
261
262
|
}
|
|
@@ -283,7 +284,7 @@ function createCloudEndpoints(emulator) {
|
|
|
283
284
|
const upload = uploadService.multipartUpload({
|
|
284
285
|
bucketId: req.params.bucketId,
|
|
285
286
|
objectId: name,
|
|
286
|
-
|
|
287
|
+
metadata: Object.assign({ contentType }, JSON.parse(metadataRaw)),
|
|
287
288
|
dataRaw: dataRaw,
|
|
288
289
|
authorization: req.header("authorization"),
|
|
289
290
|
});
|
|
@@ -318,7 +319,7 @@ function createCloudEndpoints(emulator) {
|
|
|
318
319
|
}
|
|
319
320
|
throw err;
|
|
320
321
|
}
|
|
321
|
-
return sendFileBytes(getObjectResponse.metadata, getObjectResponse.data, req, res);
|
|
322
|
+
return (0, shared_1.sendFileBytes)(getObjectResponse.metadata, getObjectResponse.data, req, res);
|
|
322
323
|
});
|
|
323
324
|
gcloudStorageAPI.post("/b/:bucketId/o/:objectId/:method(rewriteTo|copyTo)/b/:destBucketId/o/:destObjectId", (req, res, next) => {
|
|
324
325
|
if (req.params.method === "rewriteTo" && req.query.rewriteToken) {
|
|
@@ -375,31 +376,6 @@ function createCloudEndpoints(emulator) {
|
|
|
375
376
|
return gcloudStorageAPI;
|
|
376
377
|
}
|
|
377
378
|
exports.createCloudEndpoints = createCloudEndpoints;
|
|
378
|
-
function sendFileBytes(md, data, req, res) {
|
|
379
|
-
const isGZipped = md.contentEncoding === "gzip";
|
|
380
|
-
if (isGZipped) {
|
|
381
|
-
data = (0, zlib_1.gunzipSync)(data);
|
|
382
|
-
}
|
|
383
|
-
res.setHeader("Accept-Ranges", "bytes");
|
|
384
|
-
res.setHeader("Content-Type", md.contentType || "application/octet-stream");
|
|
385
|
-
res.setHeader("Content-Disposition", md.contentDisposition || "attachment");
|
|
386
|
-
res.setHeader("Content-Encoding", isGZipped ? "identity" : md.contentEncoding || "");
|
|
387
|
-
res.setHeader("ETag", md.etag);
|
|
388
|
-
res.setHeader("Cache-Control", md.cacheControl || "");
|
|
389
|
-
res.setHeader("x-goog-generation", `${md.generation}`);
|
|
390
|
-
res.setHeader("x-goog-metadatageneration", `${md.metageneration}`);
|
|
391
|
-
res.setHeader("x-goog-storage-class", md.storageClass);
|
|
392
|
-
res.setHeader("x-goog-hash", `crc32c=${(0, crc_1.crc32cToString)(md.crc32c)},md5=${md.md5Hash}`);
|
|
393
|
-
const byteRange = req.range(data.byteLength, { combine: true });
|
|
394
|
-
if (Array.isArray(byteRange) && byteRange.type === "bytes" && byteRange.length > 0) {
|
|
395
|
-
const range = byteRange[0];
|
|
396
|
-
res.setHeader("Content-Range", `${byteRange.type} ${range.start}-${range.end}/${data.byteLength}`);
|
|
397
|
-
res.status(206).end(data.slice(range.start, range.end + 1));
|
|
398
|
-
}
|
|
399
|
-
else {
|
|
400
|
-
res.end(data);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
379
|
function sendObjectNotFound(req, res) {
|
|
404
380
|
res.status(404);
|
|
405
381
|
const message = `No such object: ${req.params.bucketId}/${req.params.objectId}`;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sendFileBytes = void 0;
|
|
4
|
+
const zlib_1 = require("zlib");
|
|
5
|
+
const crc_1 = require("../crc");
|
|
6
|
+
function sendFileBytes(md, data, req, res) {
|
|
7
|
+
let didGunzip = false;
|
|
8
|
+
if (md.contentEncoding === "gzip") {
|
|
9
|
+
const acceptEncoding = req.header("accept-encoding") || "";
|
|
10
|
+
const shouldGunzip = !acceptEncoding.includes("gzip");
|
|
11
|
+
if (shouldGunzip) {
|
|
12
|
+
data = (0, zlib_1.gunzipSync)(data);
|
|
13
|
+
didGunzip = true;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
res.setHeader("Accept-Ranges", "bytes");
|
|
17
|
+
res.setHeader("Content-Type", md.contentType || "application/octet-stream");
|
|
18
|
+
res.setHeader("Content-Disposition", md.contentDisposition || "attachment");
|
|
19
|
+
if (didGunzip) {
|
|
20
|
+
res.setHeader("Transfer-Encoding", "chunked");
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
res.setHeader("Content-Encoding", md.contentEncoding || "");
|
|
24
|
+
}
|
|
25
|
+
res.setHeader("ETag", md.etag);
|
|
26
|
+
res.setHeader("Cache-Control", md.cacheControl || "");
|
|
27
|
+
res.setHeader("x-goog-generation", `${md.generation}`);
|
|
28
|
+
res.setHeader("x-goog-metadatageneration", `${md.metageneration}`);
|
|
29
|
+
res.setHeader("x-goog-storage-class", md.storageClass);
|
|
30
|
+
res.setHeader("x-goog-hash", `crc32c=${(0, crc_1.crc32cToString)(md.crc32c)},md5=${md.md5Hash}`);
|
|
31
|
+
const shouldRespectContentRange = !didGunzip;
|
|
32
|
+
if (shouldRespectContentRange) {
|
|
33
|
+
const byteRange = req.range(data.byteLength, { combine: true });
|
|
34
|
+
if (Array.isArray(byteRange) && byteRange.type === "bytes" && byteRange.length > 0) {
|
|
35
|
+
const range = byteRange[0];
|
|
36
|
+
res.setHeader("Content-Range", `${byteRange.type} ${range.start}-${range.end}/${data.byteLength}`);
|
|
37
|
+
res.status(206).end(data.slice(range.start, range.end + 1));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
res.end(data);
|
|
42
|
+
}
|
|
43
|
+
exports.sendFileBytes = sendFileBytes;
|
|
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getStorageRulesConfig = void 0;
|
|
4
4
|
const error_1 = require("../../../error");
|
|
5
5
|
const fsutils_1 = require("../../../fsutils");
|
|
6
|
+
const constants_1 = require("../../constants");
|
|
7
|
+
const types_1 = require("../../types");
|
|
8
|
+
const emulatorLogger_1 = require("../../emulatorLogger");
|
|
6
9
|
function getSourceFile(rules, options) {
|
|
7
10
|
const path = options.config.path(rules);
|
|
8
11
|
return { name: path, content: (0, fsutils_1.readFile)(path) };
|
|
@@ -10,6 +13,12 @@ function getSourceFile(rules, options) {
|
|
|
10
13
|
function getStorageRulesConfig(projectId, options) {
|
|
11
14
|
const storageConfig = options.config.data.storage;
|
|
12
15
|
if (!storageConfig) {
|
|
16
|
+
if (constants_1.Constants.isDemoProject(projectId)) {
|
|
17
|
+
const storageLogger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.STORAGE);
|
|
18
|
+
storageLogger.logLabeled("BULLET", "storage", `Detected demo project ID "${projectId}", using a default (open) rules configuration.`);
|
|
19
|
+
const path = __dirname + "/../../../../templates/emulators/default_storage.rules";
|
|
20
|
+
return { name: path, content: (0, fsutils_1.readFile)(path) };
|
|
21
|
+
}
|
|
13
22
|
throw new error_1.FirebaseError("Cannot start the Storage emulator without rules file specified in firebase.json: run 'firebase init' and set up your Storage configuration");
|
|
14
23
|
}
|
|
15
24
|
if (!Array.isArray(storageConfig)) {
|
|
@@ -50,7 +50,7 @@ class UploadService {
|
|
|
50
50
|
objectId: request.objectId,
|
|
51
51
|
uploadType: UploadType.MULTIPART,
|
|
52
52
|
dataRaw: request.dataRaw,
|
|
53
|
-
metadata:
|
|
53
|
+
metadata: request.metadata,
|
|
54
54
|
authorization: request.authorization,
|
|
55
55
|
});
|
|
56
56
|
this._persistence.deleteFile(upload.path, true);
|
|
@@ -82,7 +82,7 @@ class UploadService {
|
|
|
82
82
|
type: UploadType.RESUMABLE,
|
|
83
83
|
path: this.getStagingFileName(id, request.bucketId, request.objectId),
|
|
84
84
|
status: UploadStatus.ACTIVE,
|
|
85
|
-
metadata:
|
|
85
|
+
metadata: request.metadata,
|
|
86
86
|
size: 0,
|
|
87
87
|
authorization: request.authorization,
|
|
88
88
|
};
|
package/lib/experiments.js
CHANGED
|
@@ -46,9 +46,7 @@ exports.ALL_EXPERIMENTS = experiments({
|
|
|
46
46
|
},
|
|
47
47
|
functionsparams: {
|
|
48
48
|
shortDescription: "Adds support for paramaterizing functions deployments",
|
|
49
|
-
|
|
50
|
-
skipdeployingnoopfunctions: {
|
|
51
|
-
shortDescription: "Detect that there have been no changes to a function and skip deployment",
|
|
49
|
+
default: true,
|
|
52
50
|
},
|
|
53
51
|
emulatoruisnapshot: {
|
|
54
52
|
shortDescription: "Load pre-release versions of the emulator UI",
|
|
@@ -7,6 +7,7 @@ const apiv2_1 = require("../apiv2");
|
|
|
7
7
|
const functional_1 = require("../functional");
|
|
8
8
|
const error_1 = require("../error");
|
|
9
9
|
const planner_1 = require("../deploy/extensions/planner");
|
|
10
|
+
const logger_1 = require("../logger");
|
|
10
11
|
var DeferredProduct;
|
|
11
12
|
(function (DeferredProduct) {
|
|
12
13
|
DeferredProduct[DeferredProduct["STORAGE"] = 0] = "STORAGE";
|
|
@@ -35,11 +36,16 @@ async function checkProducts(projectId, usedProducts) {
|
|
|
35
36
|
if (usedProducts.includes(DeferredProduct.AUTH)) {
|
|
36
37
|
isAuthProvisionedPromise = isAuthProvisioned(projectId);
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
try {
|
|
40
|
+
if (isStorageProvisionedPromise && !(await isStorageProvisionedPromise)) {
|
|
41
|
+
needProvisioning.push(DeferredProduct.STORAGE);
|
|
42
|
+
}
|
|
43
|
+
if (isAuthProvisionedPromise && !(await isAuthProvisionedPromise)) {
|
|
44
|
+
needProvisioning.push(DeferredProduct.AUTH);
|
|
45
|
+
}
|
|
40
46
|
}
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
catch (err) {
|
|
48
|
+
logger_1.logger.debug(`Error while checking product provisioning, failing open: ${err}`);
|
|
43
49
|
}
|
|
44
50
|
if (needProvisioning.length > 0) {
|
|
45
51
|
let errorMessage = "Some services used by this extension have not been set up on your " +
|
package/lib/frameworks/index.js
CHANGED
|
@@ -139,12 +139,14 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
139
139
|
}
|
|
140
140
|
const configs = (0, config_1.hostingConfig)(options);
|
|
141
141
|
let firebaseDefaults = undefined;
|
|
142
|
-
if (configs.length === 0)
|
|
142
|
+
if (configs.length === 0) {
|
|
143
143
|
return;
|
|
144
|
+
}
|
|
144
145
|
for (const config of configs) {
|
|
145
146
|
const { source, site, public: publicDir } = config;
|
|
146
|
-
if (!source)
|
|
147
|
+
if (!source) {
|
|
147
148
|
continue;
|
|
149
|
+
}
|
|
148
150
|
config.rewrites || (config.rewrites = []);
|
|
149
151
|
config.redirects || (config.redirects = []);
|
|
150
152
|
config.headers || (config.headers = []);
|
|
@@ -152,8 +154,9 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
152
154
|
const dist = (0, path_1.join)(projectRoot, ".firebase", site);
|
|
153
155
|
const hostingDist = (0, path_1.join)(dist, "hosting");
|
|
154
156
|
const functionsDist = (0, path_1.join)(dist, "functions");
|
|
155
|
-
if (publicDir)
|
|
157
|
+
if (publicDir) {
|
|
156
158
|
throw new Error(`hosting.public and hosting.source cannot both be set in firebase.json`);
|
|
159
|
+
}
|
|
157
160
|
const getProjectPath = (...args) => (0, path_1.join)(projectRoot, source, ...args);
|
|
158
161
|
const functionName = `ssr${site.toLowerCase().replace(/-/g, "")}`;
|
|
159
162
|
const usesFirebaseAdminSdk = !!findDependency("firebase-admin", { cwd: getProjectPath() });
|
|
@@ -232,8 +235,9 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
232
235
|
if (devModeHandle) {
|
|
233
236
|
config.public = (0, path_1.relative)(projectRoot, publicDirectory);
|
|
234
237
|
options.frameworksDevModeHandle = devModeHandle;
|
|
235
|
-
if (mayWantBackend && firebaseDefaults)
|
|
238
|
+
if (mayWantBackend && firebaseDefaults) {
|
|
236
239
|
codegenFunctionsDirectory = codegenDevModeFunctionsDirectory;
|
|
240
|
+
}
|
|
237
241
|
}
|
|
238
242
|
else {
|
|
239
243
|
const { wantsBackend = false, rewrites = [], redirects = [], headers = [], } = (await build(getProjectPath())) || {};
|
|
@@ -248,6 +252,7 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
248
252
|
if (wantsBackend)
|
|
249
253
|
codegenFunctionsDirectory = codegenProdModeFunctionsDirectory;
|
|
250
254
|
}
|
|
255
|
+
config.webFramework = `${framework}${codegenFunctionsDirectory ? "_ssr" : ""}`;
|
|
251
256
|
if (codegenFunctionsDirectory) {
|
|
252
257
|
if (firebaseDefaults)
|
|
253
258
|
firebaseDefaults._authTokenSyncURL = "/__session";
|
|
@@ -12,6 +12,7 @@ const prompt_1 = require("../../prompt");
|
|
|
12
12
|
const semver_1 = require("semver");
|
|
13
13
|
const logger_1 = require("../../logger");
|
|
14
14
|
const error_1 = require("../../error");
|
|
15
|
+
const fsutils_1 = require("../../fsutils");
|
|
15
16
|
const CLI_COMMAND = (0, path_1.join)("node_modules", ".bin", process.platform === "win32" ? "next.cmd" : "next");
|
|
16
17
|
exports.name = "Next.js";
|
|
17
18
|
exports.support = "experimental";
|
|
@@ -20,6 +21,10 @@ function getNextVersion(cwd) {
|
|
|
20
21
|
var _a;
|
|
21
22
|
return (_a = (0, __1.findDependency)("next", { cwd, depth: 0, omitDev: false })) === null || _a === void 0 ? void 0 : _a.version;
|
|
22
23
|
}
|
|
24
|
+
function getReactVersion(cwd) {
|
|
25
|
+
var _a;
|
|
26
|
+
return (_a = (0, __1.findDependency)("react-dom", { cwd, omitDev: false })) === null || _a === void 0 ? void 0 : _a.version;
|
|
27
|
+
}
|
|
23
28
|
async function discover(dir) {
|
|
24
29
|
if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "package.json"))))
|
|
25
30
|
return;
|
|
@@ -30,6 +35,10 @@ async function discover(dir) {
|
|
|
30
35
|
exports.discover = discover;
|
|
31
36
|
async function build(dir) {
|
|
32
37
|
const { default: nextBuild } = (0, __1.relativeRequire)(dir, "next/dist/build");
|
|
38
|
+
const reactVersion = getReactVersion(dir);
|
|
39
|
+
if (reactVersion && (0, semver_1.gte)(reactVersion, "18.0.0")) {
|
|
40
|
+
process.env.__NEXT_REACT_ROOT = "true";
|
|
41
|
+
}
|
|
33
42
|
await nextBuild(dir, null, false, false, true).catch((e) => {
|
|
34
43
|
console.error(e.message);
|
|
35
44
|
throw e;
|
|
@@ -46,12 +55,19 @@ async function build(dir) {
|
|
|
46
55
|
const exportDetailBuffer = exportDetailExists ? await (0, promises_1.readFile)(exportDetailPath) : undefined;
|
|
47
56
|
const exportDetailJson = exportDetailBuffer && JSON.parse(exportDetailBuffer.toString());
|
|
48
57
|
if (exportDetailJson === null || exportDetailJson === void 0 ? void 0 : exportDetailJson.success) {
|
|
58
|
+
const appPathRoutesManifestPath = (0, path_1.join)(dir, distDir, "app-path-routes-manifest.json");
|
|
59
|
+
const appPathRoutesManifestJSON = (0, fsutils_1.fileExistsSync)(appPathRoutesManifestPath)
|
|
60
|
+
? await (0, promises_1.readFile)(appPathRoutesManifestPath).then((it) => JSON.parse(it.toString()))
|
|
61
|
+
: {};
|
|
49
62
|
const prerenderManifestJSON = await (0, promises_1.readFile)((0, path_1.join)(dir, distDir, "prerender-manifest.json")).then((it) => JSON.parse(it.toString()));
|
|
50
63
|
const anyDynamicRouteFallbacks = !!Object.values(prerenderManifestJSON.dynamicRoutes || {}).find((it) => it.fallback !== false);
|
|
51
64
|
const pagesManifestJSON = await (0, promises_1.readFile)((0, path_1.join)(dir, distDir, "server", "pages-manifest.json")).then((it) => JSON.parse(it.toString()));
|
|
52
65
|
const prerenderedRoutes = Object.keys(prerenderManifestJSON.routes);
|
|
53
66
|
const dynamicRoutes = Object.keys(prerenderManifestJSON.dynamicRoutes);
|
|
54
|
-
const unrenderedPages =
|
|
67
|
+
const unrenderedPages = [
|
|
68
|
+
...Object.keys(pagesManifestJSON),
|
|
69
|
+
...Object.values(appPathRoutesManifestJSON),
|
|
70
|
+
].filter((it) => !(["/_app", "/", "/_error", "/_document", "/404"].includes(it) ||
|
|
55
71
|
prerenderedRoutes.includes(it) ||
|
|
56
72
|
dynamicRoutes.includes(it)));
|
|
57
73
|
if (!anyDynamicRouteFallbacks && unrenderedPages.length === 0) {
|
|
@@ -85,7 +101,7 @@ async function init(setup) {
|
|
|
85
101
|
message: "What language would you like to use?",
|
|
86
102
|
choices: ["JavaScript", "TypeScript"],
|
|
87
103
|
});
|
|
88
|
-
(0, child_process_1.execSync)(`npx --yes create-next-app@latest -e hello-world ${setup.hosting.source} ${language === "TypeScript" ? "--ts" : ""}`, { stdio: "inherit" });
|
|
104
|
+
(0, child_process_1.execSync)(`npx --yes create-next-app@latest -e hello-world ${setup.hosting.source} --use-npm ${language === "TypeScript" ? "--ts" : ""}`, { stdio: "inherit" });
|
|
89
105
|
}
|
|
90
106
|
exports.init = init;
|
|
91
107
|
async function ɵcodegenPublicDirectory(sourceDir, destDir) {
|
|
@@ -104,20 +120,26 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir) {
|
|
|
104
120
|
await (0, fs_extra_1.copy)(publicPath, destDir);
|
|
105
121
|
}
|
|
106
122
|
await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, distDir, "static"), (0, path_1.join)(destDir, "_next", "static"));
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
for (const file of ["index.html", "404.html", "500.html"]) {
|
|
124
|
+
const pagesPath = (0, path_1.join)(sourceDir, distDir, "server", "pages", file);
|
|
125
|
+
if (await (0, fs_extra_1.pathExists)(pagesPath)) {
|
|
126
|
+
await (0, promises_1.copyFile)(pagesPath, (0, path_1.join)(destDir, file));
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const appPath = (0, path_1.join)(sourceDir, distDir, "server", "app", file);
|
|
130
|
+
if (await (0, fs_extra_1.pathExists)(appPath)) {
|
|
131
|
+
await (0, promises_1.copyFile)(appPath, (0, path_1.join)(destDir, file));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
116
134
|
const prerenderManifestBuffer = await (0, promises_1.readFile)((0, path_1.join)(sourceDir, distDir, "prerender-manifest.json"));
|
|
117
135
|
const prerenderManifest = JSON.parse(prerenderManifestBuffer.toString());
|
|
118
|
-
for (const
|
|
119
|
-
if (prerenderManifest.routes[
|
|
120
|
-
const
|
|
136
|
+
for (const path in prerenderManifest.routes) {
|
|
137
|
+
if (prerenderManifest.routes[path]) {
|
|
138
|
+
const { initialRevalidateSeconds } = prerenderManifest.routes[path];
|
|
139
|
+
if (initialRevalidateSeconds) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const parts = path
|
|
121
143
|
.split("/")
|
|
122
144
|
.slice(1)
|
|
123
145
|
.filter((it) => !!it);
|
|
@@ -125,10 +147,28 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir) {
|
|
|
125
147
|
const dataPath = `${(0, path_1.join)(...partsOrIndex)}.json`;
|
|
126
148
|
const htmlPath = `${(0, path_1.join)(...partsOrIndex)}.html`;
|
|
127
149
|
await (0, promises_1.mkdir)((0, path_1.join)(destDir, (0, path_1.dirname)(htmlPath)), { recursive: true });
|
|
128
|
-
|
|
129
|
-
|
|
150
|
+
const pagesHtmlPath = (0, path_1.join)(sourceDir, distDir, "server", "pages", htmlPath);
|
|
151
|
+
if (await (0, fs_extra_1.pathExists)(pagesHtmlPath)) {
|
|
152
|
+
await (0, promises_1.copyFile)(pagesHtmlPath, (0, path_1.join)(destDir, htmlPath));
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const appHtmlPath = (0, path_1.join)(sourceDir, distDir, "server", "app", htmlPath);
|
|
156
|
+
if (await (0, fs_extra_1.pathExists)(appHtmlPath)) {
|
|
157
|
+
await (0, promises_1.copyFile)(appHtmlPath, (0, path_1.join)(destDir, htmlPath));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const dataRoute = prerenderManifest.routes[path].dataRoute;
|
|
130
161
|
await (0, promises_1.mkdir)((0, path_1.join)(destDir, (0, path_1.dirname)(dataRoute)), { recursive: true });
|
|
131
|
-
|
|
162
|
+
const pagesDataPath = (0, path_1.join)(sourceDir, distDir, "server", "pages", dataPath);
|
|
163
|
+
if (await (0, fs_extra_1.pathExists)(pagesDataPath)) {
|
|
164
|
+
await (0, promises_1.copyFile)(pagesDataPath, (0, path_1.join)(destDir, dataRoute));
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const appDataPath = (0, path_1.join)(sourceDir, distDir, "server", "app", dataPath);
|
|
168
|
+
if (await (0, fs_extra_1.pathExists)(appDataPath)) {
|
|
169
|
+
await (0, promises_1.copyFile)(appDataPath, (0, path_1.join)(destDir, dataRoute));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
132
172
|
}
|
|
133
173
|
}
|
|
134
174
|
}
|
package/lib/serve/hosting.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.connect = exports.start = exports.stop = void 0;
|
|
4
4
|
const morgan = require("morgan");
|
|
5
|
-
const
|
|
5
|
+
const { server: superstatic } = require("superstatic");
|
|
6
6
|
const clc = require("colorette");
|
|
7
7
|
const net_1 = require("net");
|
|
8
8
|
const detectProjectRoot_1 = require("../detectProjectRoot");
|
|
@@ -36,13 +36,13 @@ function startServer(options, config, port, init) {
|
|
|
36
36
|
const after = options.frameworksDevModeHandle && {
|
|
37
37
|
files: options.frameworksDevModeHandle,
|
|
38
38
|
};
|
|
39
|
-
const server = (
|
|
39
|
+
const server = superstatic({
|
|
40
40
|
debug: false,
|
|
41
41
|
port: port,
|
|
42
|
-
|
|
42
|
+
host: options.host,
|
|
43
43
|
config: config,
|
|
44
44
|
compression: true,
|
|
45
|
-
cwd: (0, detectProjectRoot_1.detectProjectRoot)(options)
|
|
45
|
+
cwd: (0, detectProjectRoot_1.detectProjectRoot)(options),
|
|
46
46
|
stack: "strict",
|
|
47
47
|
before: {
|
|
48
48
|
files: (req, res, next) => {
|