firebase-tools 12.2.1 → 12.3.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/functions-secrets-access.js +2 -0
- package/lib/commands/functions-secrets-destroy.js +1 -0
- package/lib/commands/functions-secrets-get.js +2 -0
- package/lib/commands/functions-secrets-prune.js +3 -2
- package/lib/commands/functions-secrets-set.js +8 -0
- package/lib/commands/hosting-channel-deploy.js +5 -3
- package/lib/commands/index.js +2 -0
- package/lib/commands/internaltesting-frameworks-compose.js +20 -0
- package/lib/deploy/functions/release/executor.js +19 -10
- package/lib/deploy/functions/release/fabricator.js +22 -8
- package/lib/deploy/index.js +1 -1
- package/lib/emulator/auth/operations.js +2 -2
- package/lib/emulator/commandUtils.js +1 -1
- package/lib/emulator/controller.js +6 -2
- package/lib/emulator/functionsEmulatorShared.js +3 -0
- package/lib/frameworks/angular/index.js +10 -9
- package/lib/frameworks/astro/index.js +8 -6
- package/lib/frameworks/compose/discover/index.js +23 -0
- package/lib/frameworks/compose/driver/docker.js +177 -0
- package/lib/frameworks/compose/driver/hooks.js +22 -0
- package/lib/frameworks/compose/driver/index.js +16 -0
- package/lib/frameworks/compose/driver/local.js +42 -0
- package/lib/frameworks/compose/index.js +30 -0
- package/lib/frameworks/compose/interfaces.js +21 -0
- package/lib/frameworks/index.js +57 -48
- package/lib/frameworks/next/index.js +18 -17
- package/lib/frameworks/nuxt/index.js +7 -7
- package/lib/frameworks/nuxt2/index.js +2 -1
- package/lib/frameworks/utils.js +37 -22
- package/lib/frameworks/vite/index.js +2 -1
- package/lib/functions/secrets.js +8 -1
- package/lib/serve/index.js +1 -1
- package/package.json +1 -1
- package/templates/extensions/extension.yaml +7 -57
- package/templates/extensions/javascript/index.js +1 -1
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DockerDriver = exports.DockerfileBuilder = void 0;
|
|
4
|
+
const fs = require("node:fs");
|
|
5
|
+
const path = require("node:path");
|
|
6
|
+
const spawn = require("cross-spawn");
|
|
7
|
+
const hooks_1 = require("./hooks");
|
|
8
|
+
const ADAPTER_SCRIPTS_PATH = "./.firebase/adapters";
|
|
9
|
+
const DOCKER_STAGE_INSTALL = "installer";
|
|
10
|
+
const DOCKER_STAGE_BUILD = "builder";
|
|
11
|
+
class DockerfileBuilder {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.dockerfile = "";
|
|
14
|
+
this.lastStage = "";
|
|
15
|
+
}
|
|
16
|
+
from(image, name) {
|
|
17
|
+
this.dockerfile += `FROM ${image}`;
|
|
18
|
+
if (name) {
|
|
19
|
+
this.dockerfile += ` AS ${name}`;
|
|
20
|
+
this.lastStage = name;
|
|
21
|
+
}
|
|
22
|
+
this.dockerfile += "\n";
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
fromLastStage(name) {
|
|
26
|
+
return this.from(this.lastStage, name);
|
|
27
|
+
}
|
|
28
|
+
tempFrom(image, name) {
|
|
29
|
+
this.dockerfile += `FROM ${image}`;
|
|
30
|
+
if (name) {
|
|
31
|
+
this.dockerfile += ` AS ${name}`;
|
|
32
|
+
}
|
|
33
|
+
this.dockerfile += "\n";
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
workdir(dir) {
|
|
37
|
+
this.dockerfile += `WORKDIR ${dir}\n`;
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
copyForFirebase(src, dest, from) {
|
|
41
|
+
if (from) {
|
|
42
|
+
this.dockerfile += `COPY --chown=firebase:firebase --from=${from} ${src} ${dest}\n`;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.dockerfile += `COPY --chown=firebase:firebase ${src} ${dest}\n`;
|
|
46
|
+
}
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
copyFrom(src, dest, from) {
|
|
50
|
+
this.dockerfile += `COPY --from=${from} ${src} ${dest}\n`;
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
run(cmd, mount) {
|
|
54
|
+
if (mount) {
|
|
55
|
+
this.dockerfile += `RUN --mount=${mount} ${cmd}\n`;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.dockerfile += `RUN ${cmd}\n`;
|
|
59
|
+
}
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
env(key, value) {
|
|
63
|
+
this.dockerfile += `ENV ${key}="${value}"\n`;
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
envs(envs) {
|
|
67
|
+
for (const [key, value] of Object.entries(envs)) {
|
|
68
|
+
this.env(key, value);
|
|
69
|
+
}
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
cmd(cmds) {
|
|
73
|
+
this.dockerfile += `CMD [${cmds.map((c) => `"${c}"`).join(", ")}]\n`;
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
user(user) {
|
|
77
|
+
this.dockerfile += `USER ${user}\n`;
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
toString() {
|
|
81
|
+
return this.dockerfile;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.DockerfileBuilder = DockerfileBuilder;
|
|
85
|
+
class DockerDriver {
|
|
86
|
+
constructor(spec) {
|
|
87
|
+
this.spec = spec;
|
|
88
|
+
this.dockerfileBuilder = new DockerfileBuilder();
|
|
89
|
+
this.dockerfileBuilder.from(spec.baseImage, "base").user("firebase");
|
|
90
|
+
}
|
|
91
|
+
execDockerPush(args) {
|
|
92
|
+
console.log(`executing docker build: ${args.join(" ")}`);
|
|
93
|
+
return spawn.sync("docker", ["push", ...args], {
|
|
94
|
+
stdio: ["pipe", "inherit", "inherit"],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
execDockerBuild(args, contextDir) {
|
|
98
|
+
console.log(`executing docker build: ${args.join(" ")} ${contextDir}`);
|
|
99
|
+
console.log(this.dockerfileBuilder.toString());
|
|
100
|
+
return spawn.sync("docker", ["buildx", "build", ...args, "-f", "-", contextDir], {
|
|
101
|
+
env: Object.assign(Object.assign({}, process.env), this.spec.environmentVariables),
|
|
102
|
+
input: this.dockerfileBuilder.toString(),
|
|
103
|
+
stdio: ["pipe", "inherit", "inherit"],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
buildStage(stage, contextDir, tag) {
|
|
107
|
+
console.log(`Building stage: ${stage}`);
|
|
108
|
+
const args = ["--target", stage];
|
|
109
|
+
if (tag) {
|
|
110
|
+
args.push("--tag", tag);
|
|
111
|
+
}
|
|
112
|
+
const ret = this.execDockerBuild(args, contextDir);
|
|
113
|
+
if (ret.error || ret.status !== 0) {
|
|
114
|
+
throw new Error(`Failed to execute stage ${stage}: error=${ret.error} status=${ret.status}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exportBundle(stage, contextDir) {
|
|
118
|
+
const exportStage = `${stage}-export`;
|
|
119
|
+
this.dockerfileBuilder
|
|
120
|
+
.tempFrom("scratch", exportStage)
|
|
121
|
+
.copyFrom(hooks_1.BUNDLE_PATH, "/bundle.json", stage);
|
|
122
|
+
const ret = this.execDockerBuild(["--target", exportStage, "--output", ".firebase/.output"], contextDir);
|
|
123
|
+
if (ret.error || ret.status !== 0) {
|
|
124
|
+
throw new Error(`Failed to export bundle ${stage}: error=${ret.error} status=${ret.status}`);
|
|
125
|
+
}
|
|
126
|
+
return JSON.parse(fs.readFileSync("./.firebase/.output/bundle.json", "utf8"));
|
|
127
|
+
}
|
|
128
|
+
install() {
|
|
129
|
+
this.dockerfileBuilder
|
|
130
|
+
.fromLastStage(DOCKER_STAGE_INSTALL)
|
|
131
|
+
.workdir("/home/firebase/app")
|
|
132
|
+
.envs(this.spec.environmentVariables || {})
|
|
133
|
+
.copyForFirebase("package.json", ".")
|
|
134
|
+
.run(this.spec.installCommand);
|
|
135
|
+
this.buildStage(DOCKER_STAGE_INSTALL, ".");
|
|
136
|
+
}
|
|
137
|
+
build() {
|
|
138
|
+
this.dockerfileBuilder
|
|
139
|
+
.fromLastStage(DOCKER_STAGE_BUILD)
|
|
140
|
+
.copyForFirebase(".", ".")
|
|
141
|
+
.run(this.spec.buildCommand);
|
|
142
|
+
this.buildStage(DOCKER_STAGE_BUILD, ".");
|
|
143
|
+
}
|
|
144
|
+
export(bundle) {
|
|
145
|
+
var _a;
|
|
146
|
+
const startCmd = (_a = bundle.server) === null || _a === void 0 ? void 0 : _a.start.cmd;
|
|
147
|
+
if (startCmd) {
|
|
148
|
+
const exportStage = "exporter";
|
|
149
|
+
this.dockerfileBuilder
|
|
150
|
+
.from(this.spec.baseImage, exportStage)
|
|
151
|
+
.workdir("/home/firebase/app")
|
|
152
|
+
.copyForFirebase("/home/firebase/app", ".", DOCKER_STAGE_BUILD)
|
|
153
|
+
.cmd(startCmd);
|
|
154
|
+
const imageName = `us-docker.pkg.dev/${process.env.PROJECT_ID}/test/demo-nodappe`;
|
|
155
|
+
this.buildStage(exportStage, ".", imageName);
|
|
156
|
+
const ret = this.execDockerPush([imageName]);
|
|
157
|
+
if (ret.error || ret.status !== 0) {
|
|
158
|
+
throw new Error(`Failed to push image ${imageName}: error=${ret.error} status=${ret.status}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
execHook(bundle, hook) {
|
|
163
|
+
const hookScript = `hook-${Date.now()}.js`;
|
|
164
|
+
const hookScriptSrc = (0, hooks_1.genHookScript)(bundle, hook);
|
|
165
|
+
if (!fs.existsSync(ADAPTER_SCRIPTS_PATH)) {
|
|
166
|
+
fs.mkdirSync(ADAPTER_SCRIPTS_PATH, { recursive: true });
|
|
167
|
+
}
|
|
168
|
+
fs.writeFileSync(path.join(ADAPTER_SCRIPTS_PATH, hookScript), hookScriptSrc);
|
|
169
|
+
const hookStage = path.basename(hookScript, ".js");
|
|
170
|
+
this.dockerfileBuilder
|
|
171
|
+
.fromLastStage(hookStage)
|
|
172
|
+
.run(`NODE_PATH=./node_modules node /framework/adapters/${hookScript}`, `source=${ADAPTER_SCRIPTS_PATH},target=/framework/adapters`);
|
|
173
|
+
this.buildStage(hookStage, ".");
|
|
174
|
+
return this.exportBundle(hookStage, ".");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
exports.DockerDriver = DockerDriver;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.genHookScript = exports.BUNDLE_PATH = void 0;
|
|
4
|
+
exports.BUNDLE_PATH = "/home/firebase/app/.firebase/.output/bundle.json";
|
|
5
|
+
function genHookScript(bundle, hook) {
|
|
6
|
+
let hookSrc = hook.toString().trimLeft();
|
|
7
|
+
if (!hookSrc.startsWith("(") && !hookSrc.startsWith("function ")) {
|
|
8
|
+
hookSrc = `function ${hookSrc}`;
|
|
9
|
+
}
|
|
10
|
+
return `
|
|
11
|
+
const fs = require("node:fs");
|
|
12
|
+
const path = require("node:path");
|
|
13
|
+
|
|
14
|
+
const bundleDir = path.dirname("${exports.BUNDLE_PATH}");
|
|
15
|
+
if (!fs.existsSync(bundleDir)) {
|
|
16
|
+
fs.mkdirSync(bundleDir, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
const bundle = (${hookSrc})(${JSON.stringify(bundle)});
|
|
19
|
+
fs.writeFileSync("${exports.BUNDLE_PATH}", JSON.stringify(bundle));
|
|
20
|
+
`;
|
|
21
|
+
}
|
|
22
|
+
exports.genHookScript = genHookScript;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDriver = exports.SUPPORTED_MODES = void 0;
|
|
4
|
+
const local_1 = require("./local");
|
|
5
|
+
const docker_1 = require("./docker");
|
|
6
|
+
exports.SUPPORTED_MODES = ["local", "docker"];
|
|
7
|
+
function getDriver(mode, app) {
|
|
8
|
+
if (mode === "local") {
|
|
9
|
+
return new local_1.LocalDriver(app);
|
|
10
|
+
}
|
|
11
|
+
else if (mode === "docker") {
|
|
12
|
+
return new docker_1.DockerDriver(app);
|
|
13
|
+
}
|
|
14
|
+
throw new Error(`Unsupported mode ${mode}`);
|
|
15
|
+
}
|
|
16
|
+
exports.getDriver = getDriver;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LocalDriver = void 0;
|
|
4
|
+
const fs = require("node:fs");
|
|
5
|
+
const spawn = require("cross-spawn");
|
|
6
|
+
const hooks_1 = require("./hooks");
|
|
7
|
+
class LocalDriver {
|
|
8
|
+
constructor(spec) {
|
|
9
|
+
this.spec = spec;
|
|
10
|
+
}
|
|
11
|
+
execCmd(cmd, args) {
|
|
12
|
+
const ret = spawn.sync(cmd, args, {
|
|
13
|
+
env: Object.assign(Object.assign({}, process.env), this.spec.environmentVariables),
|
|
14
|
+
stdio: ["pipe", "inherit", "inherit"],
|
|
15
|
+
});
|
|
16
|
+
if (ret.error) {
|
|
17
|
+
throw ret.error;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
install() {
|
|
21
|
+
const [cmd, ...args] = this.spec.installCommand.split(" ");
|
|
22
|
+
this.execCmd(cmd, args);
|
|
23
|
+
}
|
|
24
|
+
build() {
|
|
25
|
+
const [cmd, ...args] = this.spec.buildCommand.split(" ");
|
|
26
|
+
this.execCmd(cmd, args);
|
|
27
|
+
}
|
|
28
|
+
export(bundle) {
|
|
29
|
+
}
|
|
30
|
+
execHook(bundle, hook) {
|
|
31
|
+
const script = (0, hooks_1.genHookScript)(bundle, hook);
|
|
32
|
+
this.execCmd("node", ["-e", script]);
|
|
33
|
+
if (!fs.existsSync(hooks_1.BUNDLE_PATH)) {
|
|
34
|
+
console.warn(`Expected hook to generate app bundle at ${hooks_1.BUNDLE_PATH} but got nothing.`);
|
|
35
|
+
console.warn("Returning original bundle.");
|
|
36
|
+
return bundle;
|
|
37
|
+
}
|
|
38
|
+
const newBundle = JSON.parse(fs.readFileSync(hooks_1.BUNDLE_PATH, "utf8"));
|
|
39
|
+
return newBundle;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.LocalDriver = LocalDriver;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compose = void 0;
|
|
4
|
+
const driver_1 = require("./driver");
|
|
5
|
+
const discover_1 = require("./discover");
|
|
6
|
+
function compose(mode) {
|
|
7
|
+
let bundle = { version: "v1alpha" };
|
|
8
|
+
const spec = (0, discover_1.discover)();
|
|
9
|
+
const driver = (0, driver_1.getDriver)(mode, spec);
|
|
10
|
+
if (spec.startCommand) {
|
|
11
|
+
bundle.server = {
|
|
12
|
+
start: {
|
|
13
|
+
cmd: spec.startCommand.split(" "),
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
driver.install();
|
|
18
|
+
if (spec.afterInstall) {
|
|
19
|
+
bundle = driver.execHook(bundle, spec.afterInstall);
|
|
20
|
+
}
|
|
21
|
+
driver.build();
|
|
22
|
+
if (spec.afterBuild) {
|
|
23
|
+
bundle = driver.execHook(bundle, spec.afterBuild);
|
|
24
|
+
}
|
|
25
|
+
if (bundle.server) {
|
|
26
|
+
driver.export(bundle);
|
|
27
|
+
}
|
|
28
|
+
return bundle;
|
|
29
|
+
}
|
|
30
|
+
exports.compose = compose;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Driver = void 0;
|
|
4
|
+
class Driver {
|
|
5
|
+
constructor(spec) {
|
|
6
|
+
this.spec = spec;
|
|
7
|
+
}
|
|
8
|
+
install() {
|
|
9
|
+
throw new Error("install() not implemented");
|
|
10
|
+
}
|
|
11
|
+
build() {
|
|
12
|
+
throw new Error("build() not implemented");
|
|
13
|
+
}
|
|
14
|
+
export(bundle) {
|
|
15
|
+
throw new Error("export() not implemented");
|
|
16
|
+
}
|
|
17
|
+
execHook(bundle, hook) {
|
|
18
|
+
throw new Error("execHook() not implemented");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.Driver = Driver;
|
package/lib/frameworks/index.js
CHANGED
|
@@ -8,7 +8,6 @@ const cross_spawn_1 = require("cross-spawn");
|
|
|
8
8
|
const promises_1 = require("fs/promises");
|
|
9
9
|
const fs_extra_1 = require("fs-extra");
|
|
10
10
|
const process = require("node:process");
|
|
11
|
-
const semver = require("semver");
|
|
12
11
|
const glob = require("glob");
|
|
13
12
|
const projectUtils_1 = require("../projectUtils");
|
|
14
13
|
const config_1 = require("../hosting/config");
|
|
@@ -30,6 +29,8 @@ Object.defineProperty(exports, "WebFrameworks", { enumerable: true, get: functio
|
|
|
30
29
|
const utils_2 = require("../utils");
|
|
31
30
|
const ensureTargeted_1 = require("../functions/ensureTargeted");
|
|
32
31
|
const util_1 = require("util");
|
|
32
|
+
const projectPath_1 = require("../projectPath");
|
|
33
|
+
const logger_1 = require("../logger");
|
|
33
34
|
async function discover(dir, warn = true) {
|
|
34
35
|
const allFrameworkTypes = [
|
|
35
36
|
...new Set(Object.values(constants_2.WebFrameworks).map(({ type }) => type)),
|
|
@@ -71,21 +72,17 @@ function memoizeBuild(dir, build, deps, target) {
|
|
|
71
72
|
BUILD_MEMO.set(key, value);
|
|
72
73
|
return value;
|
|
73
74
|
}
|
|
74
|
-
async function prepareFrameworks(targetNames, context, options, emulators = []) {
|
|
75
|
-
var _a, _b, _c, _d, _e;
|
|
76
|
-
var
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
throw new error_1.FirebaseError(`The frameworks awareness feature requires Node.JS >= 16 and npm >= 8 in order to work correctly, due to some of the downstream dependencies. Please upgrade your version of Node.JS, reinstall firebase-tools, and give it another go.`);
|
|
80
|
-
}
|
|
81
|
-
const project = (0, projectUtils_1.needProjectId)(context);
|
|
82
|
-
const { projectRoot } = options;
|
|
75
|
+
async function prepareFrameworks(purpose, targetNames, context, options, emulators = []) {
|
|
76
|
+
var _a, _b, _c, _d, _e, _f;
|
|
77
|
+
var _g, _h, _j, _k, _l;
|
|
78
|
+
const project = (0, projectUtils_1.needProjectId)(context || options);
|
|
79
|
+
const projectRoot = (0, projectPath_1.resolveProjectPath)(options, ".");
|
|
83
80
|
const account = (0, auth_1.getProjectDefaultAccount)(projectRoot);
|
|
84
81
|
if (!options.site) {
|
|
85
82
|
try {
|
|
86
83
|
await (0, requireHostingSite_1.requireHostingSite)(options);
|
|
87
84
|
}
|
|
88
|
-
catch (
|
|
85
|
+
catch (_m) {
|
|
89
86
|
options.site = project;
|
|
90
87
|
}
|
|
91
88
|
}
|
|
@@ -189,13 +186,17 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
189
186
|
}
|
|
190
187
|
const { framework, mayWantBackend, publicDirectory } = results;
|
|
191
188
|
const { build, ɵcodegenPublicDirectory, ɵcodegenFunctionsDirectory: codegenProdModeFunctionsDirectory, getDevModeHandle, name, support, docsUrl, getValidBuildTargets = constants_2.GET_DEFAULT_BUILD_TARGETS, shouldUseDevModeHandle = constants_2.DEFAULT_SHOULD_USE_DEV_MODE_HANDLE, } = constants_2.WebFrameworks[framework];
|
|
192
|
-
|
|
189
|
+
logger_1.logger.info(`\n${(0, utils_1.frameworksCallToAction)(constants_2.SupportLevelWarnings[support](name), docsUrl, " ")}\n`);
|
|
193
190
|
const hostingEmulatorInfo = emulators.find((e) => e.name === types_1.Emulators.HOSTING);
|
|
194
|
-
const
|
|
195
|
-
const
|
|
196
|
-
const
|
|
197
|
-
|
|
191
|
+
const validBuildTargets = await getValidBuildTargets(purpose, getProjectPath());
|
|
192
|
+
const frameworksBuildTarget = (0, utils_1.getFrameworksBuildTarget)(purpose, validBuildTargets);
|
|
193
|
+
const useDevModeHandle = purpose !== "deploy" &&
|
|
194
|
+
(await shouldUseDevModeHandle(frameworksBuildTarget, getProjectPath()));
|
|
198
195
|
let codegenFunctionsDirectory;
|
|
196
|
+
let baseUrl = "";
|
|
197
|
+
const rewrites = [];
|
|
198
|
+
const redirects = [];
|
|
199
|
+
const headers = [];
|
|
199
200
|
const devModeHandle = useDevModeHandle &&
|
|
200
201
|
getDevModeHandle &&
|
|
201
202
|
(await getDevModeHandle(getProjectPath(), frameworksBuildTarget, hostingEmulatorInfo));
|
|
@@ -208,13 +209,19 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
208
209
|
}
|
|
209
210
|
else {
|
|
210
211
|
const buildResult = await memoizeBuild(getProjectPath(), build, [firebaseDefaults, frameworksBuildTarget], frameworksBuildTarget);
|
|
211
|
-
const { wantsBackend = false,
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
212
|
+
const { wantsBackend = false, trailingSlash, i18n = false } = buildResult || {};
|
|
213
|
+
if (buildResult) {
|
|
214
|
+
baseUrl = (_d = buildResult.baseUrl) !== null && _d !== void 0 ? _d : baseUrl;
|
|
215
|
+
if (buildResult.headers)
|
|
216
|
+
headers.push(...buildResult.headers);
|
|
217
|
+
if (buildResult.rewrites)
|
|
218
|
+
rewrites.push(...buildResult.rewrites);
|
|
219
|
+
if (buildResult.redirects)
|
|
220
|
+
redirects.push(...buildResult.redirects);
|
|
221
|
+
}
|
|
222
|
+
(_e = config.trailingSlash) !== null && _e !== void 0 ? _e : (config.trailingSlash = trailingSlash);
|
|
216
223
|
if (i18n)
|
|
217
|
-
(
|
|
224
|
+
(_f = config.i18n) !== null && _f !== void 0 ? _f : (config.i18n = { root: constants_2.I18N_ROOT });
|
|
218
225
|
if (await (0, fs_extra_1.pathExists)(hostingDist))
|
|
219
226
|
await (0, promises_1.rm)(hostingDist, { recursive: true });
|
|
220
227
|
await (0, fs_extra_1.mkdirp)(hostingDist);
|
|
@@ -232,7 +239,7 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
232
239
|
firebaseDefaults._authTokenSyncURL = "/__session";
|
|
233
240
|
process.env.__FIREBASE_DEFAULTS__ = JSON.stringify(firebaseDefaults);
|
|
234
241
|
}
|
|
235
|
-
if (context.hostingChannel) {
|
|
242
|
+
if (context === null || context === void 0 ? void 0 : context.hostingChannel) {
|
|
236
243
|
experiments.assertEnabled("pintags", "deploy an app that requires a backend to a preview channel");
|
|
237
244
|
}
|
|
238
245
|
const codebase = `firebase-frameworks-${site}`;
|
|
@@ -246,10 +253,7 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
246
253
|
codebase,
|
|
247
254
|
},
|
|
248
255
|
]);
|
|
249
|
-
if (!experiments.isEnabled("pintags") ||
|
|
250
|
-
context._name === "serve" ||
|
|
251
|
-
context._name === "emulators:start" ||
|
|
252
|
-
context._name === "emulators:exec") {
|
|
256
|
+
if (!experiments.isEnabled("pintags") || purpose !== "deploy") {
|
|
253
257
|
if (!targetNames.includes("functions")) {
|
|
254
258
|
targetNames.unshift("functions");
|
|
255
259
|
}
|
|
@@ -273,38 +277,41 @@ async function prepareFrameworks(targetNames, context, options, emulators = [])
|
|
|
273
277
|
else {
|
|
274
278
|
await (0, fs_extra_1.mkdirp)(functionsDist);
|
|
275
279
|
}
|
|
276
|
-
const { packageJson, bootstrapScript, frameworksEntry = framework,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
pinTag: experiments.isEnabled("pintags"),
|
|
284
|
-
},
|
|
280
|
+
const { packageJson, bootstrapScript, frameworksEntry = framework, dotEnv = {}, rewriteSource, } = await codegenFunctionsDirectory(getProjectPath(), functionsDist, frameworksBuildTarget);
|
|
281
|
+
const rewrite = {
|
|
282
|
+
source: rewriteSource || path_1.posix.join(baseUrl, "**"),
|
|
283
|
+
function: {
|
|
284
|
+
functionId,
|
|
285
|
+
region: ssrRegion,
|
|
286
|
+
pinTag: experiments.isEnabled("pintags"),
|
|
285
287
|
},
|
|
286
|
-
|
|
287
|
-
|
|
288
|
+
};
|
|
289
|
+
if (rewriteSource) {
|
|
290
|
+
config.rewrites.unshift(rewrite);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
rewrites.push(rewrite);
|
|
294
|
+
}
|
|
288
295
|
process.env.__FIREBASE_FRAMEWORKS_ENTRY__ = frameworksEntry;
|
|
289
296
|
packageJson.main = "server.js";
|
|
290
297
|
packageJson.dependencies || (packageJson.dependencies = {});
|
|
291
|
-
(
|
|
292
|
-
(
|
|
293
|
-
(
|
|
298
|
+
(_g = packageJson.dependencies)["firebase-frameworks"] || (_g["firebase-frameworks"] = constants_2.FIREBASE_FRAMEWORKS_VERSION);
|
|
299
|
+
(_h = packageJson.dependencies)["firebase-functions"] || (_h["firebase-functions"] = constants_2.FIREBASE_FUNCTIONS_VERSION);
|
|
300
|
+
(_j = packageJson.dependencies)["firebase-admin"] || (_j["firebase-admin"] = constants_2.FIREBASE_ADMIN_VERSION);
|
|
294
301
|
packageJson.engines || (packageJson.engines = {});
|
|
295
302
|
const validEngines = constants_2.VALID_ENGINES.node.filter((it) => it <= constants_2.NODE_VERSION);
|
|
296
303
|
const engine = validEngines[validEngines.length - 1] || constants_2.VALID_ENGINES.node[0];
|
|
297
304
|
if (engine !== constants_2.NODE_VERSION) {
|
|
298
305
|
(0, utils_2.logWarning)(`This integration expects Node version ${(0, utils_1.conjoinOptions)(constants_2.VALID_ENGINES.node, "or")}. You're running version ${constants_2.NODE_VERSION}, problems may be encountered.`);
|
|
299
306
|
}
|
|
300
|
-
(
|
|
307
|
+
(_k = packageJson.engines).node || (_k.node = engine.toString());
|
|
301
308
|
delete packageJson.scripts;
|
|
302
309
|
delete packageJson.devDependencies;
|
|
303
310
|
const bundledDependencies = packageJson.bundledDependencies || {};
|
|
304
311
|
if (Object.keys(bundledDependencies).length) {
|
|
305
312
|
(0, utils_2.logWarning)("Bundled dependencies aren't supported in Cloud Functions, converting to dependencies.");
|
|
306
313
|
for (const [dep, version] of Object.entries(bundledDependencies)) {
|
|
307
|
-
(
|
|
314
|
+
(_l = packageJson.dependencies)[dep] || (_l[dep] = version);
|
|
308
315
|
}
|
|
309
316
|
delete packageJson.bundledDependencies;
|
|
310
317
|
}
|
|
@@ -376,13 +383,18 @@ ${firebaseDefaults ? `__FIREBASE_DEFAULTS__=${JSON.stringify(firebaseDefaults)}\
|
|
|
376
383
|
await (0, promises_1.rm)(functionsDist, { recursive: true });
|
|
377
384
|
}
|
|
378
385
|
}
|
|
386
|
+
const ourConfigShouldComeFirst = !["", "/"].includes(baseUrl);
|
|
387
|
+
const operation = ourConfigShouldComeFirst ? "unshift" : "push";
|
|
388
|
+
config.rewrites[operation](...rewrites);
|
|
389
|
+
config.redirects[operation](...redirects);
|
|
390
|
+
config.headers[operation](...headers);
|
|
379
391
|
if (firebaseDefaults) {
|
|
380
392
|
const encodedDefaults = Buffer.from(JSON.stringify(firebaseDefaults)).toString("base64url");
|
|
381
393
|
const expires = new Date(new Date().getTime() + 60000000000);
|
|
382
394
|
const sameSite = "Strict";
|
|
383
395
|
const path = `/`;
|
|
384
396
|
config.headers.push({
|
|
385
|
-
source: "
|
|
397
|
+
source: path_1.posix.join(baseUrl, "**", "*.[jt]s"),
|
|
386
398
|
headers: [
|
|
387
399
|
{
|
|
388
400
|
key: "Set-Cookie",
|
|
@@ -392,10 +404,7 @@ ${firebaseDefaults ? `__FIREBASE_DEFAULTS__=${JSON.stringify(firebaseDefaults)}\
|
|
|
392
404
|
});
|
|
393
405
|
}
|
|
394
406
|
}
|
|
395
|
-
|
|
396
|
-
console.log("Effective firebase.json:");
|
|
397
|
-
console.log(JSON.stringify(configs, undefined, 2));
|
|
398
|
-
}
|
|
407
|
+
logger_1.logger.debug("[web frameworks] effective firebase.json: ", JSON.stringify({ hosting: configs, functions: options.config.get("functions") }, undefined, 2));
|
|
399
408
|
BUILD_MEMO.clear();
|
|
400
409
|
delete process.env.__FIREBASE_DEFAULTS__;
|
|
401
410
|
delete process.env.__FIREBASE_FRAMEWORKS_ENTRY__;
|
|
@@ -22,6 +22,7 @@ const utils_2 = require("./utils");
|
|
|
22
22
|
const constants_1 = require("../constants");
|
|
23
23
|
const constants_2 = require("./constants");
|
|
24
24
|
const api_1 = require("../../hosting/api");
|
|
25
|
+
const logger_1 = require("../../logger");
|
|
25
26
|
const DEFAULT_BUILD_SCRIPT = ["next build"];
|
|
26
27
|
const PUBLIC_DIR = "public";
|
|
27
28
|
exports.name = "Next.js";
|
|
@@ -58,7 +59,7 @@ async function build(dir) {
|
|
|
58
59
|
throw e;
|
|
59
60
|
});
|
|
60
61
|
const reasonsForBackend = new Set();
|
|
61
|
-
const { distDir, trailingSlash, basePath } = await getConfig(dir);
|
|
62
|
+
const { distDir, trailingSlash, basePath: baseUrl } = await getConfig(dir);
|
|
62
63
|
if (await (0, utils_2.isUsingMiddleware)((0, path_1.join)(dir, distDir), false)) {
|
|
63
64
|
reasonsForBackend.add("middleware");
|
|
64
65
|
}
|
|
@@ -103,7 +104,7 @@ async function build(dir) {
|
|
|
103
104
|
(0, utils_1.readJSON)((0, path_1.join)(dir, distDir, constants_2.APP_PATH_ROUTES_MANIFEST)).catch(() => undefined),
|
|
104
105
|
]);
|
|
105
106
|
if (appPathRoutesManifest) {
|
|
106
|
-
const headersFromMetaFiles = await (0, utils_2.getHeadersFromMetaFiles)(dir, distDir,
|
|
107
|
+
const headersFromMetaFiles = await (0, utils_2.getHeadersFromMetaFiles)(dir, distDir, baseUrl, appPathRoutesManifest);
|
|
107
108
|
headers.push(...headersFromMetaFiles);
|
|
108
109
|
if (appPathsManifest) {
|
|
109
110
|
const unrenderedServerComponents = (0, utils_2.getNonStaticServerComponents)(appPathsManifest, appPathRoutesManifest, prerenderedRoutes, dynamicRoutes);
|
|
@@ -144,15 +145,17 @@ async function build(dir) {
|
|
|
144
145
|
}));
|
|
145
146
|
const wantsBackend = reasonsForBackend.size > 0;
|
|
146
147
|
if (wantsBackend) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
console.log(` • ${reason}`);
|
|
148
|
+
logger_1.logger.info("Building a Cloud Function to run this application. This is needed due to:");
|
|
149
|
+
for (const reason of Array.from(reasonsForBackend).slice(0, DEFAULT_NUMBER_OF_REASONS_TO_LIST)) {
|
|
150
|
+
logger_1.logger.info(` • ${reason}`);
|
|
151
151
|
}
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
for (const reason of Array.from(reasonsForBackend).slice(DEFAULT_NUMBER_OF_REASONS_TO_LIST)) {
|
|
153
|
+
logger_1.logger.debug(` • ${reason}`);
|
|
154
154
|
}
|
|
155
|
-
|
|
155
|
+
if (reasonsForBackend.size > DEFAULT_NUMBER_OF_REASONS_TO_LIST && !process.env.DEBUG) {
|
|
156
|
+
logger_1.logger.info(` • and ${reasonsForBackend.size - DEFAULT_NUMBER_OF_REASONS_TO_LIST} other reasons, use --debug to see more`);
|
|
157
|
+
}
|
|
158
|
+
logger_1.logger.info("");
|
|
156
159
|
}
|
|
157
160
|
const i18n = !!nextjsI18n;
|
|
158
161
|
return {
|
|
@@ -162,6 +165,7 @@ async function build(dir) {
|
|
|
162
165
|
rewrites,
|
|
163
166
|
trailingSlash,
|
|
164
167
|
i18n,
|
|
168
|
+
baseUrl,
|
|
165
169
|
};
|
|
166
170
|
}
|
|
167
171
|
exports.build = build;
|
|
@@ -226,13 +230,11 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir, _, context) {
|
|
|
226
230
|
await Promise.all(Object.entries(routesToCopy).map(async ([path, route]) => {
|
|
227
231
|
var _a, _b;
|
|
228
232
|
if (route.initialRevalidateSeconds) {
|
|
229
|
-
|
|
230
|
-
console.log(`skipping ${path} due to revalidate`);
|
|
233
|
+
logger_1.logger.debug(`skipping ${path} due to revalidate`);
|
|
231
234
|
return;
|
|
232
235
|
}
|
|
233
236
|
if (pathsUsingsFeaturesNotSupportedByHosting.some((it) => path.match(it))) {
|
|
234
|
-
|
|
235
|
-
console.log(`skipping ${path} due to it matching an unsupported rewrite/redirect/header or middlware`);
|
|
237
|
+
logger_1.logger.debug(`skipping ${path} due to it matching an unsupported rewrite/redirect/header or middlware`);
|
|
236
238
|
return;
|
|
237
239
|
}
|
|
238
240
|
const appPathRoute = route.srcRoute && ((_a = appPathRoutesEntries.find(([, it]) => it === route.srcRoute)) === null || _a === void 0 ? void 0 : _a[0]);
|
|
@@ -245,8 +247,7 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir, _, context) {
|
|
|
245
247
|
!matchingI18nDomain.locales ||
|
|
246
248
|
matchingI18nDomain.locales.includes(locale);
|
|
247
249
|
if (!includeOnThisDomain) {
|
|
248
|
-
|
|
249
|
-
console.log(`skipping ${path} since it is for a locale not deployed on this domain`);
|
|
250
|
+
logger_1.logger.debug(`skipping ${path} since it is for a locale not deployed on this domain`);
|
|
250
251
|
return;
|
|
251
252
|
}
|
|
252
253
|
const sourcePartsOrIndex = sourceParts.length > 0 ? sourceParts : ["index"];
|
|
@@ -293,7 +294,7 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir, _, context) {
|
|
|
293
294
|
exports.ɵcodegenPublicDirectory = ɵcodegenPublicDirectory;
|
|
294
295
|
const BUNDLE_NEXT_CONFIG_TIMEOUT = 10000;
|
|
295
296
|
async function ɵcodegenFunctionsDirectory(sourceDir, destDir) {
|
|
296
|
-
const { distDir
|
|
297
|
+
const { distDir } = await getConfig(sourceDir);
|
|
297
298
|
const packageJson = await (0, utils_1.readJSON)((0, path_1.join)(sourceDir, "package.json"));
|
|
298
299
|
if ((0, fs_1.existsSync)((0, path_1.join)(sourceDir, "next.config.js"))) {
|
|
299
300
|
try {
|
|
@@ -345,7 +346,7 @@ async function ɵcodegenFunctionsDirectory(sourceDir, destDir) {
|
|
|
345
346
|
}
|
|
346
347
|
await (0, fs_extra_1.mkdirp)((0, path_1.join)(destDir, distDir));
|
|
347
348
|
await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, distDir), (0, path_1.join)(destDir, distDir));
|
|
348
|
-
return { packageJson, frameworksEntry: "next.js"
|
|
349
|
+
return { packageJson, frameworksEntry: "next.js" };
|
|
349
350
|
}
|
|
350
351
|
exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
|
|
351
352
|
async function getDevModeHandle(dir, _, hostingEmulatorInfo) {
|