firebase-tools 13.0.0 → 13.0.2
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 +2 -2
- package/lib/commands/{frameworks-backends-create.js → apphosting-backends-create.js} +6 -3
- package/lib/commands/{frameworks-backends-delete.js → apphosting-backends-delete.js} +9 -7
- package/lib/commands/{frameworks-backends-get.js → apphosting-backends-get.js} +16 -27
- package/lib/commands/{frameworks-backends-list.js → apphosting-backends-list.js} +9 -19
- package/lib/commands/apphosting-builds-create.js +31 -0
- package/lib/commands/apphosting-builds-get.js +18 -0
- package/lib/commands/apphosting-rollouts-create.js +26 -0
- package/lib/commands/apphosting-rollouts-list.js +18 -0
- package/lib/commands/index.js +12 -6
- package/lib/deploy/functions/services/firestore.js +11 -1
- package/lib/frameworks/angular/index.js +5 -3
- package/lib/frameworks/angular/utils.js +19 -2
- package/lib/frameworks/astro/index.js +5 -2
- package/lib/frameworks/astro/utils.js +3 -2
- package/lib/frameworks/constants.js +31 -7
- package/lib/frameworks/index.js +12 -7
- package/lib/frameworks/next/index.js +24 -8
- package/lib/frameworks/next/utils.js +1 -1
- package/lib/frameworks/nuxt/index.js +15 -5
- package/lib/frameworks/nuxt2/index.js +5 -4
- package/lib/frameworks/sveltekit/index.js +2 -1
- package/lib/frameworks/utils.js +13 -9
- package/lib/frameworks/vite/index.js +19 -5
- package/lib/gcp/apphosting.js +89 -0
- package/lib/gcp/cloudbuild.js +5 -1
- package/lib/hosting/api.js +19 -1
- package/lib/init/features/{frameworks → apphosting}/constants.js +1 -2
- package/lib/init/features/apphosting/index.js +135 -0
- package/lib/init/features/{frameworks → apphosting}/repo.js +53 -28
- package/lib/init/features/hosting/index.js +1 -1
- package/lib/init/features/index.js +3 -3
- package/lib/init/index.js +0 -4
- package/lib/utils.js +26 -4
- package/package.json +1 -1
- package/lib/gcp/frameworks.js +0 -40
- package/lib/init/features/frameworks/index.js +0 -116
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDevModeHandle = exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.init = exports.build = exports.discover = exports.docsUrl = exports.type = exports.support = exports.name = void 0;
|
|
3
|
+
exports.getDevModeHandle = exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.init = exports.build = exports.discover = exports.docsUrl = exports.type = exports.support = exports.name = exports.supportedRange = void 0;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
5
|
const cross_spawn_1 = require("cross-spawn");
|
|
6
6
|
const promises_1 = require("fs/promises");
|
|
@@ -25,6 +25,7 @@ const api_1 = require("../../hosting/api");
|
|
|
25
25
|
const logger_1 = require("../../logger");
|
|
26
26
|
const DEFAULT_BUILD_SCRIPT = ["next build"];
|
|
27
27
|
const PUBLIC_DIR = "public";
|
|
28
|
+
exports.supportedRange = "12 - 14.0";
|
|
28
29
|
exports.name = "Next.js";
|
|
29
30
|
exports.support = "preview";
|
|
30
31
|
exports.type = 2;
|
|
@@ -38,22 +39,30 @@ function getReactVersion(cwd) {
|
|
|
38
39
|
async function discover(dir) {
|
|
39
40
|
if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "package.json"))))
|
|
40
41
|
return;
|
|
41
|
-
|
|
42
|
+
const version = (0, utils_2.getNextVersion)(dir);
|
|
43
|
+
if (!(await (0, fs_extra_1.pathExists)("next.config.js")) && !version)
|
|
42
44
|
return;
|
|
43
|
-
return { mayWantBackend: true, publicDirectory: (0, path_1.join)(dir, PUBLIC_DIR) };
|
|
45
|
+
return { mayWantBackend: true, publicDirectory: (0, path_1.join)(dir, PUBLIC_DIR), version };
|
|
44
46
|
}
|
|
45
47
|
exports.discover = discover;
|
|
46
|
-
async function build(dir) {
|
|
48
|
+
async function build(dir, target, context) {
|
|
47
49
|
var _a, _b;
|
|
48
50
|
await (0, utils_1.warnIfCustomBuildScript)(dir, exports.name, DEFAULT_BUILD_SCRIPT);
|
|
49
51
|
const reactVersion = getReactVersion(dir);
|
|
50
52
|
if (reactVersion && (0, semver_1.gte)(reactVersion, "18.0.0")) {
|
|
51
53
|
process.env.__NEXT_REACT_ROOT = "true";
|
|
52
54
|
}
|
|
55
|
+
const env = Object.assign({}, process.env);
|
|
56
|
+
if ((context === null || context === void 0 ? void 0 : context.projectId) && (context === null || context === void 0 ? void 0 : context.site)) {
|
|
57
|
+
const deploymentDomain = await (0, api_1.getDeploymentDomain)(context.projectId, context.site, context.hostingChannel);
|
|
58
|
+
if (deploymentDomain) {
|
|
59
|
+
env["VERCEL_URL"] = deploymentDomain;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
53
62
|
const cli = (0, utils_1.getNodeModuleBin)("next", dir);
|
|
54
63
|
const nextBuild = new Promise((resolve, reject) => {
|
|
55
64
|
var _a, _b;
|
|
56
|
-
const buildProcess = (0, cross_spawn_1.spawn)(cli, ["build"], { cwd: dir });
|
|
65
|
+
const buildProcess = (0, cross_spawn_1.spawn)(cli, ["build"], { cwd: dir, env });
|
|
57
66
|
(_a = buildProcess.stdout) === null || _a === void 0 ? void 0 : _a.on("data", (data) => logger_1.logger.info(data.toString()));
|
|
58
67
|
(_b = buildProcess.stderr) === null || _b === void 0 ? void 0 : _b.on("data", (data) => logger_1.logger.info(data.toString()));
|
|
59
68
|
buildProcess.on("error", (err) => {
|
|
@@ -186,7 +195,7 @@ async function init(setup, config) {
|
|
|
186
195
|
message: "What language would you like to use?",
|
|
187
196
|
choices: ["JavaScript", "TypeScript"],
|
|
188
197
|
});
|
|
189
|
-
(0, child_process_1.execSync)(`npx --yes create-next-app@
|
|
198
|
+
(0, child_process_1.execSync)(`npx --yes create-next-app@"${exports.supportedRange}" -e hello-world ${setup.hosting.source} --use-npm ${language === "TypeScript" ? "--ts" : "--js"}`, { stdio: "inherit", cwd: config.projectDir });
|
|
190
199
|
}
|
|
191
200
|
exports.init = init;
|
|
192
201
|
async function ɵcodegenPublicDirectory(sourceDir, destDir, _, context) {
|
|
@@ -302,7 +311,7 @@ async function ɵcodegenPublicDirectory(sourceDir, destDir, _, context) {
|
|
|
302
311
|
}));
|
|
303
312
|
}
|
|
304
313
|
exports.ɵcodegenPublicDirectory = ɵcodegenPublicDirectory;
|
|
305
|
-
async function ɵcodegenFunctionsDirectory(sourceDir, destDir) {
|
|
314
|
+
async function ɵcodegenFunctionsDirectory(sourceDir, destDir, target, context) {
|
|
306
315
|
const { distDir } = await getConfig(sourceDir);
|
|
307
316
|
const packageJson = await (0, utils_1.readJSON)((0, path_1.join)(sourceDir, "package.json"));
|
|
308
317
|
if ((0, fs_1.existsSync)((0, path_1.join)(sourceDir, "next.config.js"))) {
|
|
@@ -352,9 +361,16 @@ async function ɵcodegenFunctionsDirectory(sourceDir, destDir) {
|
|
|
352
361
|
if (await (0, utils_2.isUsingImageOptimization)(sourceDir, distDir)) {
|
|
353
362
|
packageJson.dependencies["sharp"] = constants_1.SHARP_VERSION;
|
|
354
363
|
}
|
|
364
|
+
const dotEnv = {};
|
|
365
|
+
if ((context === null || context === void 0 ? void 0 : context.projectId) && (context === null || context === void 0 ? void 0 : context.site)) {
|
|
366
|
+
const deploymentDomain = await (0, api_1.getDeploymentDomain)(context.projectId, context.site, context.hostingChannel);
|
|
367
|
+
if (deploymentDomain) {
|
|
368
|
+
dotEnv["VERCEL_URL"] = deploymentDomain;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
355
371
|
await (0, fs_extra_1.mkdirp)((0, path_1.join)(destDir, distDir));
|
|
356
372
|
await (0, fs_extra_1.copy)((0, path_1.join)(sourceDir, distDir), (0, path_1.join)(destDir, distDir));
|
|
357
|
-
return { packageJson, frameworksEntry: "next.js" };
|
|
373
|
+
return { packageJson, frameworksEntry: "next.js", dotEnv };
|
|
358
374
|
}
|
|
359
375
|
exports.ɵcodegenFunctionsDirectory = ɵcodegenFunctionsDirectory;
|
|
360
376
|
async function getDevModeHandle(dir, _, hostingEmulatorInfo) {
|
|
@@ -162,7 +162,7 @@ exports.getNonStaticServerComponents = getNonStaticServerComponents;
|
|
|
162
162
|
async function getHeadersFromMetaFiles(sourceDir, distDir, basePath, appPathRoutesManifest) {
|
|
163
163
|
const headers = [];
|
|
164
164
|
await Promise.all(Object.entries(appPathRoutesManifest).map(async ([key, source]) => {
|
|
165
|
-
if ((0, path_1.basename)(key)
|
|
165
|
+
if (!["route", "page"].includes((0, path_1.basename)(key)))
|
|
166
166
|
return;
|
|
167
167
|
const parts = source.split("/").filter((it) => !!it);
|
|
168
168
|
const partsOrIndex = parts.length > 0 ? parts : ["index"];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getConfig = exports.getDevModeHandle = exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.build = exports.discover = exports.type = exports.support = exports.name = void 0;
|
|
3
|
+
exports.init = exports.getConfig = exports.getDevModeHandle = exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.build = exports.discover = exports.supportedRange = exports.type = exports.support = exports.name = void 0;
|
|
4
4
|
const fs_extra_1 = require("fs-extra");
|
|
5
5
|
const promises_1 = require("fs/promises");
|
|
6
6
|
const path_1 = require("path");
|
|
@@ -11,20 +11,22 @@ const utils_2 = require("./utils");
|
|
|
11
11
|
exports.name = "Nuxt";
|
|
12
12
|
exports.support = "experimental";
|
|
13
13
|
exports.type = 4;
|
|
14
|
+
exports.supportedRange = "3";
|
|
14
15
|
const utils_3 = require("./utils");
|
|
15
16
|
const error_1 = require("../../error");
|
|
17
|
+
const child_process_1 = require("child_process");
|
|
16
18
|
const DEFAULT_BUILD_SCRIPT = ["nuxt build", "nuxi build"];
|
|
17
19
|
async function discover(dir) {
|
|
18
20
|
if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(dir, "package.json"))))
|
|
19
21
|
return;
|
|
20
22
|
const anyConfigFileExists = await (0, utils_3.nuxtConfigFilesExist)(dir);
|
|
21
|
-
const
|
|
22
|
-
if (!anyConfigFileExists && !
|
|
23
|
+
const version = (0, utils_2.getNuxtVersion)(dir);
|
|
24
|
+
if (!anyConfigFileExists && !version)
|
|
23
25
|
return;
|
|
24
|
-
if (
|
|
26
|
+
if (version && (0, semver_1.lt)(version, "3.0.0-0"))
|
|
25
27
|
return;
|
|
26
28
|
const { dir: { public: publicDirectory }, ssr: mayWantBackend, } = await getConfig(dir);
|
|
27
|
-
return { publicDirectory, mayWantBackend };
|
|
29
|
+
return { publicDirectory, mayWantBackend, version };
|
|
28
30
|
}
|
|
29
31
|
exports.discover = discover;
|
|
30
32
|
async function build(cwd) {
|
|
@@ -90,3 +92,11 @@ async function getConfig(dir) {
|
|
|
90
92
|
return await loadNuxtConfig(dir);
|
|
91
93
|
}
|
|
92
94
|
exports.getConfig = getConfig;
|
|
95
|
+
function init(setup, config) {
|
|
96
|
+
(0, child_process_1.execSync)(`npx --yes nuxi@"${exports.supportedRange}" init ${setup.hosting.source}`, {
|
|
97
|
+
stdio: "inherit",
|
|
98
|
+
cwd: config.projectDir,
|
|
99
|
+
});
|
|
100
|
+
return Promise.resolve();
|
|
101
|
+
}
|
|
102
|
+
exports.init = init;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDevModeHandle = exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.build = exports.discover = exports.type = exports.support = exports.name = void 0;
|
|
3
|
+
exports.getDevModeHandle = exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.build = exports.discover = exports.supportedRange = exports.type = exports.support = exports.name = void 0;
|
|
4
4
|
const fs_extra_1 = require("fs-extra");
|
|
5
5
|
const promises_1 = require("fs/promises");
|
|
6
6
|
const path_1 = require("path");
|
|
@@ -12,6 +12,7 @@ const cross_spawn_1 = require("cross-spawn");
|
|
|
12
12
|
exports.name = "Nuxt";
|
|
13
13
|
exports.support = "experimental";
|
|
14
14
|
exports.type = 2;
|
|
15
|
+
exports.supportedRange = "2";
|
|
15
16
|
async function getAndLoadNuxt(options) {
|
|
16
17
|
const nuxt = await (0, utils_1.relativeRequire)(options.rootDir, "nuxt/dist/nuxt.js");
|
|
17
18
|
const app = await nuxt.loadNuxt(options);
|
|
@@ -21,11 +22,11 @@ async function getAndLoadNuxt(options) {
|
|
|
21
22
|
async function discover(rootDir) {
|
|
22
23
|
if (!(await (0, fs_extra_1.pathExists)((0, path_1.join)(rootDir, "package.json"))))
|
|
23
24
|
return;
|
|
24
|
-
const
|
|
25
|
-
if (!
|
|
25
|
+
const version = (0, utils_2.getNuxtVersion)(rootDir);
|
|
26
|
+
if (!version || (version && (0, semver_1.gte)(version, "3.0.0-0")))
|
|
26
27
|
return;
|
|
27
28
|
const { app } = await getAndLoadNuxt({ rootDir, for: "build" });
|
|
28
|
-
return { mayWantBackend: true, publicDirectory: app.options.dir.static };
|
|
29
|
+
return { mayWantBackend: true, publicDirectory: app.options.dir.static, version };
|
|
29
30
|
}
|
|
30
31
|
exports.discover = discover;
|
|
31
32
|
async function build(rootDir) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.build = exports.getDevModeHandle = exports.discover = exports.type = exports.support = exports.name = void 0;
|
|
3
|
+
exports.ɵcodegenFunctionsDirectory = exports.ɵcodegenPublicDirectory = exports.build = exports.supportedRange = exports.getDevModeHandle = exports.discover = exports.type = exports.support = exports.name = void 0;
|
|
4
4
|
const fs_extra_1 = require("fs-extra");
|
|
5
5
|
const path_1 = require("path");
|
|
6
6
|
const vite_1 = require("../vite");
|
|
@@ -12,6 +12,7 @@ exports.type = 2;
|
|
|
12
12
|
exports.discover = (0, vite_1.viteDiscoverWithNpmDependency)("@sveltejs/kit");
|
|
13
13
|
var vite_2 = require("../vite");
|
|
14
14
|
Object.defineProperty(exports, "getDevModeHandle", { enumerable: true, get: function () { return vite_2.getDevModeHandle; } });
|
|
15
|
+
Object.defineProperty(exports, "supportedRange", { enumerable: true, get: function () { return vite_2.supportedRange; } });
|
|
15
16
|
async function build(root) {
|
|
16
17
|
var _a;
|
|
17
18
|
const config = await getConfig(root);
|
package/lib/frameworks/utils.js
CHANGED
|
@@ -7,6 +7,7 @@ const promises_1 = require("fs/promises");
|
|
|
7
7
|
const http_1 = require("http");
|
|
8
8
|
const cross_spawn_1 = require("cross-spawn");
|
|
9
9
|
const clc = require("colorette");
|
|
10
|
+
const semver_1 = require("semver");
|
|
10
11
|
const logger_1 = require("../logger");
|
|
11
12
|
const error_1 = require("../error");
|
|
12
13
|
const fsutils_1 = require("../fsutils");
|
|
@@ -206,20 +207,23 @@ function relativeRequire(dir, mod) {
|
|
|
206
207
|
}
|
|
207
208
|
}
|
|
208
209
|
exports.relativeRequire = relativeRequire;
|
|
209
|
-
function conjoinOptions(
|
|
210
|
-
if (!
|
|
211
|
-
return;
|
|
210
|
+
function conjoinOptions(_opts, conjunction = "and", separator = ",") {
|
|
211
|
+
if (!_opts.length)
|
|
212
|
+
return "";
|
|
213
|
+
const opts = _opts.map((it) => it.toString().trim());
|
|
212
214
|
if (opts.length === 1)
|
|
213
|
-
return opts[0]
|
|
215
|
+
return opts[0];
|
|
214
216
|
if (opts.length === 2)
|
|
215
|
-
return `${opts[0]
|
|
216
|
-
const lastElement = opts.slice(-1)[0]
|
|
217
|
-
const allButLast = opts.slice(0, -1)
|
|
217
|
+
return `${opts[0]} ${conjunction} ${opts[1]}`;
|
|
218
|
+
const lastElement = opts.slice(-1)[0];
|
|
219
|
+
const allButLast = opts.slice(0, -1);
|
|
218
220
|
return `${allButLast.join(`${separator} `)}${separator} ${conjunction} ${lastElement}`;
|
|
219
221
|
}
|
|
220
222
|
exports.conjoinOptions = conjoinOptions;
|
|
221
|
-
function frameworksCallToAction(message, docsUrl = constants_1.DEFAULT_DOCS_URL, prefix = "") {
|
|
222
|
-
return `${prefix}${message}
|
|
223
|
+
function frameworksCallToAction(message, docsUrl = constants_1.DEFAULT_DOCS_URL, prefix = "", framework, version, supportedRange, vite = false) {
|
|
224
|
+
return `${prefix}${message}${framework && supportedRange && (!version || !(0, semver_1.satisfies)(version, supportedRange))
|
|
225
|
+
? clc.yellow(`\n${prefix}The integration is known to work with ${vite ? "Vite" : framework} version ${clc.italic(conjoinOptions(supportedRange.split("||")))}. You may encounter errors.`)
|
|
226
|
+
: ``}
|
|
223
227
|
|
|
224
228
|
${prefix}${clc.bold("Documentation:")} ${docsUrl}
|
|
225
229
|
${prefix}${clc.bold("File a bug:")} ${constants_1.FILE_BUG_URL}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDevModeHandle = exports.ɵcodegenPublicDirectory = exports.build = exports.discover = exports.vitePluginDiscover = exports.viteDiscoverWithNpmDependency = exports.init = exports.initViteTemplate = exports.DEFAULT_BUILD_SCRIPT = exports.type = exports.support = exports.name = void 0;
|
|
3
|
+
exports.getDevModeHandle = exports.ɵcodegenPublicDirectory = exports.build = exports.discover = exports.vitePluginDiscover = exports.viteDiscoverWithNpmDependency = exports.init = exports.initViteTemplate = exports.DEFAULT_BUILD_SCRIPT = exports.supportedRange = exports.type = exports.support = exports.name = void 0;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
5
|
const cross_spawn_1 = require("cross-spawn");
|
|
6
6
|
const fs_1 = require("fs");
|
|
7
7
|
const fs_extra_1 = require("fs-extra");
|
|
8
8
|
const path_1 = require("path");
|
|
9
|
+
const stripAnsi = require("strip-ansi");
|
|
9
10
|
const prompt_1 = require("../../prompt");
|
|
10
11
|
const utils_1 = require("../utils");
|
|
11
12
|
exports.name = "Vite";
|
|
12
13
|
exports.support = "experimental";
|
|
13
14
|
exports.type = 4;
|
|
15
|
+
exports.supportedRange = "3 - 5";
|
|
14
16
|
exports.DEFAULT_BUILD_SCRIPT = ["vite build", "tsc && vite build"];
|
|
15
17
|
const initViteTemplate = (template) => async (setup, config) => await init(setup, config, template);
|
|
16
18
|
exports.initViteTemplate = initViteTemplate;
|
|
@@ -24,7 +26,7 @@ async function init(setup, config, baseTemplate = "vanilla") {
|
|
|
24
26
|
{ name: "TypeScript", value: `${baseTemplate}-ts` },
|
|
25
27
|
],
|
|
26
28
|
});
|
|
27
|
-
(0, child_process_1.execSync)(`npm create vite@
|
|
29
|
+
(0, child_process_1.execSync)(`npm create vite@"${exports.supportedRange}" ${setup.hosting.source} --yes -- --template ${template}`, {
|
|
28
30
|
stdio: "inherit",
|
|
29
31
|
cwd: config.projectDir,
|
|
30
32
|
});
|
|
@@ -36,6 +38,7 @@ exports.viteDiscoverWithNpmDependency = viteDiscoverWithNpmDependency;
|
|
|
36
38
|
const vitePluginDiscover = (plugin) => async (dir) => await discover(dir, plugin);
|
|
37
39
|
exports.vitePluginDiscover = vitePluginDiscover;
|
|
38
40
|
async function discover(dir, plugin, npmDependency) {
|
|
41
|
+
var _a;
|
|
39
42
|
if (!(0, fs_1.existsSync)((0, path_1.join)(dir, "package.json")))
|
|
40
43
|
return;
|
|
41
44
|
const additionalDep = npmDependency && (0, utils_1.findDependency)(npmDependency, { cwd: dir, depth: 0, omitDev: false });
|
|
@@ -45,14 +48,24 @@ async function discover(dir, plugin, npmDependency) {
|
|
|
45
48
|
(0, fs_extra_1.pathExists)((0, path_1.join)(dir, "vite.config.ts")),
|
|
46
49
|
]);
|
|
47
50
|
const anyConfigFileExists = configFilesExist.some((it) => it);
|
|
48
|
-
|
|
51
|
+
const version = (_a = (0, utils_1.findDependency)("vite", {
|
|
52
|
+
cwd: dir,
|
|
53
|
+
depth,
|
|
54
|
+
omitDev: false,
|
|
55
|
+
})) === null || _a === void 0 ? void 0 : _a.version;
|
|
56
|
+
if (!anyConfigFileExists && !version)
|
|
49
57
|
return;
|
|
50
58
|
if (npmDependency && !additionalDep)
|
|
51
59
|
return;
|
|
52
60
|
const { appType, publicDir: publicDirectory, plugins } = await getConfig(dir);
|
|
53
61
|
if (plugin && !plugins.find(({ name }) => name === plugin))
|
|
54
62
|
return;
|
|
55
|
-
return {
|
|
63
|
+
return {
|
|
64
|
+
mayWantBackend: appType !== "spa",
|
|
65
|
+
publicDirectory,
|
|
66
|
+
version,
|
|
67
|
+
vite: true,
|
|
68
|
+
};
|
|
56
69
|
}
|
|
57
70
|
exports.discover = discover;
|
|
58
71
|
async function build(root) {
|
|
@@ -77,7 +90,8 @@ async function getDevModeHandle(dir) {
|
|
|
77
90
|
const serve = (0, cross_spawn_1.spawn)(cli, [], { cwd: dir });
|
|
78
91
|
serve.stdout.on("data", (data) => {
|
|
79
92
|
process.stdout.write(data);
|
|
80
|
-
const
|
|
93
|
+
const dataWithoutAnsiCodes = stripAnsi(data.toString());
|
|
94
|
+
const match = dataWithoutAnsiCodes.match(/(http:\/\/.+:\d+)/);
|
|
81
95
|
if (match)
|
|
82
96
|
resolve(match[1]);
|
|
83
97
|
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureApiEnabled = exports.listLocations = exports.updateTraffic = exports.listRollouts = exports.createRollout = exports.createBuild = exports.getBuild = exports.deleteBackend = exports.listBackends = exports.getBackend = exports.createBackend = exports.API_VERSION = exports.API_HOST = void 0;
|
|
4
|
+
const proto = require("../gcp/proto");
|
|
5
|
+
const apiv2_1 = require("../apiv2");
|
|
6
|
+
const projectUtils_1 = require("../projectUtils");
|
|
7
|
+
const api_1 = require("../api");
|
|
8
|
+
const ensureApiEnabled_1 = require("../ensureApiEnabled");
|
|
9
|
+
exports.API_HOST = new URL(api_1.apphostingOrigin).host;
|
|
10
|
+
exports.API_VERSION = "v1alpha";
|
|
11
|
+
const client = new apiv2_1.Client({
|
|
12
|
+
urlPrefix: api_1.apphostingOrigin,
|
|
13
|
+
auth: true,
|
|
14
|
+
apiVersion: exports.API_VERSION,
|
|
15
|
+
});
|
|
16
|
+
async function createBackend(projectId, location, backendReqBoby, backendId) {
|
|
17
|
+
const res = await client.post(`projects/${projectId}/locations/${location}/backends`, backendReqBoby, { queryParams: { backendId } });
|
|
18
|
+
return res.body;
|
|
19
|
+
}
|
|
20
|
+
exports.createBackend = createBackend;
|
|
21
|
+
async function getBackend(projectId, location, backendId) {
|
|
22
|
+
const name = `projects/${projectId}/locations/${location}/backends/${backendId}`;
|
|
23
|
+
const res = await client.get(name);
|
|
24
|
+
return res.body;
|
|
25
|
+
}
|
|
26
|
+
exports.getBackend = getBackend;
|
|
27
|
+
async function listBackends(projectId, location) {
|
|
28
|
+
const name = `projects/${projectId}/locations/${location}/backends`;
|
|
29
|
+
const res = await client.get(name);
|
|
30
|
+
return res.body;
|
|
31
|
+
}
|
|
32
|
+
exports.listBackends = listBackends;
|
|
33
|
+
async function deleteBackend(projectId, location, backendId) {
|
|
34
|
+
const name = `projects/${projectId}/locations/${location}/backends/${backendId}`;
|
|
35
|
+
const res = await client.delete(name);
|
|
36
|
+
return res.body;
|
|
37
|
+
}
|
|
38
|
+
exports.deleteBackend = deleteBackend;
|
|
39
|
+
async function getBuild(projectId, location, backendId, buildId) {
|
|
40
|
+
const name = `projects/${projectId}/locations/${location}/backends/${backendId}/builds/${buildId}`;
|
|
41
|
+
const res = await client.get(name);
|
|
42
|
+
return res.body;
|
|
43
|
+
}
|
|
44
|
+
exports.getBuild = getBuild;
|
|
45
|
+
async function createBuild(projectId, location, backendId, buildId, buildInput) {
|
|
46
|
+
const res = await client.post(`projects/${projectId}/locations/${location}/backends/${backendId}/builds`, buildInput, { queryParams: { buildId } });
|
|
47
|
+
return res.body;
|
|
48
|
+
}
|
|
49
|
+
exports.createBuild = createBuild;
|
|
50
|
+
async function createRollout(projectId, location, backendId, rolloutId, rollout) {
|
|
51
|
+
const res = await client.post(`projects/${projectId}/locations/${location}/backends/${backendId}/rollouts`, rollout, { queryParams: { rolloutId } });
|
|
52
|
+
return res.body;
|
|
53
|
+
}
|
|
54
|
+
exports.createRollout = createRollout;
|
|
55
|
+
async function listRollouts(projectId, location, backendId) {
|
|
56
|
+
const res = await client.get(`projects/${projectId}/locations/${location}/backends/${backendId}/rollouts`);
|
|
57
|
+
return res.body.rollouts;
|
|
58
|
+
}
|
|
59
|
+
exports.listRollouts = listRollouts;
|
|
60
|
+
async function updateTraffic(projectId, location, backendId, traffic) {
|
|
61
|
+
const fieldMasks = proto.fieldMasks(traffic);
|
|
62
|
+
const queryParams = {
|
|
63
|
+
updateMask: fieldMasks.join(","),
|
|
64
|
+
};
|
|
65
|
+
const name = `projects/${projectId}/locations/${location}/backends/${backendId}/traffic`;
|
|
66
|
+
const res = await client.patch(name, Object.assign(Object.assign({}, traffic), { name }), {
|
|
67
|
+
queryParams,
|
|
68
|
+
});
|
|
69
|
+
return res.body;
|
|
70
|
+
}
|
|
71
|
+
exports.updateTraffic = updateTraffic;
|
|
72
|
+
async function listLocations(projectId) {
|
|
73
|
+
let pageToken;
|
|
74
|
+
let locations = [];
|
|
75
|
+
do {
|
|
76
|
+
const response = await client.get(`projects/${projectId}/locations`);
|
|
77
|
+
if (response.body.locations && response.body.locations.length > 0) {
|
|
78
|
+
locations = locations.concat(response.body.locations);
|
|
79
|
+
}
|
|
80
|
+
pageToken = response.body.nextPageToken;
|
|
81
|
+
} while (pageToken);
|
|
82
|
+
return locations;
|
|
83
|
+
}
|
|
84
|
+
exports.listLocations = listLocations;
|
|
85
|
+
async function ensureApiEnabled(options) {
|
|
86
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
87
|
+
return await (0, ensureApiEnabled_1.ensure)(projectId, exports.API_HOST, "frameworks", true);
|
|
88
|
+
}
|
|
89
|
+
exports.ensureApiEnabled = ensureApiEnabled;
|
package/lib/gcp/cloudbuild.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deleteRepository = exports.getRepository = exports.createRepository = exports.fetchLinkableRepositories = exports.deleteConnection = exports.listConnections = exports.getConnection = exports.createConnection = void 0;
|
|
3
|
+
exports.serviceAgentEmail = exports.deleteRepository = exports.getRepository = exports.createRepository = exports.fetchLinkableRepositories = exports.deleteConnection = exports.listConnections = exports.getConnection = exports.createConnection = void 0;
|
|
4
4
|
const apiv2_1 = require("../apiv2");
|
|
5
5
|
const api_1 = require("../api");
|
|
6
6
|
const PAGE_SIZE_MAX = 100;
|
|
@@ -69,3 +69,7 @@ async function deleteRepository(projectId, location, connectionId, repositoryId)
|
|
|
69
69
|
return res.body;
|
|
70
70
|
}
|
|
71
71
|
exports.deleteRepository = deleteRepository;
|
|
72
|
+
function serviceAgentEmail(projectNumber) {
|
|
73
|
+
return `service-${projectNumber}@gcp-sa-cloudbuild.iam.gserviceaccount.com`;
|
|
74
|
+
}
|
|
75
|
+
exports.serviceAgentEmail = serviceAgentEmail;
|
package/lib/hosting/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getAllSiteDomains = exports.getSiteDomains = exports.cleanAuthState = exports.getCleanDomains = exports.removeAuthDomain = exports.addAuthDomains = exports.deleteSite = exports.updateSite = exports.createSite = exports.getSite = exports.listSites = exports.createRelease = exports.cloneVersion = exports.listVersions = exports.updateVersion = exports.createVersion = exports.deleteChannel = exports.updateChannelTtl = exports.createChannel = exports.listChannels = exports.getChannel = exports.normalizeName = exports.SiteType = void 0;
|
|
3
|
+
exports.getDeploymentDomain = exports.getAllSiteDomains = exports.getSiteDomains = exports.cleanAuthState = exports.getCleanDomains = exports.removeAuthDomain = exports.addAuthDomains = exports.deleteSite = exports.updateSite = exports.createSite = exports.getSite = exports.listSites = exports.createRelease = exports.cloneVersion = exports.listVersions = exports.updateVersion = exports.createVersion = exports.deleteChannel = exports.updateChannelTtl = exports.createChannel = exports.listChannels = exports.getChannel = exports.normalizeName = exports.SiteType = void 0;
|
|
4
4
|
const error_1 = require("../error");
|
|
5
5
|
const api_1 = require("../api");
|
|
6
6
|
const apiv2_1 = require("../apiv2");
|
|
@@ -8,6 +8,7 @@ const operationPoller = require("../operation-poller");
|
|
|
8
8
|
const expireUtils_1 = require("../hosting/expireUtils");
|
|
9
9
|
const auth_1 = require("../gcp/auth");
|
|
10
10
|
const proto = require("../gcp/proto");
|
|
11
|
+
const utils_1 = require("../utils");
|
|
11
12
|
const ONE_WEEK_MS = 604800000;
|
|
12
13
|
var ReleaseType;
|
|
13
14
|
(function (ReleaseType) {
|
|
@@ -170,6 +171,7 @@ async function getSite(project, site) {
|
|
|
170
171
|
if (e instanceof error_1.FirebaseError && e.status === 404) {
|
|
171
172
|
throw new error_1.FirebaseError(`could not find site "${site}" for project "${project}"`, {
|
|
172
173
|
original: e,
|
|
174
|
+
status: e.status,
|
|
173
175
|
});
|
|
174
176
|
}
|
|
175
177
|
throw e;
|
|
@@ -287,3 +289,19 @@ async function getAllSiteDomains(projectId, siteId) {
|
|
|
287
289
|
return Array.from(allSiteDomains);
|
|
288
290
|
}
|
|
289
291
|
exports.getAllSiteDomains = getAllSiteDomains;
|
|
292
|
+
async function getDeploymentDomain(projectId, siteId, hostingChannel) {
|
|
293
|
+
if (hostingChannel) {
|
|
294
|
+
const channel = await getChannel(projectId, siteId, hostingChannel);
|
|
295
|
+
return channel && (0, utils_1.getHostnameFromUrl)(channel === null || channel === void 0 ? void 0 : channel.url);
|
|
296
|
+
}
|
|
297
|
+
const site = await getSite(projectId, siteId).catch((e) => {
|
|
298
|
+
if (e instanceof error_1.FirebaseError &&
|
|
299
|
+
e.original instanceof error_1.FirebaseError &&
|
|
300
|
+
e.original.status === 404) {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
throw e;
|
|
304
|
+
});
|
|
305
|
+
return site && (0, utils_1.getHostnameFromUrl)(site === null || site === void 0 ? void 0 : site.defaultUrl);
|
|
306
|
+
}
|
|
307
|
+
exports.getDeploymentDomain = getDeploymentDomain;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ALLOWED_DEPLOY_METHODS = exports.DEFAULT_DEPLOY_METHOD = exports.
|
|
3
|
+
exports.ALLOWED_DEPLOY_METHODS = exports.DEFAULT_DEPLOY_METHOD = exports.DEFAULT_REGION = void 0;
|
|
4
4
|
exports.DEFAULT_REGION = "us-central1";
|
|
5
|
-
exports.ALLOWED_REGIONS = [{ name: "us-central1 (Iowa)", value: "us-central1" }];
|
|
6
5
|
exports.DEFAULT_DEPLOY_METHOD = "github";
|
|
7
6
|
exports.ALLOWED_DEPLOY_METHODS = [{ name: "Deploy using github", value: "github" }];
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.onboardRollout = exports.createBackend = exports.onboardBackend = exports.doSetup = void 0;
|
|
4
|
+
const clc = require("colorette");
|
|
5
|
+
const repo = require("./repo");
|
|
6
|
+
const poller = require("../../../operation-poller");
|
|
7
|
+
const apphosting = require("../../../gcp/apphosting");
|
|
8
|
+
const utils_1 = require("../../../utils");
|
|
9
|
+
const api_1 = require("../../../api");
|
|
10
|
+
const apphosting_1 = require("../../../gcp/apphosting");
|
|
11
|
+
const error_1 = require("../../../error");
|
|
12
|
+
const prompt_1 = require("../../../prompt");
|
|
13
|
+
const constants_1 = require("./constants");
|
|
14
|
+
const ensureApiEnabled_1 = require("../../../ensureApiEnabled");
|
|
15
|
+
const apphostingPollerOptions = {
|
|
16
|
+
apiOrigin: api_1.apphostingOrigin,
|
|
17
|
+
apiVersion: apphosting_1.API_VERSION,
|
|
18
|
+
masterTimeout: 25 * 60 * 1000,
|
|
19
|
+
maxBackoff: 10000,
|
|
20
|
+
};
|
|
21
|
+
async function doSetup(setup, projectId) {
|
|
22
|
+
await Promise.all([
|
|
23
|
+
(0, ensureApiEnabled_1.ensure)(projectId, "cloudbuild.googleapis.com", "apphosting", true),
|
|
24
|
+
(0, ensureApiEnabled_1.ensure)(projectId, "secretmanager.googleapis.com", "apphosting", true),
|
|
25
|
+
(0, ensureApiEnabled_1.ensure)(projectId, "run.googleapis.com", "apphosting", true),
|
|
26
|
+
(0, ensureApiEnabled_1.ensure)(projectId, "artifactregistry.googleapis.com", "apphosting", true),
|
|
27
|
+
]);
|
|
28
|
+
const allowedLocations = (await apphosting.listLocations(projectId)).map((loc) => loc.locationId);
|
|
29
|
+
if (setup.location) {
|
|
30
|
+
if (!allowedLocations.includes(setup.location)) {
|
|
31
|
+
throw new error_1.FirebaseError(`Invalid location ${setup.location}. Valid choices are ${allowedLocations.join(", ")}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
(0, utils_1.logBullet)("First we need a few details to create your backend.");
|
|
35
|
+
const location = setup.location || (await promptLocation(projectId, allowedLocations));
|
|
36
|
+
(0, utils_1.logSuccess)(`Region set to ${location}.\n`);
|
|
37
|
+
let backendId;
|
|
38
|
+
while (true) {
|
|
39
|
+
backendId = await (0, prompt_1.promptOnce)({
|
|
40
|
+
name: "backendId",
|
|
41
|
+
type: "input",
|
|
42
|
+
default: "my-web-app",
|
|
43
|
+
message: "Create a name for your backend [1-30 characters]",
|
|
44
|
+
});
|
|
45
|
+
try {
|
|
46
|
+
await apphosting.getBackend(projectId, location, backendId);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
if (err.status === 404) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
throw new error_1.FirebaseError(`Failed to check if backend with id ${backendId} already exists in ${location}`, { original: err });
|
|
53
|
+
}
|
|
54
|
+
(0, utils_1.logWarning)(`Backend with id ${backendId} already exists in ${location}`);
|
|
55
|
+
}
|
|
56
|
+
const backend = await onboardBackend(projectId, location, backendId);
|
|
57
|
+
const confirmRollout = await (0, prompt_1.promptOnce)({
|
|
58
|
+
type: "confirm",
|
|
59
|
+
name: "rollout",
|
|
60
|
+
default: true,
|
|
61
|
+
message: "Do you want to deploy now?",
|
|
62
|
+
});
|
|
63
|
+
if (!confirmRollout) {
|
|
64
|
+
(0, utils_1.logSuccess)(`Successfully created backend:\n\t${backend.name}`);
|
|
65
|
+
(0, utils_1.logSuccess)(`Your site will be deployed at:\n\thttps://${backend.uri}`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const branch = await (0, prompt_1.promptOnce)({
|
|
69
|
+
name: "branch",
|
|
70
|
+
type: "input",
|
|
71
|
+
default: "main",
|
|
72
|
+
message: "Which branch do you want to deploy?",
|
|
73
|
+
});
|
|
74
|
+
const { build } = await onboardRollout(projectId, location, backendId, {
|
|
75
|
+
source: {
|
|
76
|
+
codebase: {
|
|
77
|
+
branch,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
if (build.state !== "READY") {
|
|
82
|
+
throw new error_1.FirebaseError(`Failed to build your app. Please inspect the build logs at ${build.buildLogsUri}.`, { children: [build.error] });
|
|
83
|
+
}
|
|
84
|
+
(0, utils_1.logSuccess)(`Successfully created backend:\n\t${backend.name}`);
|
|
85
|
+
(0, utils_1.logSuccess)(`Your site is now deployed at:\n\thttps://${backend.uri}`);
|
|
86
|
+
(0, utils_1.logSuccess)(`View the rollout status by running:\n\tfirebase apphosting:backends:get ${backendId} --project ${projectId}`);
|
|
87
|
+
}
|
|
88
|
+
exports.doSetup = doSetup;
|
|
89
|
+
async function promptLocation(projectId, locations) {
|
|
90
|
+
return (await (0, prompt_1.promptOnce)({
|
|
91
|
+
name: "region",
|
|
92
|
+
type: "list",
|
|
93
|
+
default: constants_1.DEFAULT_REGION,
|
|
94
|
+
message: "Please select a region " +
|
|
95
|
+
`(${clc.yellow("info")}: Your region determines where your backend is located):\n`,
|
|
96
|
+
choices: locations.map((loc) => ({ value: loc })),
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
function toBackend(cloudBuildConnRepo) {
|
|
100
|
+
return {
|
|
101
|
+
servingLocality: "GLOBAL_ACCESS",
|
|
102
|
+
codebase: {
|
|
103
|
+
repository: `${cloudBuildConnRepo.name}`,
|
|
104
|
+
rootDirectory: "/",
|
|
105
|
+
},
|
|
106
|
+
labels: {},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async function onboardBackend(projectId, location, backendId) {
|
|
110
|
+
const cloudBuildConnRepo = await repo.linkGitHubRepository(projectId, location);
|
|
111
|
+
const backendDetails = toBackend(cloudBuildConnRepo);
|
|
112
|
+
return await createBackend(projectId, location, backendDetails, backendId);
|
|
113
|
+
}
|
|
114
|
+
exports.onboardBackend = onboardBackend;
|
|
115
|
+
async function createBackend(projectId, location, backendReqBoby, backendId) {
|
|
116
|
+
const op = await apphosting.createBackend(projectId, location, backendReqBoby, backendId);
|
|
117
|
+
const backend = await poller.pollOperation(Object.assign(Object.assign({}, apphostingPollerOptions), { pollerName: `create-${projectId}-${location}-${backendId}`, operationResourceName: op.name }));
|
|
118
|
+
return backend;
|
|
119
|
+
}
|
|
120
|
+
exports.createBackend = createBackend;
|
|
121
|
+
async function onboardRollout(projectId, location, backendId, buildInput) {
|
|
122
|
+
(0, utils_1.logBullet)("Starting a new rollout... this may take a few minutes.");
|
|
123
|
+
const buildId = (0, utils_1.generateId)();
|
|
124
|
+
const buildOp = await apphosting.createBuild(projectId, location, backendId, buildId, buildInput);
|
|
125
|
+
const rolloutId = (0, utils_1.generateId)();
|
|
126
|
+
const rolloutOp = await apphosting.createRollout(projectId, location, backendId, rolloutId, {
|
|
127
|
+
build: `projects/${projectId}/locations/${location}/backends/${backendId}/builds/${buildId}`,
|
|
128
|
+
});
|
|
129
|
+
const rolloutPoll = poller.pollOperation(Object.assign(Object.assign({}, apphostingPollerOptions), { pollerName: `create-${projectId}-${location}-backend-${backendId}-rollout-${rolloutId}`, operationResourceName: rolloutOp.name }));
|
|
130
|
+
const buildPoll = poller.pollOperation(Object.assign(Object.assign({}, apphostingPollerOptions), { pollerName: `create-${projectId}-${location}-backend-${backendId}-build-${buildId}`, operationResourceName: buildOp.name }));
|
|
131
|
+
const [rollout, build] = await Promise.all([rolloutPoll, buildPoll]);
|
|
132
|
+
(0, utils_1.logSuccess)("Rollout completed.");
|
|
133
|
+
return { rollout, build };
|
|
134
|
+
}
|
|
135
|
+
exports.onboardRollout = onboardRollout;
|