firebase-tools 11.18.0 → 11.20.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.
- package/lib/api.js +3 -2
- package/lib/bin/firebase.js +0 -0
- package/lib/commands/functions-delete.js +1 -1
- package/lib/commands/index.js +5 -0
- package/lib/commands/internaltesting-functions-discover.js +25 -0
- package/lib/deploy/extensions/prepare.js +6 -1
- package/lib/deploy/extensions/v2FunctionHelper.js +53 -0
- package/lib/deploy/functions/build.js +17 -2
- package/lib/deploy/functions/cel.js +90 -13
- package/lib/deploy/functions/params.js +141 -6
- package/lib/deploy/functions/prepare.js +40 -25
- package/lib/deploy/functions/release/fabricator.js +27 -1
- package/lib/deploy/functions/runtimes/discovery/parsing.js +7 -1
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +1 -1
- package/lib/deploy/functions/runtimes/node/index.js +2 -2
- package/lib/deploy/functions/runtimes/node/versioning.js +30 -14
- package/lib/emulator/auth/operations.js +1 -1
- package/lib/emulator/commandUtils.js +2 -1
- package/lib/emulator/downloadableEmulators.js +6 -6
- package/lib/emulator/env.js +29 -27
- package/lib/emulator/extensionsEmulator.js +14 -9
- package/lib/emulator/functionsEmulator.js +16 -8
- package/lib/emulator/pubsubEmulator.js +13 -1
- package/lib/emulator/storage/rules/runtime.js +2 -2
- package/lib/emulator/workQueue.js +11 -6
- package/lib/experiments.js +6 -0
- package/lib/extensions/emulator/triggerHelper.js +12 -2
- package/lib/frameworks/index.js +7 -1
- package/lib/frameworks/next/constants.js +10 -0
- package/lib/frameworks/next/index.js +146 -146
- package/lib/frameworks/next/utils.js +65 -7
- package/lib/gcp/eventarc.js +42 -0
- package/lib/serve/hosting.js +5 -5
- package/npm-shrinkwrap.json +463 -737
- package/package.json +2 -5
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.functionResourceToEmulatedTriggerDefintion = void 0;
|
|
4
|
-
const functionsEmulatorShared_1 = require("../../emulator/functionsEmulatorShared");
|
|
5
4
|
const emulatorLogger_1 = require("../../emulator/emulatorLogger");
|
|
5
|
+
const functionsEmulatorShared_1 = require("../../emulator/functionsEmulatorShared");
|
|
6
6
|
const types_1 = require("../../emulator/types");
|
|
7
|
+
const error_1 = require("../../error");
|
|
7
8
|
const types_2 = require("../../extensions/types");
|
|
8
9
|
const proto = require("../../gcp/proto");
|
|
9
|
-
const error_1 = require("../../error");
|
|
10
10
|
function functionResourceToEmulatedTriggerDefintion(resource) {
|
|
11
11
|
const resourceType = resource.type;
|
|
12
12
|
if (resource.type === types_2.FUNCTIONS_RESOURCE_TYPE) {
|
|
@@ -29,6 +29,16 @@ function functionResourceToEmulatedTriggerDefintion(resource) {
|
|
|
29
29
|
service: (0, functionsEmulatorShared_1.getServiceFromEventType)(properties.eventTrigger.eventType),
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
+
else if (properties.scheduleTrigger) {
|
|
33
|
+
const schedule = {
|
|
34
|
+
schedule: properties.scheduleTrigger.schedule,
|
|
35
|
+
};
|
|
36
|
+
etd.schedule = schedule;
|
|
37
|
+
etd.eventTrigger = {
|
|
38
|
+
eventType: "google.pubsub.topic.publish",
|
|
39
|
+
resource: "",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
32
42
|
else {
|
|
33
43
|
emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS).log("WARN", `Function '${resource.name} is missing a trigger in extension.yaml. Please add one, as triggers defined in code are ignored.`);
|
|
34
44
|
}
|
package/lib/frameworks/index.js
CHANGED
|
@@ -230,7 +230,10 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
230
230
|
const { build, ɵcodegenPublicDirectory, ɵcodegenFunctionsDirectory: codegenProdModeFunctionsDirectory, getDevModeHandle, name, support, } = exports.WebFrameworks[framework];
|
|
231
231
|
console.log(`Detected a ${name} codebase. ${SupportLevelWarnings[support] || ""}\n`);
|
|
232
232
|
const isDevMode = context._name === "serve" || context._name === "emulators:start";
|
|
233
|
-
const
|
|
233
|
+
const hostingEmulatorInfo = emulators.find((e) => e.name === types_1.Emulators.HOSTING);
|
|
234
|
+
const devModeHandle = isDevMode &&
|
|
235
|
+
getDevModeHandle &&
|
|
236
|
+
(await getDevModeHandle(getProjectPath(), hostingEmulatorInfo));
|
|
234
237
|
let codegenFunctionsDirectory;
|
|
235
238
|
if (devModeHandle) {
|
|
236
239
|
config.public = (0, path_1.relative)(projectRoot, publicDirectory);
|
|
@@ -326,6 +329,9 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
326
329
|
${firebaseDefaults ? `__FIREBASE_DEFAULTS__=${JSON.stringify(firebaseDefaults)}\n` : ""}`);
|
|
327
330
|
await (0, promises_1.copyFile)(getProjectPath("package-lock.json"), (0, path_1.join)(functionsDist, "package-lock.json")).catch(() => {
|
|
328
331
|
});
|
|
332
|
+
if (await (0, fs_extra_1.pathExists)(getProjectPath(".npmrc"))) {
|
|
333
|
+
await (0, promises_1.copyFile)(getProjectPath(".npmrc"), (0, path_1.join)(functionsDist, ".npmrc"));
|
|
334
|
+
}
|
|
329
335
|
(0, child_process_1.execSync)(`${NPM_COMMAND} i --omit dev --no-audit`, {
|
|
330
336
|
cwd: functionsDist,
|
|
331
337
|
stdio: "inherit",
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
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
|
+
exports.APP_PATH_ROUTES_MANIFEST = "app-path-routes-manifest.json";
|
|
5
|
+
exports.EXPORT_MARKER = "export-marker.json";
|
|
6
|
+
exports.IMAGES_MANIFEST = "images-manifest.json";
|
|
7
|
+
exports.MIDDLEWARE_MANIFEST = "middleware-manifest.json";
|
|
8
|
+
exports.PAGES_MANIFEST = "pages-manifest.json";
|
|
9
|
+
exports.PRERENDER_MANIFEST = "prerender-manifest.json";
|
|
10
|
+
exports.ROUTES_MANIFEST = "routes-manifest.json";
|
|
@@ -7,20 +7,22 @@ const path_1 = require("path");
|
|
|
7
7
|
const fs_extra_1 = require("fs-extra");
|
|
8
8
|
const url_1 = require("url");
|
|
9
9
|
const fs_1 = require("fs");
|
|
10
|
+
const semver_1 = require("semver");
|
|
11
|
+
const clc = require("colorette");
|
|
10
12
|
const __1 = require("..");
|
|
11
13
|
const prompt_1 = require("../../prompt");
|
|
12
|
-
const semver_1 = require("semver");
|
|
13
|
-
const logger_1 = require("../../logger");
|
|
14
14
|
const error_1 = require("../../error");
|
|
15
|
-
const fsutils_1 = require("../../fsutils");
|
|
16
15
|
const utils_1 = require("./utils");
|
|
17
16
|
const utils_2 = require("../utils");
|
|
18
17
|
const utils_3 = require("../utils");
|
|
19
|
-
const
|
|
18
|
+
const utils_4 = require("./utils");
|
|
19
|
+
const constants_1 = require("./constants");
|
|
20
20
|
const DEFAULT_BUILD_SCRIPT = ["next build"];
|
|
21
|
+
const PUBLIC_DIR = "public";
|
|
21
22
|
exports.name = "Next.js";
|
|
22
23
|
exports.support = "experimental";
|
|
23
24
|
exports.type = 2;
|
|
25
|
+
const DEFAULT_NUMBER_OF_REASONS_TO_LIST = 5;
|
|
24
26
|
function getNextVersion(cwd) {
|
|
25
27
|
var _a;
|
|
26
28
|
return (_a = (0, __1.findDependency)("next", { cwd, depth: 0, omitDev: false })) === null || _a === void 0 ? void 0 : _a.version;
|
|
@@ -34,7 +36,7 @@ async function discover(dir) {
|
|
|
34
36
|
return;
|
|
35
37
|
if (!(await (0, fs_extra_1.pathExists)("next.config.js")) && !getNextVersion(dir))
|
|
36
38
|
return;
|
|
37
|
-
return { mayWantBackend: true, publicDirectory: (0, path_1.join)(dir,
|
|
39
|
+
return { mayWantBackend: true, publicDirectory: (0, path_1.join)(dir, PUBLIC_DIR) };
|
|
38
40
|
}
|
|
39
41
|
exports.discover = discover;
|
|
40
42
|
async function build(dir) {
|
|
@@ -49,51 +51,57 @@ async function build(dir) {
|
|
|
49
51
|
console.error(e.message);
|
|
50
52
|
throw e;
|
|
51
53
|
});
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
const reasonsForBackend = [];
|
|
55
|
+
const { distDir } = await getConfig(dir);
|
|
56
|
+
if (await (0, utils_1.isUsingMiddleware)((0, path_1.join)(dir, distDir), false)) {
|
|
57
|
+
reasonsForBackend.push("middleware");
|
|
54
58
|
}
|
|
55
|
-
|
|
59
|
+
if (await (0, utils_1.isUsingImageOptimization)((0, path_1.join)(dir, distDir))) {
|
|
60
|
+
reasonsForBackend.push(`Image Optimization`);
|
|
56
61
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
const prerenderedRoutes = Object.keys(prerenderManifestJSON.routes);
|
|
72
|
-
const dynamicRoutes = Object.keys(prerenderManifestJSON.dynamicRoutes);
|
|
73
|
-
const unrenderedPages = [
|
|
74
|
-
...Object.keys(pagesManifestJSON),
|
|
75
|
-
...Object.values(appPathRoutesManifestJSON),
|
|
76
|
-
].filter((it) => !(["/_app", "/", "/_error", "/_document", "/404"].includes(it) ||
|
|
77
|
-
prerenderedRoutes.includes(it) ||
|
|
78
|
-
dynamicRoutes.includes(it)));
|
|
79
|
-
if (!anyDynamicRouteFallbacks && unrenderedPages.length === 0) {
|
|
80
|
-
wantsBackend = false;
|
|
62
|
+
if ((0, utils_1.isUsingAppDirectory)((0, path_1.join)(dir, distDir))) {
|
|
63
|
+
reasonsForBackend.push("app directory (unstable)");
|
|
64
|
+
}
|
|
65
|
+
const prerenderManifest = await (0, utils_2.readJSON)((0, path_1.join)(dir, distDir, constants_1.PRERENDER_MANIFEST));
|
|
66
|
+
const dynamicRoutesWithFallback = Object.entries(prerenderManifest.dynamicRoutes || {}).filter(([, it]) => it.fallback !== false);
|
|
67
|
+
if (dynamicRoutesWithFallback.length > 0) {
|
|
68
|
+
for (const [key] of dynamicRoutesWithFallback) {
|
|
69
|
+
reasonsForBackend.push(`use of fallback ${key}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const routesWithRevalidate = Object.entries(prerenderManifest.routes).filter(([, it]) => it.initialRevalidateSeconds);
|
|
73
|
+
if (routesWithRevalidate.length > 0) {
|
|
74
|
+
for (const [key] of routesWithRevalidate) {
|
|
75
|
+
reasonsForBackend.push(`use of revalidate ${key}`);
|
|
81
76
|
}
|
|
82
77
|
}
|
|
83
|
-
const
|
|
78
|
+
const pagesManifestJSON = await (0, utils_2.readJSON)((0, path_1.join)(dir, distDir, "server", constants_1.PAGES_MANIFEST));
|
|
79
|
+
const prerenderedRoutes = Object.keys(prerenderManifest.routes);
|
|
80
|
+
const dynamicRoutes = Object.keys(prerenderManifest.dynamicRoutes);
|
|
81
|
+
const unrenderedPages = Object.keys(pagesManifestJSON).filter((it) => !(["/_app", "/", "/_error", "/_document", "/404"].includes(it) ||
|
|
82
|
+
prerenderedRoutes.includes(it) ||
|
|
83
|
+
dynamicRoutes.includes(it)));
|
|
84
|
+
if (unrenderedPages.length > 0) {
|
|
85
|
+
for (const key of unrenderedPages) {
|
|
86
|
+
reasonsForBackend.push(`non-static route ${key}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const manifest = await (0, utils_2.readJSON)((0, path_1.join)(dir, distDir, constants_1.ROUTES_MANIFEST));
|
|
84
90
|
const { headers: nextJsHeaders = [], redirects: nextJsRedirects = [], rewrites: nextJsRewrites = [], } = manifest;
|
|
85
|
-
const isEveryHeaderSupported = nextJsHeaders.every(utils_1.
|
|
86
|
-
if (!isEveryHeaderSupported)
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
const isEveryHeaderSupported = nextJsHeaders.every(utils_1.isHeaderSupportedByHosting);
|
|
92
|
+
if (!isEveryHeaderSupported) {
|
|
93
|
+
reasonsForBackend.push("advanced headers");
|
|
94
|
+
}
|
|
95
|
+
const headers = nextJsHeaders.filter(utils_1.isHeaderSupportedByHosting).map(({ source, headers }) => ({
|
|
89
96
|
source: (0, utils_1.cleanEscapedChars)(source),
|
|
90
97
|
headers,
|
|
91
98
|
}));
|
|
92
|
-
const isEveryRedirectSupported = nextJsRedirects.every(utils_1.
|
|
93
|
-
if (!isEveryRedirectSupported)
|
|
94
|
-
|
|
99
|
+
const isEveryRedirectSupported = nextJsRedirects.every(utils_1.isRedirectSupportedByHosting);
|
|
100
|
+
if (!isEveryRedirectSupported) {
|
|
101
|
+
reasonsForBackend.push("advanced redirects");
|
|
102
|
+
}
|
|
95
103
|
const redirects = nextJsRedirects
|
|
96
|
-
.filter(utils_1.
|
|
104
|
+
.filter(utils_1.isRedirectSupportedByHosting)
|
|
97
105
|
.map(({ source, destination, statusCode: type }) => ({
|
|
98
106
|
source: (0, utils_1.cleanEscapedChars)(source),
|
|
99
107
|
destination,
|
|
@@ -102,19 +110,30 @@ async function build(dir) {
|
|
|
102
110
|
const nextJsRewritesToUse = (0, utils_1.getNextjsRewritesToUse)(nextJsRewrites);
|
|
103
111
|
if (!Array.isArray(nextJsRewrites) &&
|
|
104
112
|
(((_a = nextJsRewrites.afterFiles) === null || _a === void 0 ? void 0 : _a.length) || ((_b = nextJsRewrites.fallback) === null || _b === void 0 ? void 0 : _b.length))) {
|
|
105
|
-
|
|
113
|
+
reasonsForBackend.push("advanced rewrites");
|
|
106
114
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
wantsBackend = true;
|
|
115
|
+
const isEveryRewriteSupported = nextJsRewritesToUse.every(utils_1.isRewriteSupportedByHosting);
|
|
116
|
+
if (!isEveryRewriteSupported) {
|
|
117
|
+
reasonsForBackend.push("advanced rewrites");
|
|
111
118
|
}
|
|
112
119
|
const rewrites = nextJsRewritesToUse
|
|
113
|
-
.filter(utils_1.
|
|
120
|
+
.filter(utils_1.isRewriteSupportedByHosting)
|
|
114
121
|
.map(({ source, destination }) => ({
|
|
115
122
|
source: (0, utils_1.cleanEscapedChars)(source),
|
|
116
123
|
destination,
|
|
117
124
|
}));
|
|
125
|
+
const wantsBackend = reasonsForBackend.length > 0;
|
|
126
|
+
if (wantsBackend) {
|
|
127
|
+
const numberOfReasonsToList = process.env.DEBUG ? Infinity : DEFAULT_NUMBER_OF_REASONS_TO_LIST;
|
|
128
|
+
console.log("Building a Cloud Function to run this application. This is needed due to:");
|
|
129
|
+
for (const reason of reasonsForBackend.slice(0, numberOfReasonsToList)) {
|
|
130
|
+
console.log(` • ${reason}`);
|
|
131
|
+
}
|
|
132
|
+
if (reasonsForBackend.length > numberOfReasonsToList) {
|
|
133
|
+
console.log(` • and ${reasonsForBackend.length - numberOfReasonsToList} other reasons, use --debug to see more`);
|
|
134
|
+
}
|
|
135
|
+
console.log("");
|
|
136
|
+
}
|
|
118
137
|
return { wantsBackend, headers, redirects, rewrites };
|
|
119
138
|
}
|
|
120
139
|
exports.build = build;
|
|
@@ -130,130 +149,111 @@ async function init(setup) {
|
|
|
130
149
|
exports.init = init;
|
|
131
150
|
async function ɵcodegenPublicDirectory(sourceDir, destDir) {
|
|
132
151
|
const { distDir } = await getConfig(sourceDir);
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (exportDetailJson === null || exportDetailJson === void 0 ? void 0 : exportDetailJson.success) {
|
|
138
|
-
(0, fs_extra_1.copy)(exportDetailJson.outDirectory, destDir);
|
|
152
|
+
const publicPath = (0, path_1.join)(sourceDir, "public");
|
|
153
|
+
await (0, promises_1.mkdir)((0, path_1.join)(destDir, "_next", "static"), { recursive: true });
|
|
154
|
+
if (await (0, fs_extra_1.pathExists)(publicPath)) {
|
|
155
|
+
await (0, fs_extra_1.copy)(publicPath, destDir);
|
|
139
156
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (await (0, fs_extra_1.pathExists)(
|
|
144
|
-
await (0,
|
|
157
|
+
await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, distDir, "static"), (0, path_1.join)(destDir, "_next", "static"));
|
|
158
|
+
for (const file of ["index.html", "404.html", "500.html"]) {
|
|
159
|
+
const pagesPath = (0, path_1.join)(sourceDir, distDir, "server", "pages", file);
|
|
160
|
+
if (await (0, fs_extra_1.pathExists)(pagesPath)) {
|
|
161
|
+
await (0, promises_1.copyFile)(pagesPath, (0, path_1.join)(destDir, file));
|
|
162
|
+
continue;
|
|
145
163
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (await (0, fs_extra_1.pathExists)(pagesPath)) {
|
|
150
|
-
await (0, promises_1.copyFile)(pagesPath, (0, path_1.join)(destDir, file));
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
const appPath = (0, path_1.join)(sourceDir, distDir, "server", "app", file);
|
|
154
|
-
if (await (0, fs_extra_1.pathExists)(appPath)) {
|
|
155
|
-
await (0, promises_1.copyFile)(appPath, (0, path_1.join)(destDir, file));
|
|
156
|
-
}
|
|
164
|
+
const appPath = (0, path_1.join)(sourceDir, distDir, "server", "app", file);
|
|
165
|
+
if (await (0, fs_extra_1.pathExists)(appPath)) {
|
|
166
|
+
await (0, promises_1.copyFile)(appPath, (0, path_1.join)(destDir, file));
|
|
157
167
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
await (0, promises_1.copyFile)(appHtmlPath, (0, path_1.join)(destDir, htmlPath));
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
const dataRoute = prerenderManifest.routes[path].dataRoute;
|
|
204
|
-
await (0, promises_1.mkdir)((0, path_1.join)(destDir, (0, path_1.dirname)(dataRoute)), { recursive: true });
|
|
205
|
-
const pagesDataPath = (0, path_1.join)(sourceDir, distDir, "server", "pages", dataPath);
|
|
206
|
-
if (await (0, fs_extra_1.pathExists)(pagesDataPath)) {
|
|
207
|
-
await (0, promises_1.copyFile)(pagesDataPath, (0, path_1.join)(destDir, dataRoute));
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
const appDataPath = (0, path_1.join)(sourceDir, distDir, "server", "app", dataPath);
|
|
211
|
-
if (await (0, fs_extra_1.pathExists)(appDataPath)) {
|
|
212
|
-
await (0, promises_1.copyFile)(appDataPath, (0, path_1.join)(destDir, dataRoute));
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
168
|
+
}
|
|
169
|
+
const [middlewareManifest, prerenderManifest, routesManifest] = await Promise.all([
|
|
170
|
+
(0, utils_2.readJSON)((0, path_1.join)(sourceDir, distDir, "server", constants_1.MIDDLEWARE_MANIFEST)),
|
|
171
|
+
(0, utils_2.readJSON)((0, path_1.join)(sourceDir, distDir, constants_1.PRERENDER_MANIFEST)),
|
|
172
|
+
(0, utils_2.readJSON)((0, path_1.join)(sourceDir, distDir, constants_1.ROUTES_MANIFEST)),
|
|
173
|
+
]);
|
|
174
|
+
const middlewareMatcherRegexes = Object.values(middlewareManifest.middleware)
|
|
175
|
+
.map((it) => it.matchers)
|
|
176
|
+
.flat()
|
|
177
|
+
.map((it) => new RegExp(it.regexp));
|
|
178
|
+
const { redirects = [], rewrites = [], headers = [] } = routesManifest;
|
|
179
|
+
const rewritesRegexesNotSupportedByHosting = (0, utils_1.getNextjsRewritesToUse)(rewrites)
|
|
180
|
+
.filter((rewrite) => !(0, utils_1.isRewriteSupportedByHosting)(rewrite))
|
|
181
|
+
.map((rewrite) => new RegExp(rewrite.regex));
|
|
182
|
+
const redirectsRegexesNotSupportedByHosting = redirects
|
|
183
|
+
.filter((redirect) => !(0, utils_1.isRedirectSupportedByHosting)(redirect))
|
|
184
|
+
.map((redirect) => new RegExp(redirect.regex));
|
|
185
|
+
const headersRegexesNotSupportedByHosting = headers
|
|
186
|
+
.filter((header) => !(0, utils_1.isHeaderSupportedByHosting)(header))
|
|
187
|
+
.map((header) => new RegExp(header.regex));
|
|
188
|
+
const pathsUsingsFeaturesNotSupportedByHosting = [
|
|
189
|
+
...middlewareMatcherRegexes,
|
|
190
|
+
...rewritesRegexesNotSupportedByHosting,
|
|
191
|
+
...redirectsRegexesNotSupportedByHosting,
|
|
192
|
+
...headersRegexesNotSupportedByHosting,
|
|
193
|
+
];
|
|
194
|
+
for (const [path, route] of Object.entries(prerenderManifest.routes)) {
|
|
195
|
+
if (route.initialRevalidateSeconds ||
|
|
196
|
+
pathsUsingsFeaturesNotSupportedByHosting.some((it) => path.match(it))) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const isReactServerComponent = route.dataRoute.endsWith(".rsc");
|
|
200
|
+
const contentDist = (0, path_1.join)(sourceDir, distDir, "server", isReactServerComponent ? "app" : "pages");
|
|
201
|
+
const parts = path.split("/").filter((it) => !!it);
|
|
202
|
+
const partsOrIndex = parts.length > 0 ? parts : ["index"];
|
|
203
|
+
const htmlPath = `${(0, path_1.join)(...partsOrIndex)}.html`;
|
|
204
|
+
await (0, promises_1.mkdir)((0, path_1.join)(destDir, (0, path_1.dirname)(htmlPath)), { recursive: true });
|
|
205
|
+
await (0, promises_1.copyFile)((0, path_1.join)(contentDist, htmlPath), (0, path_1.join)(destDir, htmlPath));
|
|
206
|
+
if (!isReactServerComponent) {
|
|
207
|
+
const dataPath = `${(0, path_1.join)(...partsOrIndex)}.json`;
|
|
208
|
+
await (0, promises_1.mkdir)((0, path_1.join)(destDir, (0, path_1.dirname)(route.dataRoute)), { recursive: true });
|
|
209
|
+
await (0, promises_1.copyFile)((0, path_1.join)(contentDist, dataPath), (0, path_1.join)(destDir, route.dataRoute));
|
|
216
210
|
}
|
|
217
211
|
}
|
|
218
212
|
}
|
|
219
213
|
exports.ɵcodegenPublicDirectory = ɵcodegenPublicDirectory;
|
|
220
214
|
async function ɵcodegenFunctionsDirectory(sourceDir, destDir) {
|
|
221
215
|
const { distDir } = await getConfig(sourceDir);
|
|
222
|
-
const
|
|
223
|
-
const packageJson = JSON.parse(packageJsonBuffer.toString());
|
|
216
|
+
const packageJson = await (0, utils_2.readJSON)((0, path_1.join)(sourceDir, "package.json"));
|
|
224
217
|
if ((0, fs_1.existsSync)((0, path_1.join)(sourceDir, "next.config.js"))) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
await esbuild.build({
|
|
234
|
-
bundle: true,
|
|
235
|
-
external: Object.keys(packageJson.dependencies),
|
|
236
|
-
absWorkingDir: sourceDir,
|
|
237
|
-
entryPoints: ["next.config.js"],
|
|
238
|
-
outfile: (0, path_1.join)(destDir, "next.config.js"),
|
|
239
|
-
target: `node${__1.NODE_VERSION}`,
|
|
240
|
-
platform: "node",
|
|
218
|
+
const dependencyTree = JSON.parse((0, child_process_1.spawnSync)("npm", ["ls", "--omit=dev", "--all", "--json"], {
|
|
219
|
+
cwd: sourceDir,
|
|
220
|
+
}).stdout.toString());
|
|
221
|
+
const esbuildArgs = (0, utils_1.allDependencyNames)(dependencyTree)
|
|
222
|
+
.map((it) => `--external:${it}`)
|
|
223
|
+
.concat("--bundle", "--platform=node", `--target=node${__1.NODE_VERSION}`, `--outdir=${destDir}`, "--log-level=error");
|
|
224
|
+
const bundle = (0, child_process_1.spawnSync)("npx", ["--yes", "esbuild", "next.config.js", ...esbuildArgs], {
|
|
225
|
+
cwd: sourceDir,
|
|
241
226
|
});
|
|
227
|
+
if (bundle.status) {
|
|
228
|
+
console.error(bundle.stderr.toString());
|
|
229
|
+
throw new error_1.FirebaseError("Unable to bundle next.config.js for use in Cloud Functions");
|
|
230
|
+
}
|
|
242
231
|
}
|
|
243
232
|
if (await (0, fs_extra_1.pathExists)((0, path_1.join)(sourceDir, "public"))) {
|
|
244
233
|
await (0, promises_1.mkdir)((0, path_1.join)(destDir, "public"));
|
|
245
234
|
await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, "public"), (0, path_1.join)(destDir, "public"));
|
|
246
235
|
}
|
|
236
|
+
if (!(await (0, utils_4.hasUnoptimizedImage)(sourceDir, distDir)) &&
|
|
237
|
+
((0, utils_4.usesAppDirRouter)(sourceDir) || (await (0, utils_4.usesNextImage)(sourceDir, distDir)))) {
|
|
238
|
+
packageJson.dependencies["sharp"] = "latest";
|
|
239
|
+
}
|
|
247
240
|
await (0, fs_extra_1.mkdirp)((0, path_1.join)(destDir, distDir));
|
|
248
241
|
await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, distDir), (0, path_1.join)(destDir, distDir));
|
|
249
242
|
return { packageJson, frameworksEntry: "next.js" };
|
|
250
243
|
}
|
|
251
244
|
exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
|
|
252
|
-
async function getDevModeHandle(dir) {
|
|
245
|
+
async function getDevModeHandle(dir, hostingEmulatorInfo) {
|
|
246
|
+
if (!hostingEmulatorInfo) {
|
|
247
|
+
if (await (0, utils_1.isUsingMiddleware)(dir, true)) {
|
|
248
|
+
throw new error_1.FirebaseError(`${clc.bold("firebase serve")} does not support Next.js Middleware. Please use ${clc.bold("firebase emulators:start")} instead.`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
253
251
|
const { default: next } = (0, __1.relativeRequire)(dir, "next");
|
|
254
252
|
const nextApp = next({
|
|
255
253
|
dev: true,
|
|
256
254
|
dir,
|
|
255
|
+
hostname: hostingEmulatorInfo === null || hostingEmulatorInfo === void 0 ? void 0 : hostingEmulatorInfo.host,
|
|
256
|
+
port: hostingEmulatorInfo === null || hostingEmulatorInfo === void 0 ? void 0 : hostingEmulatorInfo.port,
|
|
257
257
|
});
|
|
258
258
|
const handler = nextApp.getRequestHandler();
|
|
259
259
|
await nextApp.prepare();
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getNextjsRewritesToUse = exports.
|
|
3
|
+
exports.allDependencyNames = exports.isUsingAppDirectory = exports.isUsingImageOptimization = exports.isUsingMiddleware = exports.hasUnoptimizedImage = exports.usesNextImage = exports.usesAppDirRouter = exports.getNextjsRewritesToUse = exports.isHeaderSupportedByHosting = exports.isRedirectSupportedByHosting = exports.isRewriteSupportedByHosting = exports.cleanEscapedChars = exports.pathHasRegex = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const fs_extra_1 = require("fs-extra");
|
|
6
|
+
const path_1 = require("path");
|
|
4
7
|
const utils_1 = require("../utils");
|
|
8
|
+
const constants_1 = require("./constants");
|
|
9
|
+
const fsutils_1 = require("../../fsutils");
|
|
5
10
|
function pathHasRegex(path) {
|
|
6
11
|
return /(?<!\\)\(/.test(path);
|
|
7
12
|
}
|
|
@@ -10,18 +15,18 @@ function cleanEscapedChars(path) {
|
|
|
10
15
|
return path.replace(/\\([(){}:+?*])/g, (a, b) => b);
|
|
11
16
|
}
|
|
12
17
|
exports.cleanEscapedChars = cleanEscapedChars;
|
|
13
|
-
function
|
|
18
|
+
function isRewriteSupportedByHosting(rewrite) {
|
|
14
19
|
return !("has" in rewrite || pathHasRegex(rewrite.source) || (0, utils_1.isUrl)(rewrite.destination));
|
|
15
20
|
}
|
|
16
|
-
exports.
|
|
17
|
-
function
|
|
21
|
+
exports.isRewriteSupportedByHosting = isRewriteSupportedByHosting;
|
|
22
|
+
function isRedirectSupportedByHosting(redirect) {
|
|
18
23
|
return !("has" in redirect || pathHasRegex(redirect.source) || "internal" in redirect);
|
|
19
24
|
}
|
|
20
|
-
exports.
|
|
21
|
-
function
|
|
25
|
+
exports.isRedirectSupportedByHosting = isRedirectSupportedByHosting;
|
|
26
|
+
function isHeaderSupportedByHosting(header) {
|
|
22
27
|
return !("has" in header || pathHasRegex(header.source));
|
|
23
28
|
}
|
|
24
|
-
exports.
|
|
29
|
+
exports.isHeaderSupportedByHosting = isHeaderSupportedByHosting;
|
|
25
30
|
function getNextjsRewritesToUse(nextJsRewrites) {
|
|
26
31
|
if (Array.isArray(nextJsRewrites)) {
|
|
27
32
|
return nextJsRewrites;
|
|
@@ -32,3 +37,56 @@ function getNextjsRewritesToUse(nextJsRewrites) {
|
|
|
32
37
|
return [];
|
|
33
38
|
}
|
|
34
39
|
exports.getNextjsRewritesToUse = getNextjsRewritesToUse;
|
|
40
|
+
function usesAppDirRouter(sourceDir) {
|
|
41
|
+
const appPathRoutesManifestPath = (0, path_1.join)(sourceDir, constants_1.APP_PATH_ROUTES_MANIFEST);
|
|
42
|
+
return (0, fs_1.existsSync)(appPathRoutesManifestPath);
|
|
43
|
+
}
|
|
44
|
+
exports.usesAppDirRouter = usesAppDirRouter;
|
|
45
|
+
async function usesNextImage(sourceDir, distDir) {
|
|
46
|
+
const exportMarker = await (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, constants_1.EXPORT_MARKER));
|
|
47
|
+
return exportMarker.isNextImageImported;
|
|
48
|
+
}
|
|
49
|
+
exports.usesNextImage = usesNextImage;
|
|
50
|
+
async function hasUnoptimizedImage(sourceDir, distDir) {
|
|
51
|
+
const imagesManifest = await (0, utils_1.readJSON)((0, path_1.join)(sourceDir, distDir, constants_1.IMAGES_MANIFEST));
|
|
52
|
+
return imagesManifest.images.unoptimized;
|
|
53
|
+
}
|
|
54
|
+
exports.hasUnoptimizedImage = hasUnoptimizedImage;
|
|
55
|
+
async function isUsingMiddleware(dir, isDevMode) {
|
|
56
|
+
if (isDevMode) {
|
|
57
|
+
const [middlewareJs, middlewareTs] = await Promise.all([
|
|
58
|
+
(0, fs_extra_1.pathExists)((0, path_1.join)(dir, "middleware.js")),
|
|
59
|
+
(0, fs_extra_1.pathExists)((0, path_1.join)(dir, "middleware.ts")),
|
|
60
|
+
]);
|
|
61
|
+
return middlewareJs || middlewareTs;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const middlewareManifest = await (0, utils_1.readJSON)((0, path_1.join)(dir, "server", constants_1.MIDDLEWARE_MANIFEST));
|
|
65
|
+
return Object.keys(middlewareManifest.middleware).length > 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.isUsingMiddleware = isUsingMiddleware;
|
|
69
|
+
async function isUsingImageOptimization(dir) {
|
|
70
|
+
const { isNextImageImported } = await (0, utils_1.readJSON)((0, path_1.join)(dir, constants_1.EXPORT_MARKER));
|
|
71
|
+
if (isNextImageImported) {
|
|
72
|
+
const imagesManifest = await (0, utils_1.readJSON)((0, path_1.join)(dir, constants_1.IMAGES_MANIFEST));
|
|
73
|
+
const usingImageOptimization = imagesManifest.images.unoptimized === false;
|
|
74
|
+
if (usingImageOptimization) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
exports.isUsingImageOptimization = isUsingImageOptimization;
|
|
81
|
+
function isUsingAppDirectory(dir) {
|
|
82
|
+
const appPathRoutesManifestPath = (0, path_1.join)(dir, constants_1.APP_PATH_ROUTES_MANIFEST);
|
|
83
|
+
return (0, fsutils_1.fileExistsSync)(appPathRoutesManifestPath);
|
|
84
|
+
}
|
|
85
|
+
exports.isUsingAppDirectory = isUsingAppDirectory;
|
|
86
|
+
function allDependencyNames(mod) {
|
|
87
|
+
if (!mod.dependencies)
|
|
88
|
+
return [];
|
|
89
|
+
const dependencyNames = Object.keys(mod.dependencies).reduce((acc, it) => [...acc, it, ...allDependencyNames(mod.dependencies[it])], []);
|
|
90
|
+
return [...new Set(dependencyNames)];
|
|
91
|
+
}
|
|
92
|
+
exports.allDependencyNames = allDependencyNames;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteChannel = exports.updateChannel = exports.createChannel = exports.getChannel = exports.API_VERSION = void 0;
|
|
4
|
+
const apiv2_1 = require("../apiv2");
|
|
5
|
+
const api_1 = require("../api");
|
|
6
|
+
const lodash_1 = require("lodash");
|
|
7
|
+
const proto_1 = require("./proto");
|
|
8
|
+
exports.API_VERSION = "v1";
|
|
9
|
+
const client = new apiv2_1.Client({
|
|
10
|
+
urlPrefix: api_1.eventarcOrigin,
|
|
11
|
+
auth: true,
|
|
12
|
+
apiVersion: exports.API_VERSION,
|
|
13
|
+
});
|
|
14
|
+
async function getChannel(name) {
|
|
15
|
+
const res = await client.get(name);
|
|
16
|
+
if (res.status === 404) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
return res.body;
|
|
20
|
+
}
|
|
21
|
+
exports.getChannel = getChannel;
|
|
22
|
+
async function createChannel(channel) {
|
|
23
|
+
const pathParts = channel.name.split("/");
|
|
24
|
+
const res = await client.post(pathParts.slice(0, -1).join("/"), channel, {
|
|
25
|
+
queryParams: { channelId: (0, lodash_1.last)(pathParts) },
|
|
26
|
+
});
|
|
27
|
+
return res.body;
|
|
28
|
+
}
|
|
29
|
+
exports.createChannel = createChannel;
|
|
30
|
+
async function updateChannel(channel) {
|
|
31
|
+
const res = await client.put(channel.name, channel, {
|
|
32
|
+
queryParams: {
|
|
33
|
+
updateMask: (0, proto_1.fieldMasks)(channel).join(","),
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
return res.body;
|
|
37
|
+
}
|
|
38
|
+
exports.updateChannel = updateChannel;
|
|
39
|
+
async function deleteChannel(name) {
|
|
40
|
+
await client.delete(name);
|
|
41
|
+
}
|
|
42
|
+
exports.deleteChannel = deleteChannel;
|
package/lib/serve/hosting.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
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 { server: superstatic } = require("superstatic");
|
|
6
|
-
const clc = require("colorette");
|
|
7
5
|
const net_1 = require("net");
|
|
6
|
+
const superstatic_1 = require("superstatic");
|
|
7
|
+
const clc = require("colorette");
|
|
8
8
|
const detectProjectRoot_1 = require("../detectProjectRoot");
|
|
9
9
|
const error_1 = require("../error");
|
|
10
10
|
const implicitInit_1 = require("../hosting/implicitInit");
|
|
@@ -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 = (0, superstatic_1.server)({
|
|
40
40
|
debug: false,
|
|
41
41
|
port: port,
|
|
42
|
-
|
|
42
|
+
hostname: options.host,
|
|
43
43
|
config: config,
|
|
44
44
|
compression: true,
|
|
45
|
-
cwd: (0, detectProjectRoot_1.detectProjectRoot)(options),
|
|
45
|
+
cwd: (0, detectProjectRoot_1.detectProjectRoot)(options) || undefined,
|
|
46
46
|
stack: "strict",
|
|
47
47
|
before: {
|
|
48
48
|
files: (req, res, next) => {
|