firebase-tools 12.2.0 → 12.3.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/commands/hosting-channel-deploy.js +5 -3
- 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/emulator/storage/index.js +0 -5
- package/lib/emulator/storage/rules/manager.js +4 -0
- package/lib/emulator/storage/rules/runtime.js +21 -7
- package/lib/emulator/storage/server.js +0 -52
- package/lib/frameworks/angular/index.js +10 -9
- package/lib/frameworks/astro/index.js +8 -6
- 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 -19
- package/lib/frameworks/vite/index.js +2 -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
- package/templates/init/storage/storage.rules +4 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.command = void 0;
|
|
3
|
+
exports.hostingChannelDeployAction = exports.command = void 0;
|
|
4
4
|
const colorette_1 = require("colorette");
|
|
5
5
|
const command_1 = require("../command");
|
|
6
6
|
const error_1 = require("../error");
|
|
@@ -25,7 +25,8 @@ exports.command = new command_1.Command("hosting:channel:deploy [channelId]")
|
|
|
25
25
|
.before(requireConfig_1.requireConfig)
|
|
26
26
|
.before(requirePermissions_1.requirePermissions, ["firebasehosting.sites.update"])
|
|
27
27
|
.before(requireHostingSite_1.requireHostingSite)
|
|
28
|
-
.action(
|
|
28
|
+
.action(hostingChannelDeployAction);
|
|
29
|
+
async function hostingChannelDeployAction(channelId, options) {
|
|
29
30
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
30
31
|
if (options.open) {
|
|
31
32
|
throw new error_1.FirebaseError("open is not yet implemented");
|
|
@@ -122,7 +123,8 @@ exports.command = new command_1.Command("hosting:channel:deploy [channelId]")
|
|
|
122
123
|
(0, utils_1.logLabeledSuccess)(LOG_TAG, `Channel URL (${(0, colorette_1.bold)(d.site || d.target || "")}): ${d.url} ${expires}${version}`);
|
|
123
124
|
});
|
|
124
125
|
return deploys;
|
|
125
|
-
}
|
|
126
|
+
}
|
|
127
|
+
exports.hostingChannelDeployAction = hostingChannelDeployAction;
|
|
126
128
|
async function syncAuthState(projectId, sites) {
|
|
127
129
|
const siteNames = sites.map((d) => d.site);
|
|
128
130
|
const urlNames = sites.map((d) => d.url);
|
package/lib/deploy/index.js
CHANGED
|
@@ -52,7 +52,7 @@ const deploy = async function (targetNames, options, customContext = {}) {
|
|
|
52
52
|
const config = options.config.get("hosting");
|
|
53
53
|
if (Array.isArray(config) ? config.some((it) => it.source) : config.source) {
|
|
54
54
|
experiments.assertEnabled("webframeworks", "deploy a web framework from source");
|
|
55
|
-
await (0, frameworks_1.prepareFrameworks)(targetNames, context, options);
|
|
55
|
+
await (0, frameworks_1.prepareFrameworks)("deploy", targetNames, context, options);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
if (targetNames.includes("hosting") && (0, prepare_1.hasPinnedFunctions)(options)) {
|
|
@@ -146,13 +146,13 @@ async function signUp(state, reqBody, ctx) {
|
|
|
146
146
|
(0, errors_1.assert)(state.enableAnonymousUser, "ADMIN_ONLY_OPERATION");
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
|
-
if (reqBody.email) {
|
|
149
|
+
if (typeof reqBody.email === "string") {
|
|
150
150
|
(0, errors_1.assert)((0, utils_1.isValidEmailAddress)(reqBody.email), "INVALID_EMAIL");
|
|
151
151
|
const email = (0, utils_1.canonicalizeEmailAddress)(reqBody.email);
|
|
152
152
|
(0, errors_1.assert)(!state.getUserByEmail(email), "EMAIL_EXISTS");
|
|
153
153
|
updates.email = email;
|
|
154
154
|
}
|
|
155
|
-
if (reqBody.password) {
|
|
155
|
+
if (typeof reqBody.password === "string") {
|
|
156
156
|
(0, errors_1.assert)(reqBody.password.length >= PASSWORD_MIN_LENGTH, `WEAK_PASSWORD : Password should be at least ${PASSWORD_MIN_LENGTH} characters`);
|
|
157
157
|
updates.salt = "fakeSalt" + (0, utils_1.randomId)(20);
|
|
158
158
|
updates.passwordHash = hashPassword(reqBody.password, updates.salt);
|
|
@@ -288,7 +288,7 @@ async function emulatorExec(script, options) {
|
|
|
288
288
|
let deprecationNotices;
|
|
289
289
|
try {
|
|
290
290
|
const showUI = !!options.ui;
|
|
291
|
-
({ deprecationNotices } = await controller.startAll(options, showUI));
|
|
291
|
+
({ deprecationNotices } = await controller.startAll(options, showUI, true));
|
|
292
292
|
exitCode = await runScript(script, extraEnv);
|
|
293
293
|
await controller.onExit(options);
|
|
294
294
|
}
|
|
@@ -116,6 +116,10 @@ function shouldStart(options, name) {
|
|
|
116
116
|
}
|
|
117
117
|
exports.shouldStart = shouldStart;
|
|
118
118
|
function findExportMetadata(importPath) {
|
|
119
|
+
const pathExists = fs.existsSync(importPath);
|
|
120
|
+
if (!pathExists) {
|
|
121
|
+
throw new error_1.FirebaseError(`Directory "${importPath}" does not exist.`);
|
|
122
|
+
}
|
|
119
123
|
const pathIsDirectory = fs.lstatSync(importPath).isDirectory();
|
|
120
124
|
if (!pathIsDirectory) {
|
|
121
125
|
return;
|
|
@@ -151,7 +155,7 @@ function findExportMetadata(importPath) {
|
|
|
151
155
|
return metadata;
|
|
152
156
|
}
|
|
153
157
|
}
|
|
154
|
-
async function startAll(options, showUI = true) {
|
|
158
|
+
async function startAll(options, showUI = true, runningTestScript = false) {
|
|
155
159
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
156
160
|
const targets = filterEmulatorTargets(options);
|
|
157
161
|
options.targets = targets;
|
|
@@ -291,7 +295,7 @@ async function startAll(options, showUI = true) {
|
|
|
291
295
|
});
|
|
292
296
|
}
|
|
293
297
|
}
|
|
294
|
-
await (0, frameworks_1.prepareFrameworks)(targets,
|
|
298
|
+
await (0, frameworks_1.prepareFrameworks)(runningTestScript ? "test" : "emulate", targets, undefined, options, emulators);
|
|
295
299
|
}
|
|
296
300
|
const projectDir = (options.extDevDir || options.config.projectDir);
|
|
297
301
|
if (shouldStart(options, types_1.Emulators.FUNCTIONS)) {
|
|
@@ -272,6 +272,9 @@ function getSignatureType(def) {
|
|
|
272
272
|
if (def.httpsTrigger || def.blockingTrigger) {
|
|
273
273
|
return "http";
|
|
274
274
|
}
|
|
275
|
+
if (def.platform === "gcfv2" && def.schedule) {
|
|
276
|
+
return "http";
|
|
277
|
+
}
|
|
275
278
|
return def.platform === "gcfv2" ? "cloudevent" : "event";
|
|
276
279
|
}
|
|
277
280
|
exports.getSignatureType = getSignatureType;
|
|
@@ -82,11 +82,6 @@ class StorageEmulator {
|
|
|
82
82
|
getApp() {
|
|
83
83
|
return this._app;
|
|
84
84
|
}
|
|
85
|
-
async replaceRules(rules) {
|
|
86
|
-
await this._rulesManager.stop();
|
|
87
|
-
this._rulesManager = this.createRulesManager(rules);
|
|
88
|
-
return this._rulesManager.start();
|
|
89
|
-
}
|
|
90
85
|
createRulesManager(rules) {
|
|
91
86
|
return (0, manager_1.createStorageRulesManager)(rules, this._rulesRuntime);
|
|
92
87
|
}
|
|
@@ -20,6 +20,7 @@ class DefaultStorageRulesManager {
|
|
|
20
20
|
this._rules = _rules;
|
|
21
21
|
}
|
|
22
22
|
async start() {
|
|
23
|
+
this._runtime.start();
|
|
23
24
|
const issues = await this.loadRuleset();
|
|
24
25
|
this.updateWatcher(this._rules.name);
|
|
25
26
|
return issues;
|
|
@@ -29,6 +30,9 @@ class DefaultStorageRulesManager {
|
|
|
29
30
|
}
|
|
30
31
|
async stop() {
|
|
31
32
|
await this._watcher.close();
|
|
33
|
+
if (this._runtime.alive) {
|
|
34
|
+
await this._runtime.stop();
|
|
35
|
+
}
|
|
32
36
|
}
|
|
33
37
|
updateWatcher(rulesFile) {
|
|
34
38
|
this._watcher = chokidar
|
|
@@ -71,6 +71,9 @@ class StorageRulesRuntime {
|
|
|
71
71
|
}
|
|
72
72
|
async start(autoDownload = true) {
|
|
73
73
|
var _a, _b;
|
|
74
|
+
if (this.alive) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
74
77
|
const downloadDetails = downloadableEmulators_1.DownloadDetails[types_2.Emulators.STORAGE];
|
|
75
78
|
const hasEmulator = fs.existsSync(downloadDetails.downloadPath);
|
|
76
79
|
if (!hasEmulator) {
|
|
@@ -90,11 +93,11 @@ class StorageRulesRuntime {
|
|
|
90
93
|
this._childprocess = (0, cross_spawn_1.spawn)(command.binary, command.args, {
|
|
91
94
|
stdio: ["pipe", "pipe", "pipe"],
|
|
92
95
|
});
|
|
93
|
-
this._childprocess.on("exit", (
|
|
96
|
+
this._childprocess.on("exit", () => {
|
|
97
|
+
var _a;
|
|
94
98
|
this._alive = false;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
99
|
+
(_a = this._childprocess) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
|
|
100
|
+
this._childprocess = undefined;
|
|
98
101
|
});
|
|
99
102
|
const startPromise = new Promise((resolve) => {
|
|
100
103
|
this._requests[-1] = {
|
|
@@ -152,12 +155,23 @@ class StorageRulesRuntime {
|
|
|
152
155
|
return startPromise;
|
|
153
156
|
}
|
|
154
157
|
stop() {
|
|
155
|
-
|
|
156
|
-
|
|
158
|
+
emulatorLogger_1.EmulatorLogger.forEmulator(types_2.Emulators.STORAGE).log("DEBUG", "Stopping rules runtime.");
|
|
159
|
+
return new Promise((resolve) => {
|
|
160
|
+
var _a;
|
|
161
|
+
if (this.alive) {
|
|
162
|
+
this._childprocess.on("exit", () => {
|
|
163
|
+
resolve();
|
|
164
|
+
});
|
|
165
|
+
(_a = this._childprocess) === null || _a === void 0 ? void 0 : _a.kill("SIGINT");
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
resolve();
|
|
169
|
+
}
|
|
170
|
+
});
|
|
157
171
|
}
|
|
158
172
|
async _sendRequest(rab, overrideId) {
|
|
159
173
|
if (!this._childprocess) {
|
|
160
|
-
throw new error_1.FirebaseError("
|
|
174
|
+
throw new error_1.FirebaseError("Failed to send Cloud Storage rules request due to rules runtime not available.");
|
|
161
175
|
}
|
|
162
176
|
const runtimeActionRequest = Object.assign(Object.assign({}, rab), { id: overrideId !== null && overrideId !== void 0 ? overrideId : this._requestCount++ });
|
|
163
177
|
if (overrideId !== undefined) {
|
|
@@ -8,7 +8,6 @@ const types_1 = require("../types");
|
|
|
8
8
|
const bodyParser = require("body-parser");
|
|
9
9
|
const gcloud_1 = require("./apis/gcloud");
|
|
10
10
|
const firebase_1 = require("./apis/firebase");
|
|
11
|
-
const errors_1 = require("../auth/errors");
|
|
12
11
|
function createApp(defaultProjectId, emulator) {
|
|
13
12
|
const { storageLayer } = emulator;
|
|
14
13
|
const app = express();
|
|
@@ -51,54 +50,6 @@ function createApp(defaultProjectId, emulator) {
|
|
|
51
50
|
await storageLayer.export(path, { initiatedBy });
|
|
52
51
|
res.sendStatus(200);
|
|
53
52
|
});
|
|
54
|
-
app.put("/internal/setRules", async (req, res) => {
|
|
55
|
-
const rulesRaw = req.body.rules;
|
|
56
|
-
if (!(rulesRaw && Array.isArray(rulesRaw.files) && rulesRaw.files.length > 0)) {
|
|
57
|
-
res.status(400).json({
|
|
58
|
-
message: "Request body must include 'rules.files' array",
|
|
59
|
-
});
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const { files } = rulesRaw;
|
|
63
|
-
function parseRulesFromFiles(files) {
|
|
64
|
-
if (files.length === 1) {
|
|
65
|
-
const file = files[0];
|
|
66
|
-
if (!isRulesFile(file)) {
|
|
67
|
-
throw new errors_1.InvalidArgumentError("Each member of 'rules.files' array must contain 'name' and 'content'");
|
|
68
|
-
}
|
|
69
|
-
return { name: file.name, content: file.content };
|
|
70
|
-
}
|
|
71
|
-
const rules = [];
|
|
72
|
-
for (const file of files) {
|
|
73
|
-
if (!isRulesFile(file) || !file.resource) {
|
|
74
|
-
throw new errors_1.InvalidArgumentError("Each member of 'rules.files' array must contain 'name', 'content', and 'resource'");
|
|
75
|
-
}
|
|
76
|
-
rules.push({ resource: file.resource, rules: { name: file.name, content: file.content } });
|
|
77
|
-
}
|
|
78
|
-
return rules;
|
|
79
|
-
}
|
|
80
|
-
let rules;
|
|
81
|
-
try {
|
|
82
|
-
rules = parseRulesFromFiles(files);
|
|
83
|
-
}
|
|
84
|
-
catch (err) {
|
|
85
|
-
if (err instanceof errors_1.InvalidArgumentError) {
|
|
86
|
-
res.status(400).json({ message: err.message });
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
throw err;
|
|
90
|
-
}
|
|
91
|
-
const issues = await emulator.replaceRules(rules);
|
|
92
|
-
if (issues.errors.length > 0) {
|
|
93
|
-
res.status(400).json({
|
|
94
|
-
message: "There was an error updating rules, see logs for more details",
|
|
95
|
-
});
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
res.status(200).json({
|
|
99
|
-
message: "Rules updated successfully",
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
53
|
app.post("/internal/reset", (req, res) => {
|
|
103
54
|
emulator.reset();
|
|
104
55
|
res.sendStatus(200);
|
|
@@ -108,6 +59,3 @@ function createApp(defaultProjectId, emulator) {
|
|
|
108
59
|
return Promise.resolve(app);
|
|
109
60
|
}
|
|
110
61
|
exports.createApp = createApp;
|
|
111
|
-
function isRulesFile(file) {
|
|
112
|
-
return (typeof file.name === "string" && typeof file.content === "string");
|
|
113
|
-
}
|
|
@@ -44,7 +44,7 @@ async function init(setup, config) {
|
|
|
44
44
|
}
|
|
45
45
|
exports.init = init;
|
|
46
46
|
async function build(dir, configuration) {
|
|
47
|
-
const { targets, serverTarget, serveOptimizedImages, locales, baseHref } = await (0, utils_2.getBuildConfig)(dir, configuration);
|
|
47
|
+
const { targets, serverTarget, serveOptimizedImages, locales, baseHref: baseUrl, } = await (0, utils_2.getBuildConfig)(dir, configuration);
|
|
48
48
|
await (0, utils_1.warnIfCustomBuildScript)(dir, exports.name, DEFAULT_BUILD_SCRIPT);
|
|
49
49
|
for (const target of targets) {
|
|
50
50
|
const cli = (0, utils_1.getNodeModuleBin)("ng", dir);
|
|
@@ -60,12 +60,12 @@ async function build(dir, configuration) {
|
|
|
60
60
|
? []
|
|
61
61
|
: [
|
|
62
62
|
{
|
|
63
|
-
source: path_1.posix.join(
|
|
64
|
-
destination: path_1.posix.join(
|
|
63
|
+
source: path_1.posix.join(baseUrl, "**"),
|
|
64
|
+
destination: path_1.posix.join(baseUrl, "index.html"),
|
|
65
65
|
},
|
|
66
66
|
];
|
|
67
67
|
const i18n = !!locales;
|
|
68
|
-
return { wantsBackend, i18n, rewrites };
|
|
68
|
+
return { wantsBackend, i18n, rewrites, baseUrl };
|
|
69
69
|
}
|
|
70
70
|
exports.build = build;
|
|
71
71
|
async function getDevModeHandle(dir, configuration) {
|
|
@@ -73,7 +73,7 @@ async function getDevModeHandle(dir, configuration) {
|
|
|
73
73
|
const { serveTarget } = await (0, utils_2.getContext)(dir, configuration);
|
|
74
74
|
if (!serveTarget)
|
|
75
75
|
throw new Error("Could not find the serveTarget");
|
|
76
|
-
const host = new Promise((resolve) => {
|
|
76
|
+
const host = new Promise((resolve, reject) => {
|
|
77
77
|
const cli = (0, utils_1.getNodeModuleBin)("ng", dir);
|
|
78
78
|
const serve = (0, cross_spawn_1.spawn)(cli, ["run", targetStringFromTarget(serveTarget), "--host", "localhost"], {
|
|
79
79
|
cwd: dir,
|
|
@@ -87,6 +87,7 @@ async function getDevModeHandle(dir, configuration) {
|
|
|
87
87
|
serve.stderr.on("data", (data) => {
|
|
88
88
|
process.stderr.write(data);
|
|
89
89
|
});
|
|
90
|
+
serve.on("exit", reject);
|
|
90
91
|
});
|
|
91
92
|
return (0, utils_1.simpleProxy)(await host);
|
|
92
93
|
}
|
|
@@ -114,7 +115,7 @@ async function getValidBuildTargets(purpose, dir) {
|
|
|
114
115
|
const validTargetNames = new Set(["development", "production"]);
|
|
115
116
|
try {
|
|
116
117
|
const { workspaceProject, browserTarget, serverTarget, serveTarget } = await (0, utils_2.getContext)(dir);
|
|
117
|
-
const { target } = ((purpose === "
|
|
118
|
+
const { target } = ((purpose === "emulate" && serveTarget) || serverTarget || browserTarget);
|
|
118
119
|
const workspaceTarget = workspaceProject.targets.get(target);
|
|
119
120
|
Object.keys(workspaceTarget.configurations || {}).forEach((it) => validTargetNames.add(it));
|
|
120
121
|
}
|
|
@@ -134,7 +135,7 @@ exports.shouldUseDevModeHandle = shouldUseDevModeHandle;
|
|
|
134
135
|
async function ɵcodegenFunctionsDirectory(sourceDir, destDir, configuration) {
|
|
135
136
|
var _a;
|
|
136
137
|
var _b;
|
|
137
|
-
const { packageJson, serverOutputPath, browserOutputPath, defaultLocale, serverLocales, browserLocales, bundleDependencies, externalDependencies, baseHref
|
|
138
|
+
const { packageJson, serverOutputPath, browserOutputPath, defaultLocale, serverLocales, browserLocales, bundleDependencies, externalDependencies, baseHref, serveOptimizedImages, } = await (0, utils_2.getServerConfig)(sourceDir, configuration);
|
|
138
139
|
const dotEnv = { __NG_BROWSER_OUTPUT_PATH__: browserOutputPath };
|
|
139
140
|
let rewriteSource = undefined;
|
|
140
141
|
await Promise.all([
|
|
@@ -187,8 +188,8 @@ exports.handle = function(req,res) {
|
|
|
187
188
|
}
|
|
188
189
|
else {
|
|
189
190
|
bootstrapScript = `exports.handle = (res, req) => req.sendStatus(404);\n`;
|
|
190
|
-
rewriteSource = path_1.posix.join(
|
|
191
|
+
rewriteSource = path_1.posix.join(baseHref, "__image__");
|
|
191
192
|
}
|
|
192
|
-
return { bootstrapScript, packageJson,
|
|
193
|
+
return { bootstrapScript, packageJson, dotEnv, rewriteSource };
|
|
193
194
|
}
|
|
194
195
|
exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
|
|
@@ -21,7 +21,7 @@ async function discover(dir) {
|
|
|
21
21
|
return;
|
|
22
22
|
const { output, publicDir: publicDirectory } = await (0, utils_2.getConfig)(dir);
|
|
23
23
|
return {
|
|
24
|
-
mayWantBackend: output
|
|
24
|
+
mayWantBackend: output !== "static",
|
|
25
25
|
publicDirectory,
|
|
26
26
|
};
|
|
27
27
|
}
|
|
@@ -31,18 +31,19 @@ async function build(cwd) {
|
|
|
31
31
|
const cli = (0, utils_1.getNodeModuleBin)("astro", cwd);
|
|
32
32
|
await (0, utils_1.warnIfCustomBuildScript)(cwd, exports.name, DEFAULT_BUILD_SCRIPT);
|
|
33
33
|
const { output, adapter } = await (0, utils_2.getConfig)(cwd);
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
const wantsBackend = output !== "static";
|
|
35
|
+
if (wantsBackend && (adapter === null || adapter === void 0 ? void 0 : adapter.name) !== "@astrojs/node") {
|
|
36
|
+
throw new error_1.FirebaseError("Deploying an Astro application with SSR on Firebase Hosting requires the @astrojs/node adapter in middleware mode. https://docs.astro.build/en/guides/integrations-guide/node/");
|
|
36
37
|
}
|
|
37
38
|
const build = (0, cross_spawn_1.sync)(cli, ["build"], { cwd, stdio: "inherit" });
|
|
38
39
|
if (build.status !== 0)
|
|
39
40
|
throw new error_1.FirebaseError("Unable to build your Astro app");
|
|
40
|
-
return { wantsBackend
|
|
41
|
+
return { wantsBackend };
|
|
41
42
|
}
|
|
42
43
|
exports.build = build;
|
|
43
44
|
async function ɵcodegenPublicDirectory(root, dest) {
|
|
44
45
|
const { outDir, output } = await (0, utils_2.getConfig)(root);
|
|
45
|
-
const assetPath = (0, path_1.join)(root, outDir, output
|
|
46
|
+
const assetPath = (0, path_1.join)(root, outDir, output !== "static" ? "client" : "");
|
|
46
47
|
await (0, fs_extra_1.copy)(assetPath, dest);
|
|
47
48
|
}
|
|
48
49
|
exports.ɵcodegenPublicDirectory = ɵcodegenPublicDirectory;
|
|
@@ -57,7 +58,7 @@ async function ɵcodegenFunctionsDirectory(sourceDir, destDir) {
|
|
|
57
58
|
}
|
|
58
59
|
exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
|
|
59
60
|
async function getDevModeHandle(cwd) {
|
|
60
|
-
const host = new Promise((resolve) => {
|
|
61
|
+
const host = new Promise((resolve, reject) => {
|
|
61
62
|
const cli = (0, utils_1.getNodeModuleBin)("astro", cwd);
|
|
62
63
|
const serve = (0, cross_spawn_1.spawn)(cli, ["dev"], { cwd });
|
|
63
64
|
serve.stdout.on("data", (data) => {
|
|
@@ -69,6 +70,7 @@ async function getDevModeHandle(cwd) {
|
|
|
69
70
|
serve.stderr.on("data", (data) => {
|
|
70
71
|
process.stderr.write(data);
|
|
71
72
|
});
|
|
73
|
+
serve.on("exit", reject);
|
|
72
74
|
});
|
|
73
75
|
return (0, utils_1.simpleProxy)(await host);
|
|
74
76
|
}
|
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) {
|
|
@@ -30,7 +30,7 @@ exports.discover = discover;
|
|
|
30
30
|
async function build(cwd) {
|
|
31
31
|
await (0, utils_1.warnIfCustomBuildScript)(cwd, exports.name, DEFAULT_BUILD_SCRIPT);
|
|
32
32
|
const cli = (0, utils_1.getNodeModuleBin)("nuxt", cwd);
|
|
33
|
-
const { ssr: wantsBackend, app: { baseURL }, } = await getConfig(cwd);
|
|
33
|
+
const { ssr: wantsBackend, app: { baseURL: baseUrl }, } = await getConfig(cwd);
|
|
34
34
|
const command = wantsBackend ? ["build"] : ["generate"];
|
|
35
35
|
const build = (0, cross_spawn_1.sync)(cli, command, {
|
|
36
36
|
cwd,
|
|
@@ -43,11 +43,11 @@ async function build(cwd) {
|
|
|
43
43
|
? []
|
|
44
44
|
: [
|
|
45
45
|
{
|
|
46
|
-
source: path_1.posix.join(
|
|
47
|
-
destination: path_1.posix.join(
|
|
46
|
+
source: path_1.posix.join(baseUrl, "**"),
|
|
47
|
+
destination: path_1.posix.join(baseUrl, "200.html"),
|
|
48
48
|
},
|
|
49
49
|
];
|
|
50
|
-
return { wantsBackend, rewrites };
|
|
50
|
+
return { wantsBackend, rewrites, baseUrl };
|
|
51
51
|
}
|
|
52
52
|
exports.build = build;
|
|
53
53
|
async function ɵcodegenPublicDirectory(root, dest) {
|
|
@@ -64,12 +64,11 @@ async function ɵcodegenFunctionsDirectory(sourceDir) {
|
|
|
64
64
|
const packageJson = JSON.parse(packageJsonBuffer.toString());
|
|
65
65
|
packageJson.dependencies || (packageJson.dependencies = {});
|
|
66
66
|
packageJson.dependencies["nitro-output"] = `file:${serverDir}`;
|
|
67
|
-
|
|
68
|
-
return { packageJson, frameworksEntry: "nitro", baseUrl };
|
|
67
|
+
return { packageJson, frameworksEntry: "nitro" };
|
|
69
68
|
}
|
|
70
69
|
exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
|
|
71
70
|
async function getDevModeHandle(cwd) {
|
|
72
|
-
const host = new Promise((resolve) => {
|
|
71
|
+
const host = new Promise((resolve, reject) => {
|
|
73
72
|
const cli = (0, utils_1.getNodeModuleBin)("nuxt", cwd);
|
|
74
73
|
const serve = (0, cross_spawn_1.spawn)(cli, ["dev"], { cwd: cwd });
|
|
75
74
|
serve.stdout.on("data", (data) => {
|
|
@@ -81,6 +80,7 @@ async function getDevModeHandle(cwd) {
|
|
|
81
80
|
serve.stderr.on("data", (data) => {
|
|
82
81
|
process.stderr.write(data);
|
|
83
82
|
});
|
|
83
|
+
serve.on("exit", reject);
|
|
84
84
|
});
|
|
85
85
|
return (0, utils_1.simpleProxy)(await host);
|
|
86
86
|
}
|
|
@@ -60,7 +60,7 @@ async function ɵcodegenFunctionsDirectory(rootDir, destDir) {
|
|
|
60
60
|
}
|
|
61
61
|
exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
|
|
62
62
|
async function getDevModeHandle(cwd) {
|
|
63
|
-
const host = new Promise((resolve) => {
|
|
63
|
+
const host = new Promise((resolve, reject) => {
|
|
64
64
|
const cli = (0, utils_1.getNodeModuleBin)("nuxt", cwd);
|
|
65
65
|
const serve = (0, cross_spawn_1.spawn)(cli, ["dev"], { cwd });
|
|
66
66
|
serve.stdout.on("data", (data) => {
|
|
@@ -72,6 +72,7 @@ async function getDevModeHandle(cwd) {
|
|
|
72
72
|
serve.stderr.on("data", (data) => {
|
|
73
73
|
process.stderr.write(data);
|
|
74
74
|
});
|
|
75
|
+
serve.on("exit", reject);
|
|
75
76
|
});
|
|
76
77
|
return (0, utils_3.simpleProxy)(await host);
|
|
77
78
|
}
|
package/lib/frameworks/utils.js
CHANGED
|
@@ -32,16 +32,31 @@ async function warnIfCustomBuildScript(dir, framework, defaultBuildScripts) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
exports.warnIfCustomBuildScript = warnIfCustomBuildScript;
|
|
35
|
+
function proxyResponse(original, next) {
|
|
36
|
+
return (response) => {
|
|
37
|
+
const { statusCode, statusMessage } = response;
|
|
38
|
+
if (!statusCode) {
|
|
39
|
+
original.end();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (statusCode === 404) {
|
|
43
|
+
return next();
|
|
44
|
+
}
|
|
45
|
+
const headers = "getHeaders" in response ? response.getHeaders() : response.headers;
|
|
46
|
+
original.writeHead(statusCode, statusMessage, headers);
|
|
47
|
+
response.pipe(original);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
35
50
|
function simpleProxy(hostOrRequestHandler) {
|
|
36
51
|
const agent = new http_1.Agent({ keepAlive: true });
|
|
52
|
+
const firebaseDefaultsJSON = process.env.__FIREBASE_DEFAULTS__;
|
|
53
|
+
const authTokenSyncURL = firebaseDefaultsJSON && JSON.parse(firebaseDefaultsJSON)._authTokenSyncURL;
|
|
37
54
|
return async (originalReq, originalRes, next) => {
|
|
38
55
|
const { method, headers, url: path } = originalReq;
|
|
39
56
|
if (!method || !path) {
|
|
40
57
|
originalRes.end();
|
|
41
58
|
return;
|
|
42
59
|
}
|
|
43
|
-
const firebaseDefaultsJSON = process.env.__FIREBASE_DEFAULTS__;
|
|
44
|
-
const authTokenSyncURL = firebaseDefaultsJSON && JSON.parse(firebaseDefaultsJSON)._authTokenSyncURL;
|
|
45
60
|
if (path === authTokenSyncURL) {
|
|
46
61
|
return next();
|
|
47
62
|
}
|
|
@@ -61,8 +76,13 @@ function simpleProxy(hostOrRequestHandler) {
|
|
|
61
76
|
};
|
|
62
77
|
const req = (0, http_1.request)(opts, (response) => {
|
|
63
78
|
const { statusCode, statusMessage, headers } = response;
|
|
64
|
-
|
|
65
|
-
|
|
79
|
+
if (statusCode === 404) {
|
|
80
|
+
next();
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
originalRes.writeHead(statusCode, statusMessage, headers);
|
|
84
|
+
response.pipe(originalRes);
|
|
85
|
+
}
|
|
66
86
|
});
|
|
67
87
|
originalReq.pipe(req);
|
|
68
88
|
req.on("error", (err) => {
|
|
@@ -71,7 +91,9 @@ function simpleProxy(hostOrRequestHandler) {
|
|
|
71
91
|
});
|
|
72
92
|
}
|
|
73
93
|
else {
|
|
74
|
-
await hostOrRequestHandler(originalReq, originalRes);
|
|
94
|
+
await Promise.resolve(hostOrRequestHandler(originalReq, originalRes, next));
|
|
95
|
+
const proxiedRes = new http_1.ServerResponse(originalReq);
|
|
96
|
+
proxyResponse(originalRes, next)(proxiedRes);
|
|
75
97
|
}
|
|
76
98
|
};
|
|
77
99
|
}
|
|
@@ -183,22 +205,18 @@ function getFrameworksBuildTarget(purpose, validOptions) {
|
|
|
183
205
|
}
|
|
184
206
|
return frameworksBuild;
|
|
185
207
|
}
|
|
186
|
-
else if (
|
|
187
|
-
switch (process.env.NODE_ENV) {
|
|
188
|
-
case "development":
|
|
189
|
-
return "development";
|
|
190
|
-
case "production":
|
|
191
|
-
case "test":
|
|
192
|
-
return "production";
|
|
193
|
-
default:
|
|
194
|
-
throw new error_1.FirebaseError(`We cannot infer your build target from a non-standard NODE_ENV. Please set the FIREBASE_FRAMEWORKS_BUILD_TARGET environment variable. Valid values are: ${validOptions.join(", ")}`);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
else if (purpose !== "serve") {
|
|
208
|
+
else if (["test", "deploy"].includes(purpose)) {
|
|
198
209
|
return "production";
|
|
199
210
|
}
|
|
200
|
-
|
|
201
|
-
|
|
211
|
+
switch (process.env.NODE_ENV) {
|
|
212
|
+
case undefined:
|
|
213
|
+
case "development":
|
|
214
|
+
return "development";
|
|
215
|
+
case "production":
|
|
216
|
+
case "test":
|
|
217
|
+
return "production";
|
|
218
|
+
default:
|
|
219
|
+
throw new error_1.FirebaseError(`We cannot infer your build target from a non-standard NODE_ENV. Please set the FIREBASE_FRAMEWORKS_BUILD_TARGET environment variable. Valid values are: ${validOptions.join(", ")}`);
|
|
202
220
|
}
|
|
203
221
|
}
|
|
204
222
|
exports.getFrameworksBuildTarget = getFrameworksBuildTarget;
|
|
@@ -72,7 +72,7 @@ async function ɵcodegenPublicDirectory(root, dest) {
|
|
|
72
72
|
}
|
|
73
73
|
exports.ɵcodegenPublicDirectory = ɵcodegenPublicDirectory;
|
|
74
74
|
async function getDevModeHandle(dir) {
|
|
75
|
-
const host = new Promise((resolve) => {
|
|
75
|
+
const host = new Promise((resolve, reject) => {
|
|
76
76
|
const cli = (0, utils_1.getNodeModuleBin)("vite", dir);
|
|
77
77
|
const serve = (0, cross_spawn_1.spawn)(cli, [], { cwd: dir });
|
|
78
78
|
serve.stdout.on("data", (data) => {
|
|
@@ -84,6 +84,7 @@ async function getDevModeHandle(dir) {
|
|
|
84
84
|
serve.stderr.on("data", (data) => {
|
|
85
85
|
process.stderr.write(data);
|
|
86
86
|
});
|
|
87
|
+
serve.on("exit", reject);
|
|
87
88
|
});
|
|
88
89
|
return (0, utils_1.simpleProxy)(await host);
|
|
89
90
|
}
|
package/lib/serve/index.js
CHANGED
|
@@ -19,7 +19,7 @@ async function serve(options) {
|
|
|
19
19
|
options.port = parseInt(options.port, 10);
|
|
20
20
|
if (targetNames.includes("hosting") && config.extract(options).some((it) => it.source)) {
|
|
21
21
|
experiments.assertEnabled("webframeworks", "emulate a web framework");
|
|
22
|
-
await (0, frameworks_1.prepareFrameworks)(targetNames,
|
|
22
|
+
await (0, frameworks_1.prepareFrameworks)("emulate", targetNames, undefined, options);
|
|
23
23
|
}
|
|
24
24
|
const isDemoProject = constants_1.Constants.isDemoProject((0, projectUtils_1.getProjectId)(options) || "");
|
|
25
25
|
targetNames.forEach((targetName) => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Learn detailed information about the fields of an extension.yaml file in the docs:
|
|
2
2
|
# https://firebase.google.com/docs/extensions/reference/extension-yaml
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
# Identifier for your extension
|
|
5
|
+
# TODO: Replace this with an descriptive name for your extension.
|
|
6
|
+
name: greet-the-world
|
|
5
7
|
version: 0.0.1 # Follow semver versioning
|
|
6
8
|
specVersion: v1beta # Version of the Firebase Extensions specification
|
|
7
9
|
|
|
@@ -14,12 +16,13 @@ description: >-
|
|
|
14
16
|
|
|
15
17
|
license: Apache-2.0 # https://spdx.org/licenses/
|
|
16
18
|
|
|
17
|
-
# Public URL for the source code of your extension
|
|
18
|
-
|
|
19
|
+
# Public URL for the source code of your extension.
|
|
20
|
+
# TODO: Replace this with your GitHub repo.
|
|
21
|
+
sourceUrl: https://github.com/ORG_OR_USER/REPO_NAME
|
|
19
22
|
|
|
20
23
|
# Specify whether a paid-tier billing plan is required to use your extension.
|
|
21
24
|
# Learn more in the docs: https://firebase.google.com/docs/extensions/reference/extension-yaml#billing-required-field
|
|
22
|
-
billingRequired:
|
|
25
|
+
billingRequired: true
|
|
23
26
|
|
|
24
27
|
# In an `apis` field, list any Google APIs (like Cloud Translation, BigQuery, etc.)
|
|
25
28
|
# required for your extension to operate.
|
|
@@ -39,8 +42,6 @@ resources:
|
|
|
39
42
|
description: >-
|
|
40
43
|
HTTP request-triggered function that responds with a specified greeting message
|
|
41
44
|
properties:
|
|
42
|
-
# LOCATION is a user-configured parameter value specified by the user during installation.
|
|
43
|
-
location: ${LOCATION}
|
|
44
45
|
# httpsTrigger is used for an HTTP triggered function.
|
|
45
46
|
httpsTrigger: {}
|
|
46
47
|
runtime: "nodejs16"
|
|
@@ -58,54 +59,3 @@ params:
|
|
|
58
59
|
default: Hello
|
|
59
60
|
required: true
|
|
60
61
|
immutable: false
|
|
61
|
-
|
|
62
|
-
- param: LOCATION
|
|
63
|
-
label: Cloud Functions location
|
|
64
|
-
description: >-
|
|
65
|
-
Where do you want to deploy the functions created for this extension?
|
|
66
|
-
For help selecting a location, refer to the [location selection
|
|
67
|
-
guide](https://firebase.google.com/docs/functions/locations).
|
|
68
|
-
type: select
|
|
69
|
-
options:
|
|
70
|
-
- label: Iowa (us-central1)
|
|
71
|
-
value: us-central1
|
|
72
|
-
- label: South Carolina (us-east1)
|
|
73
|
-
value: us-east1
|
|
74
|
-
- label: Northern Virginia (us-east4)
|
|
75
|
-
value: us-east4
|
|
76
|
-
- label: Los Angeles (us-west2)
|
|
77
|
-
value: us-west2
|
|
78
|
-
- label: Salt Lake City (us-west3)
|
|
79
|
-
value: us-west3
|
|
80
|
-
- label: Las Vegas (us-west4)
|
|
81
|
-
value: us-west4
|
|
82
|
-
- label: Warsaw (europe-central2)
|
|
83
|
-
value: europe-central2
|
|
84
|
-
- label: Belgium (europe-west1)
|
|
85
|
-
value: europe-west1
|
|
86
|
-
- label: London (europe-west2)
|
|
87
|
-
value: europe-west2
|
|
88
|
-
- label: Frankfurt (europe-west3)
|
|
89
|
-
value: europe-west3
|
|
90
|
-
- label: Zurich (europe-west6)
|
|
91
|
-
value: europe-west6
|
|
92
|
-
- label: Hong Kong (asia-east2)
|
|
93
|
-
value: asia-east2
|
|
94
|
-
- label: Tokyo (asia-northeast1)
|
|
95
|
-
value: asia-northeast1
|
|
96
|
-
- label: Osaka (asia-northeast2)
|
|
97
|
-
value: asia-northeast2
|
|
98
|
-
- label: Seoul (asia-northeast3)
|
|
99
|
-
value: asia-northeast3
|
|
100
|
-
- label: Mumbai (asia-south1)
|
|
101
|
-
value: asia-south1
|
|
102
|
-
- label: Jakarta (asia-southeast2)
|
|
103
|
-
value: asia-southeast2
|
|
104
|
-
- label: Montreal (northamerica-northeast1)
|
|
105
|
-
value: northamerica-northeast1
|
|
106
|
-
- label: Sao Paulo (southamerica-east1)
|
|
107
|
-
value: southamerica-east1
|
|
108
|
-
- label: Sydney (australia-southeast1)
|
|
109
|
-
value: australia-southeast1
|
|
110
|
-
required: true
|
|
111
|
-
immutable: true
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Reference PARAMETERS in your functions code with:
|
|
6
6
|
* `process.env.<parameter-name>`
|
|
7
7
|
* Learn more about building extensions in the docs:
|
|
8
|
-
* https://firebase.google.com/docs/extensions/
|
|
8
|
+
* https://firebase.google.com/docs/extensions/publishers
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const functions = require("firebase-functions");
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
rules_version = '2';
|
|
2
|
+
|
|
3
|
+
// Craft rules based on data in your Firestore database
|
|
4
|
+
// allow write: if firestore.get(
|
|
5
|
+
// /databases/(default)/documents/users/$(request.auth.uid)).data.isAdmin;
|
|
2
6
|
service firebase.storage {
|
|
3
7
|
match /b/{bucket}/o {
|
|
4
8
|
match /{allPaths=**} {
|