@hot-updater/firebase 0.35.8 → 0.35.9
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/dist/firebase/functions/index.cjs +1 -1
- package/dist/iac/index.cjs +392 -214
- package/dist/iac/index.d.cts +4 -5
- package/dist/iac/index.d.mts +4 -5
- package/dist/iac/index.mjs +385 -208
- package/dist/init/index.cjs +43 -0
- package/dist/init/index.d.cts +40 -0
- package/dist/init/index.d.mts +40 -0
- package/dist/init/index.mjs +40 -0
- package/package.json +13 -8
package/dist/iac/index.cjs
CHANGED
|
@@ -39,6 +39,7 @@ let node_path = require("node:path");
|
|
|
39
39
|
node_path = __toESM(node_path);
|
|
40
40
|
let node_timers_promises = require("node:timers/promises");
|
|
41
41
|
let node_os = require("node:os");
|
|
42
|
+
node_os = __toESM(node_os);
|
|
42
43
|
let node_events = require("node:events");
|
|
43
44
|
let node_v8 = require("node:v8");
|
|
44
45
|
let node_fs = require("node:fs");
|
|
@@ -1423,7 +1424,7 @@ var require_isexe = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1423
1424
|
//#region ../../node_modules/.pnpm/which@2.0.2/node_modules/which/which.js
|
|
1424
1425
|
var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1425
1426
|
const isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
1426
|
-
const path$
|
|
1427
|
+
const path$11 = require("path");
|
|
1427
1428
|
const COLON = isWindows ? ";" : ":";
|
|
1428
1429
|
const isexe = require_isexe();
|
|
1429
1430
|
const getNotFoundError = (cmd) => Object.assign(/* @__PURE__ */ new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -1453,7 +1454,7 @@ var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1453
1454
|
if (i === pathEnv.length) return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
|
|
1454
1455
|
const ppRaw = pathEnv[i];
|
|
1455
1456
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
1456
|
-
const pCmd = path$
|
|
1457
|
+
const pCmd = path$11.join(pathPart, cmd);
|
|
1457
1458
|
resolve(subStep(!pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd, i, 0));
|
|
1458
1459
|
});
|
|
1459
1460
|
const subStep = (p, i, ii) => new Promise((resolve, reject) => {
|
|
@@ -1474,7 +1475,7 @@ var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1474
1475
|
for (let i = 0; i < pathEnv.length; i++) {
|
|
1475
1476
|
const ppRaw = pathEnv[i];
|
|
1476
1477
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
1477
|
-
const pCmd = path$
|
|
1478
|
+
const pCmd = path$11.join(pathPart, cmd);
|
|
1478
1479
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
1479
1480
|
for (let j = 0; j < pathExt.length; j++) {
|
|
1480
1481
|
const cur = p + pathExt[j];
|
|
@@ -1505,7 +1506,7 @@ var require_path_key = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1505
1506
|
//#endregion
|
|
1506
1507
|
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
|
|
1507
1508
|
var require_resolveCommand = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1508
|
-
const path$
|
|
1509
|
+
const path$10 = require("path");
|
|
1509
1510
|
const which = require_which();
|
|
1510
1511
|
const getPathKey = require_path_key();
|
|
1511
1512
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
@@ -1520,12 +1521,12 @@ var require_resolveCommand = /* @__PURE__ */ __commonJSMin(((exports, module) =>
|
|
|
1520
1521
|
try {
|
|
1521
1522
|
resolved = which.sync(parsed.command, {
|
|
1522
1523
|
path: env[getPathKey({ env })],
|
|
1523
|
-
pathExt: withoutPathExt ? path$
|
|
1524
|
+
pathExt: withoutPathExt ? path$10.delimiter : void 0
|
|
1524
1525
|
});
|
|
1525
1526
|
} catch (e) {} finally {
|
|
1526
1527
|
if (shouldSwitchCwd) process.chdir(cwd);
|
|
1527
1528
|
}
|
|
1528
|
-
if (resolved) resolved = path$
|
|
1529
|
+
if (resolved) resolved = path$10.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
1529
1530
|
return resolved;
|
|
1530
1531
|
}
|
|
1531
1532
|
function resolveCommand(parsed) {
|
|
@@ -1592,7 +1593,7 @@ var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1592
1593
|
//#endregion
|
|
1593
1594
|
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
|
|
1594
1595
|
var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1595
|
-
const path$
|
|
1596
|
+
const path$9 = require("path");
|
|
1596
1597
|
const resolveCommand = require_resolveCommand();
|
|
1597
1598
|
const escape = require_escape();
|
|
1598
1599
|
const readShebang = require_readShebang();
|
|
@@ -1615,7 +1616,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1615
1616
|
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
1616
1617
|
if (parsed.options.forceShell || needsShell) {
|
|
1617
1618
|
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
1618
|
-
parsed.command = path$
|
|
1619
|
+
parsed.command = path$9.normalize(parsed.command);
|
|
1619
1620
|
parsed.command = escape.command(parsed.command);
|
|
1620
1621
|
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
|
|
1621
1622
|
parsed.args = [
|
|
@@ -6711,6 +6712,212 @@ createExeca(mapNode);
|
|
|
6711
6712
|
createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
|
|
6712
6713
|
const { sendMessage, getOneMessage, getEachMessage, getCancelSignal } = getIpcExport();
|
|
6713
6714
|
//#endregion
|
|
6715
|
+
//#region iac/init/index.ts
|
|
6716
|
+
const isFirebaseRegion = (value) => value !== void 0 && /^[a-z]+(?:-[a-z]+)+[0-9]+$/.test(value);
|
|
6717
|
+
const isFirebaseProjectId = (value) => value !== void 0 && /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/.test(value);
|
|
6718
|
+
const initProvider = {
|
|
6719
|
+
label: "Firebase",
|
|
6720
|
+
inputs: {
|
|
6721
|
+
projectId: {
|
|
6722
|
+
envKey: "HOT_UPDATER_FIREBASE_PROJECT_ID",
|
|
6723
|
+
help: "Firebase project ID",
|
|
6724
|
+
prompt: {
|
|
6725
|
+
message: "Enter the Firebase project ID:",
|
|
6726
|
+
placeholder: "hot-updater-app",
|
|
6727
|
+
type: "text"
|
|
6728
|
+
},
|
|
6729
|
+
validate: isFirebaseProjectId
|
|
6730
|
+
},
|
|
6731
|
+
region: {
|
|
6732
|
+
envKey: "HOT_UPDATER_FIREBASE_REGION",
|
|
6733
|
+
help: "Firebase Functions region",
|
|
6734
|
+
prompt: {
|
|
6735
|
+
message: "Select Region",
|
|
6736
|
+
type: "select"
|
|
6737
|
+
},
|
|
6738
|
+
validate: isFirebaseRegion
|
|
6739
|
+
},
|
|
6740
|
+
applicationCredentials: {
|
|
6741
|
+
envKey: "GOOGLE_APPLICATION_CREDENTIALS",
|
|
6742
|
+
help: "Service account JSON path",
|
|
6743
|
+
optional: true,
|
|
6744
|
+
persistence: "with-consent",
|
|
6745
|
+
prompt: {
|
|
6746
|
+
message: "Enter the service account JSON path (press Enter to configure later)",
|
|
6747
|
+
placeholder: "~/Downloads/firebase-service-account.json",
|
|
6748
|
+
type: "text"
|
|
6749
|
+
}
|
|
6750
|
+
}
|
|
6751
|
+
}
|
|
6752
|
+
};
|
|
6753
|
+
//#endregion
|
|
6754
|
+
//#region iac/firebaseApplicationCredentials.ts
|
|
6755
|
+
const inputFirebaseApplicationCredentials = async ({ applicationCredentials, nonInteractive, projectId }) => {
|
|
6756
|
+
if (nonInteractive) return applicationCredentials;
|
|
6757
|
+
const prompt = initProvider.inputs.applicationCredentials.prompt;
|
|
6758
|
+
_hot_updater_cli_tools.p.log.step(`Service account JSON: ${(0, _hot_updater_cli_tools.link)(`https://console.firebase.google.com/project/${projectId}/settings/serviceaccounts/adminsdk`)}`);
|
|
6759
|
+
_hot_updater_cli_tools.p.log.step("Project settings > Service accounts > Generate new private key");
|
|
6760
|
+
const credentialsPath = await _hot_updater_cli_tools.p.text({
|
|
6761
|
+
...(0, _hot_updater_cli_tools.getInitProviderTextPromptValues)(prompt, applicationCredentials),
|
|
6762
|
+
message: prompt.message
|
|
6763
|
+
});
|
|
6764
|
+
if (_hot_updater_cli_tools.p.isCancel(credentialsPath)) process.exit(1);
|
|
6765
|
+
return credentialsPath || void 0;
|
|
6766
|
+
};
|
|
6767
|
+
//#endregion
|
|
6768
|
+
//#region iac/firebaseInitInputs.ts
|
|
6769
|
+
const resolveFirebaseCredentialsPath = (credentialsPath, { cwd = process.cwd(), homeDir = node_os.default.homedir(), pathApi = node_path.default }) => {
|
|
6770
|
+
const homeRelativePath = credentialsPath === "~" ? "" : credentialsPath.startsWith("~/") || credentialsPath.startsWith("~\\") ? credentialsPath.slice(2) : void 0;
|
|
6771
|
+
return homeRelativePath === void 0 ? pathApi.resolve(cwd, credentialsPath) : pathApi.resolve(homeDir, homeRelativePath);
|
|
6772
|
+
};
|
|
6773
|
+
const getFirebaseCliEnv = (applicationCredentials, pathContext = {}) => {
|
|
6774
|
+
if (!applicationCredentials) return;
|
|
6775
|
+
const resolvedCredentialsPath = resolveFirebaseCredentialsPath(applicationCredentials, pathContext);
|
|
6776
|
+
return { [initProvider.inputs.applicationCredentials.envKey]: resolvedCredentialsPath };
|
|
6777
|
+
};
|
|
6778
|
+
const resolveFirebaseInitInputs = (existingEnv) => {
|
|
6779
|
+
const { inputs } = initProvider;
|
|
6780
|
+
const applicationCredentials = (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.applicationCredentials);
|
|
6781
|
+
return {
|
|
6782
|
+
applicationCredentials: applicationCredentials === "your-credentials.json" ? void 0 : applicationCredentials,
|
|
6783
|
+
projectId: (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.projectId),
|
|
6784
|
+
region: (0, _hot_updater_cli_tools.resolveInitProviderInput)(existingEnv, inputs.region)
|
|
6785
|
+
};
|
|
6786
|
+
};
|
|
6787
|
+
const assertFirebaseNonInteractiveInputs = (inputs, nonInteractive = false) => {
|
|
6788
|
+
(0, _hot_updater_cli_tools.assertInitProviderInputs)({
|
|
6789
|
+
inputs,
|
|
6790
|
+
provider: initProvider,
|
|
6791
|
+
strict: nonInteractive
|
|
6792
|
+
});
|
|
6793
|
+
};
|
|
6794
|
+
//#endregion
|
|
6795
|
+
//#region iac/firebaseRegion.ts
|
|
6796
|
+
const REGIONS = [
|
|
6797
|
+
{
|
|
6798
|
+
value: "us-central1",
|
|
6799
|
+
label: "US Central (Iowa)"
|
|
6800
|
+
},
|
|
6801
|
+
{
|
|
6802
|
+
value: "us-east1",
|
|
6803
|
+
label: "US East (South Carolina)"
|
|
6804
|
+
},
|
|
6805
|
+
{
|
|
6806
|
+
value: "us-east4",
|
|
6807
|
+
label: "US East (Northern Virginia)"
|
|
6808
|
+
},
|
|
6809
|
+
{
|
|
6810
|
+
value: "us-west1",
|
|
6811
|
+
label: "US West (Oregon)"
|
|
6812
|
+
},
|
|
6813
|
+
{
|
|
6814
|
+
value: "us-west2",
|
|
6815
|
+
label: "US West (Los Angeles)"
|
|
6816
|
+
},
|
|
6817
|
+
{
|
|
6818
|
+
value: "us-west3",
|
|
6819
|
+
label: "US West (Salt Lake City)"
|
|
6820
|
+
},
|
|
6821
|
+
{
|
|
6822
|
+
value: "us-west4",
|
|
6823
|
+
label: "US West (Las Vegas)"
|
|
6824
|
+
},
|
|
6825
|
+
{
|
|
6826
|
+
value: "europe-west1",
|
|
6827
|
+
label: "Europe West (Belgium)"
|
|
6828
|
+
},
|
|
6829
|
+
{
|
|
6830
|
+
value: "europe-west2",
|
|
6831
|
+
label: "Europe West (London)"
|
|
6832
|
+
},
|
|
6833
|
+
{
|
|
6834
|
+
value: "europe-west3",
|
|
6835
|
+
label: "Europe West (Frankfurt)"
|
|
6836
|
+
},
|
|
6837
|
+
{
|
|
6838
|
+
value: "europe-west6",
|
|
6839
|
+
label: "Europe West (Zurich)"
|
|
6840
|
+
},
|
|
6841
|
+
{
|
|
6842
|
+
value: "asia-east1",
|
|
6843
|
+
label: "Asia East (Taiwan)"
|
|
6844
|
+
},
|
|
6845
|
+
{
|
|
6846
|
+
value: "asia-east2",
|
|
6847
|
+
label: "Asia East (Hong Kong)"
|
|
6848
|
+
},
|
|
6849
|
+
{
|
|
6850
|
+
value: "asia-northeast1",
|
|
6851
|
+
label: "Asia Northeast (Tokyo)"
|
|
6852
|
+
},
|
|
6853
|
+
{
|
|
6854
|
+
value: "asia-northeast2",
|
|
6855
|
+
label: "Asia Northeast (Osaka)"
|
|
6856
|
+
},
|
|
6857
|
+
{
|
|
6858
|
+
value: "asia-northeast3",
|
|
6859
|
+
label: "Asia Northeast (Seoul)"
|
|
6860
|
+
},
|
|
6861
|
+
{
|
|
6862
|
+
value: "asia-south1",
|
|
6863
|
+
label: "Asia South (Mumbai)"
|
|
6864
|
+
},
|
|
6865
|
+
{
|
|
6866
|
+
value: "asia-southeast1",
|
|
6867
|
+
label: "Asia Southeast (Singapore)"
|
|
6868
|
+
},
|
|
6869
|
+
{
|
|
6870
|
+
value: "asia-southeast2",
|
|
6871
|
+
label: "Asia Southeast (Jakarta)"
|
|
6872
|
+
},
|
|
6873
|
+
{
|
|
6874
|
+
value: "australia-southeast1",
|
|
6875
|
+
label: "Australia Southeast (Sydney)"
|
|
6876
|
+
}
|
|
6877
|
+
];
|
|
6878
|
+
const resolveFirebaseRegion = async ({ cwd, discoverExistingProject = true, nonInteractive, savedRegion, cliEnv }) => {
|
|
6879
|
+
if (nonInteractive) {
|
|
6880
|
+
if (isFirebaseRegion(savedRegion)) return savedRegion;
|
|
6881
|
+
throw new _hot_updater_cli_tools.MissingInitInputsError(["HOT_UPDATER_FIREBASE_REGION"]);
|
|
6882
|
+
}
|
|
6883
|
+
let discoveredRegion;
|
|
6884
|
+
if (discoverExistingProject) {
|
|
6885
|
+
const functionsList = await execa("npx", [
|
|
6886
|
+
"firebase",
|
|
6887
|
+
"functions:list",
|
|
6888
|
+
"--json"
|
|
6889
|
+
], {
|
|
6890
|
+
cwd,
|
|
6891
|
+
env: cliEnv,
|
|
6892
|
+
reject: false
|
|
6893
|
+
});
|
|
6894
|
+
if (functionsList.exitCode === 0) {
|
|
6895
|
+
const parsed = JSON.parse(functionsList.stdout);
|
|
6896
|
+
if (typeof parsed === "object" && parsed !== null && "result" in parsed && Array.isArray(parsed.result)) {
|
|
6897
|
+
for (const entry of parsed.result) if (typeof entry === "object" && entry !== null && "id" in entry && entry.id === "hot-updater" && "region" in entry && typeof entry.region === "string") {
|
|
6898
|
+
discoveredRegion = entry.region;
|
|
6899
|
+
break;
|
|
6900
|
+
}
|
|
6901
|
+
}
|
|
6902
|
+
}
|
|
6903
|
+
}
|
|
6904
|
+
const initialRegion = isFirebaseRegion(savedRegion) ? savedRegion : isFirebaseRegion(discoveredRegion) ? discoveredRegion : REGIONS[0].value;
|
|
6905
|
+
const options = REGIONS.some((region) => region.value === initialRegion) ? REGIONS : [{
|
|
6906
|
+
value: initialRegion,
|
|
6907
|
+
label: `Existing (${initialRegion})`
|
|
6908
|
+
}, ...REGIONS];
|
|
6909
|
+
const selectedRegion = await _hot_updater_cli_tools.p.select({
|
|
6910
|
+
initialValue: initialRegion,
|
|
6911
|
+
message: initProvider.inputs.region.prompt.message,
|
|
6912
|
+
options
|
|
6913
|
+
});
|
|
6914
|
+
if (_hot_updater_cli_tools.p.isCancel(selectedRegion)) {
|
|
6915
|
+
_hot_updater_cli_tools.p.cancel("Operation cancelled.");
|
|
6916
|
+
process.exit(1);
|
|
6917
|
+
}
|
|
6918
|
+
return selectedRegion;
|
|
6919
|
+
};
|
|
6920
|
+
//#endregion
|
|
6714
6921
|
//#region iac/prepareTemplate.ts
|
|
6715
6922
|
const ensureExists = async (targetPath, description) => {
|
|
6716
6923
|
try {
|
|
@@ -6783,15 +6990,16 @@ const credential = admin.credential.applicationDefault();`.trim()
|
|
|
6783
6990
|
defaultOrNamespace: "admin"
|
|
6784
6991
|
}).setIntermediateCode(helperStatements.map((statement) => statement.code.trim()).join("\n\n")), { helperStatements });
|
|
6785
6992
|
};
|
|
6786
|
-
const setEnv = async ({ projectId, storageBucket, build }) => {
|
|
6993
|
+
const setEnv = async ({ applicationCredentials, projectId, storageBucket, build, region }) => {
|
|
6787
6994
|
await (0, _hot_updater_cli_tools.makeEnv)({
|
|
6788
|
-
|
|
6995
|
+
[initProvider.inputs.applicationCredentials.envKey]: {
|
|
6789
6996
|
comment: "Project Settings > Service Accounts > New Private Key > Download JSON",
|
|
6790
|
-
value: "your-credentials.json"
|
|
6997
|
+
value: applicationCredentials ?? "your-credentials.json"
|
|
6791
6998
|
},
|
|
6792
|
-
|
|
6999
|
+
[initProvider.inputs.projectId.envKey]: projectId,
|
|
7000
|
+
[initProvider.inputs.region.envKey]: region,
|
|
6793
7001
|
HOT_UPDATER_FIREBASE_STORAGE_BUCKET: storageBucket
|
|
6794
|
-
}, ".env.hotupdater", { preserveKeys: [
|
|
7002
|
+
}, ".env.hotupdater", { preserveKeys: applicationCredentials ? [] : [initProvider.inputs.applicationCredentials.envKey] });
|
|
6795
7003
|
_hot_updater_cli_tools.p.log.success("Firebase credentials have been successfully configured.");
|
|
6796
7004
|
try {
|
|
6797
7005
|
const configWriteResult = await (0, _hot_updater_cli_tools.writeHotUpdaterConfig)(getConfigScaffold(build));
|
|
@@ -6799,7 +7007,8 @@ const setEnv = async ({ projectId, storageBucket, build }) => {
|
|
|
6799
7007
|
else if (configWriteResult.status === "merged") _hot_updater_cli_tools.p.log.success("Configuration file 'hot-updater.config.ts' has been updated.");
|
|
6800
7008
|
else _hot_updater_cli_tools.p.log.warn(`Existing 'hot-updater.config.ts' was left unchanged: ${configWriteResult.reason}`);
|
|
6801
7009
|
} catch (error) {
|
|
6802
|
-
|
|
7010
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7011
|
+
console.error("Error writing configuration file:", message);
|
|
6803
7012
|
}
|
|
6804
7013
|
};
|
|
6805
7014
|
const handleError = (err) => {
|
|
@@ -6807,43 +7016,81 @@ const handleError = (err) => {
|
|
|
6807
7016
|
else if (err instanceof Error) _hot_updater_cli_tools.p.log.error(`Error occurred: ${err.message}`);
|
|
6808
7017
|
process.exit(1);
|
|
6809
7018
|
};
|
|
6810
|
-
const
|
|
7019
|
+
const createFirebaseProject = async ({ cliEnv, projectId }) => {
|
|
7020
|
+
if (!isFirebaseProjectId(projectId)) throw new Error(`Invalid Firebase project ID: ${projectId}`);
|
|
7021
|
+
try {
|
|
7022
|
+
await execa("npx", [
|
|
7023
|
+
"firebase",
|
|
7024
|
+
"projects:create",
|
|
7025
|
+
`--display-name=${projectId}`,
|
|
7026
|
+
"--non-interactive",
|
|
7027
|
+
"--",
|
|
7028
|
+
projectId
|
|
7029
|
+
], {
|
|
7030
|
+
env: cliEnv,
|
|
7031
|
+
stdio: "inherit"
|
|
7032
|
+
});
|
|
7033
|
+
} catch (error) {
|
|
7034
|
+
handleError(error instanceof Error ? error : new Error(String(error)));
|
|
7035
|
+
}
|
|
7036
|
+
_hot_updater_cli_tools.p.log.success("Firebase project created successfully");
|
|
7037
|
+
_hot_updater_cli_tools.p.log.step("Enable Firestore, Storage, and Billing before running init again:");
|
|
7038
|
+
_hot_updater_cli_tools.p.log.step((0, _hot_updater_cli_tools.link)(`https://console.firebase.google.com/project/${projectId}/firestore`));
|
|
7039
|
+
_hot_updater_cli_tools.p.log.step((0, _hot_updater_cli_tools.link)(`https://console.firebase.google.com/project/${projectId}/storage`));
|
|
7040
|
+
};
|
|
7041
|
+
const listProjects = async (nonInteractive = false, cliEnv) => {
|
|
6811
7042
|
try {
|
|
6812
7043
|
const projects = await execa("npx", [
|
|
6813
7044
|
"firebase",
|
|
6814
7045
|
"projects:list",
|
|
6815
|
-
"--json"
|
|
6816
|
-
|
|
7046
|
+
"--json",
|
|
7047
|
+
...nonInteractive ? ["--non-interactive"] : []
|
|
7048
|
+
], { env: cliEnv });
|
|
6817
7049
|
return JSON.parse(projects.stdout)?.result ?? [];
|
|
6818
|
-
} catch {
|
|
6819
|
-
|
|
7050
|
+
} catch (error) {
|
|
7051
|
+
if (nonInteractive) throw new _hot_updater_cli_tools.MissingInitInputsError(["Firebase CLI authentication (`firebase login`)"]);
|
|
7052
|
+
throw error;
|
|
6820
7053
|
}
|
|
6821
7054
|
};
|
|
6822
|
-
const initFirebaseUser = async (cwd) => {
|
|
6823
|
-
try {
|
|
6824
|
-
await execa("npx", ["firebase", "login"], {
|
|
6825
|
-
stdio: "inherit",
|
|
6826
|
-
shell: true
|
|
6827
|
-
});
|
|
6828
|
-
} catch (err) {
|
|
6829
|
-
handleError(err);
|
|
6830
|
-
}
|
|
6831
|
-
try {
|
|
7055
|
+
const initFirebaseUser = async (cwd, preferredProjectId, nonInteractive = false, cliEnv, resolveCliEnv) => {
|
|
7056
|
+
if (!cliEnv) try {
|
|
6832
7057
|
const authList = await execa("gcloud", [
|
|
6833
7058
|
"auth",
|
|
6834
7059
|
"list",
|
|
6835
7060
|
"--format=json"
|
|
6836
|
-
], {
|
|
6837
|
-
if (JSON.parse(authList.stdout).length === 0)
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
7061
|
+
], { env: cliEnv });
|
|
7062
|
+
if (JSON.parse(authList.stdout).length === 0) {
|
|
7063
|
+
if (nonInteractive) throw new _hot_updater_cli_tools.MissingInitInputsError(["active gcloud authentication (`gcloud auth login`)"]);
|
|
7064
|
+
await execa("gcloud", ["auth", "login"], {
|
|
7065
|
+
env: cliEnv,
|
|
7066
|
+
stdio: "inherit"
|
|
7067
|
+
});
|
|
7068
|
+
}
|
|
6841
7069
|
} catch (err) {
|
|
7070
|
+
if (err instanceof _hot_updater_cli_tools.MissingInitInputsError) throw err;
|
|
6842
7071
|
handleError(err);
|
|
6843
7072
|
}
|
|
6844
|
-
|
|
7073
|
+
let projects;
|
|
7074
|
+
try {
|
|
7075
|
+
projects = await listProjects(nonInteractive, cliEnv);
|
|
7076
|
+
} catch (error) {
|
|
7077
|
+
if (nonInteractive || cliEnv) throw error;
|
|
7078
|
+
try {
|
|
7079
|
+
await execa("npx", ["firebase", "login"], {
|
|
7080
|
+
env: cliEnv,
|
|
7081
|
+
stdio: "inherit"
|
|
7082
|
+
});
|
|
7083
|
+
projects = await listProjects(false, cliEnv);
|
|
7084
|
+
} catch (loginError) {
|
|
7085
|
+
handleError(loginError instanceof Error ? loginError : new Error(String(loginError)));
|
|
7086
|
+
}
|
|
7087
|
+
}
|
|
6845
7088
|
const createKey = `create/${Math.random().toString(36).substring(2, 15)}`;
|
|
6846
|
-
const
|
|
7089
|
+
const preferredProject = projects.find((project) => project.projectId === preferredProjectId);
|
|
7090
|
+
if (preferredProjectId && !preferredProject) _hot_updater_cli_tools.p.log.warn("Saved Firebase project was not found. Select a project again.");
|
|
7091
|
+
if (nonInteractive && !preferredProject) throw new _hot_updater_cli_tools.MissingInitInputsError(["HOT_UPDATER_FIREBASE_PROJECT_ID"]);
|
|
7092
|
+
const projectId = nonInteractive && preferredProject ? preferredProject.projectId : await _hot_updater_cli_tools.p.select({
|
|
7093
|
+
initialValue: preferredProject?.projectId ?? projects[0]?.projectId,
|
|
6847
7094
|
message: "Select a Firebase project",
|
|
6848
7095
|
options: [...projects.map((project) => ({
|
|
6849
7096
|
label: project.displayName,
|
|
@@ -6858,29 +7105,22 @@ const initFirebaseUser = async (cwd) => {
|
|
|
6858
7105
|
process.exit(1);
|
|
6859
7106
|
}
|
|
6860
7107
|
if (projectId === createKey) {
|
|
6861
|
-
const
|
|
7108
|
+
const prompt = initProvider.inputs.projectId.prompt;
|
|
7109
|
+
const newProjectId = await _hot_updater_cli_tools.p.text({
|
|
7110
|
+
...(0, _hot_updater_cli_tools.getInitProviderTextPromptValues)(prompt, preferredProjectId),
|
|
7111
|
+
message: prompt.message,
|
|
7112
|
+
validate: (value) => isFirebaseProjectId(value) ? void 0 : "Use 6-30 lowercase letters, numbers, or hyphens; start with a letter and end with a letter or number."
|
|
7113
|
+
});
|
|
6862
7114
|
if (_hot_updater_cli_tools.p.isCancel(newProjectId)) {
|
|
6863
7115
|
_hot_updater_cli_tools.p.log.error("Project ID is required");
|
|
6864
7116
|
process.exit(1);
|
|
6865
7117
|
}
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
newProjectId
|
|
6871
|
-
], {
|
|
6872
|
-
stdio: "inherit",
|
|
6873
|
-
shell: true
|
|
6874
|
-
});
|
|
6875
|
-
_hot_updater_cli_tools.p.log.success("Firebase project created successfully");
|
|
6876
|
-
_hot_updater_cli_tools.p.log.step("Please Go to the following links to enable Firestore and Storage and Billing");
|
|
6877
|
-
_hot_updater_cli_tools.p.log.step((0, _hot_updater_cli_tools.link)(`https://console.firebase.google.com/project/${newProjectId}/firestore`));
|
|
6878
|
-
_hot_updater_cli_tools.p.log.step((0, _hot_updater_cli_tools.link)(`https://console.firebase.google.com/project/${newProjectId}/storage`));
|
|
6879
|
-
} catch (err) {
|
|
6880
|
-
handleError(err);
|
|
6881
|
-
}
|
|
6882
|
-
process.exit(0);
|
|
7118
|
+
return {
|
|
7119
|
+
status: "create",
|
|
7120
|
+
projectId: newProjectId
|
|
7121
|
+
};
|
|
6883
7122
|
}
|
|
7123
|
+
const selectedProjectCliEnv = resolveCliEnv ? await resolveCliEnv(projectId) : cliEnv;
|
|
6884
7124
|
await _hot_updater_cli_tools.p.tasks([{
|
|
6885
7125
|
title: `Select Firebase project (${projectId})...`,
|
|
6886
7126
|
task: async () => {
|
|
@@ -6888,11 +7128,12 @@ const initFirebaseUser = async (cwd) => {
|
|
|
6888
7128
|
await execa("npx", [
|
|
6889
7129
|
"firebase",
|
|
6890
7130
|
"use",
|
|
6891
|
-
"--add",
|
|
6892
|
-
projectId
|
|
7131
|
+
...nonInteractive ? [] : ["--add"],
|
|
7132
|
+
projectId,
|
|
7133
|
+
...nonInteractive ? ["--non-interactive"] : []
|
|
6893
7134
|
], {
|
|
6894
7135
|
cwd,
|
|
6895
|
-
|
|
7136
|
+
env: selectedProjectCliEnv
|
|
6896
7137
|
});
|
|
6897
7138
|
} catch (error) {
|
|
6898
7139
|
if (error instanceof ExecaError) _hot_updater_cli_tools.p.log.error(error.stderr || error.stdout || error.message);
|
|
@@ -6909,7 +7150,7 @@ const initFirebaseUser = async (cwd) => {
|
|
|
6909
7150
|
`--project=${projectId}`,
|
|
6910
7151
|
"--format=json"
|
|
6911
7152
|
], {
|
|
6912
|
-
|
|
7153
|
+
env: selectedProjectCliEnv,
|
|
6913
7154
|
input: "N\n"
|
|
6914
7155
|
});
|
|
6915
7156
|
if (JSON.parse(databases.stdout).length === 0) {
|
|
@@ -6920,7 +7161,7 @@ const initFirebaseUser = async (cwd) => {
|
|
|
6920
7161
|
process.exit(1);
|
|
6921
7162
|
}
|
|
6922
7163
|
} catch (err) {
|
|
6923
|
-
handleError(err);
|
|
7164
|
+
handleError(err instanceof Error ? err : new Error(String(err)));
|
|
6924
7165
|
}
|
|
6925
7166
|
let storageBucket = null;
|
|
6926
7167
|
await _hot_updater_cli_tools.p.tasks([{
|
|
@@ -6932,7 +7173,7 @@ const initFirebaseUser = async (cwd) => {
|
|
|
6932
7173
|
"list",
|
|
6933
7174
|
`--project=${projectId}`,
|
|
6934
7175
|
"--format=json"
|
|
6935
|
-
], {
|
|
7176
|
+
], { env: selectedProjectCliEnv });
|
|
6936
7177
|
storageBucket = JSON.parse(buckets.stdout).find((bucket) => bucket.name === `${projectId}.firebasestorage.app` || bucket.name === `${projectId}.appspot.com`)?.name;
|
|
6937
7178
|
if (!storageBucket) {
|
|
6938
7179
|
_hot_updater_cli_tools.p.log.error("Storage Bucket not found");
|
|
@@ -6952,7 +7193,7 @@ const initFirebaseUser = async (cwd) => {
|
|
|
6952
7193
|
"describe",
|
|
6953
7194
|
projectId,
|
|
6954
7195
|
"--format=json"
|
|
6955
|
-
], {
|
|
7196
|
+
], { env: selectedProjectCliEnv });
|
|
6956
7197
|
const projectJson = JSON.parse(project.stdout);
|
|
6957
7198
|
const projectNumber = Number(projectJson.projectNumber);
|
|
6958
7199
|
if (Number.isNaN(projectNumber)) {
|
|
@@ -6960,6 +7201,7 @@ const initFirebaseUser = async (cwd) => {
|
|
|
6960
7201
|
process.exit(1);
|
|
6961
7202
|
}
|
|
6962
7203
|
return {
|
|
7204
|
+
status: "ready",
|
|
6963
7205
|
storageBucket,
|
|
6964
7206
|
projectNumber,
|
|
6965
7207
|
projectId
|
|
@@ -6978,88 +7220,6 @@ export default HotUpdater.wrap({
|
|
|
6978
7220
|
baseURL: "%%source%%",
|
|
6979
7221
|
updateStrategy: "appVersion", // or "fingerprint"
|
|
6980
7222
|
})(App);`;
|
|
6981
|
-
const REGIONS = [
|
|
6982
|
-
{
|
|
6983
|
-
value: "us-central1",
|
|
6984
|
-
label: "US Central (Iowa)"
|
|
6985
|
-
},
|
|
6986
|
-
{
|
|
6987
|
-
value: "us-east1",
|
|
6988
|
-
label: "US East (South Carolina)"
|
|
6989
|
-
},
|
|
6990
|
-
{
|
|
6991
|
-
value: "us-east4",
|
|
6992
|
-
label: "US East (Northern Virginia)"
|
|
6993
|
-
},
|
|
6994
|
-
{
|
|
6995
|
-
value: "us-west1",
|
|
6996
|
-
label: "US West (Oregon)"
|
|
6997
|
-
},
|
|
6998
|
-
{
|
|
6999
|
-
value: "us-west2",
|
|
7000
|
-
label: "US West (Los Angeles)"
|
|
7001
|
-
},
|
|
7002
|
-
{
|
|
7003
|
-
value: "us-west3",
|
|
7004
|
-
label: "US West (Salt Lake City)"
|
|
7005
|
-
},
|
|
7006
|
-
{
|
|
7007
|
-
value: "us-west4",
|
|
7008
|
-
label: "US West (Las Vegas)"
|
|
7009
|
-
},
|
|
7010
|
-
{
|
|
7011
|
-
value: "europe-west1",
|
|
7012
|
-
label: "Europe West (Belgium)"
|
|
7013
|
-
},
|
|
7014
|
-
{
|
|
7015
|
-
value: "europe-west2",
|
|
7016
|
-
label: "Europe West (London)"
|
|
7017
|
-
},
|
|
7018
|
-
{
|
|
7019
|
-
value: "europe-west3",
|
|
7020
|
-
label: "Europe West (Frankfurt)"
|
|
7021
|
-
},
|
|
7022
|
-
{
|
|
7023
|
-
value: "europe-west6",
|
|
7024
|
-
label: "Europe West (Zurich)"
|
|
7025
|
-
},
|
|
7026
|
-
{
|
|
7027
|
-
value: "asia-east1",
|
|
7028
|
-
label: "Asia East (Taiwan)"
|
|
7029
|
-
},
|
|
7030
|
-
{
|
|
7031
|
-
value: "asia-east2",
|
|
7032
|
-
label: "Asia East (Hong Kong)"
|
|
7033
|
-
},
|
|
7034
|
-
{
|
|
7035
|
-
value: "asia-northeast1",
|
|
7036
|
-
label: "Asia Northeast (Tokyo)"
|
|
7037
|
-
},
|
|
7038
|
-
{
|
|
7039
|
-
value: "asia-northeast2",
|
|
7040
|
-
label: "Asia Northeast (Osaka)"
|
|
7041
|
-
},
|
|
7042
|
-
{
|
|
7043
|
-
value: "asia-northeast3",
|
|
7044
|
-
label: "Asia Northeast (Seoul)"
|
|
7045
|
-
},
|
|
7046
|
-
{
|
|
7047
|
-
value: "asia-south1",
|
|
7048
|
-
label: "Asia South (Mumbai)"
|
|
7049
|
-
},
|
|
7050
|
-
{
|
|
7051
|
-
value: "asia-southeast1",
|
|
7052
|
-
label: "Asia Southeast (Singapore)"
|
|
7053
|
-
},
|
|
7054
|
-
{
|
|
7055
|
-
value: "asia-southeast2",
|
|
7056
|
-
label: "Asia Southeast (Jakarta)"
|
|
7057
|
-
},
|
|
7058
|
-
{
|
|
7059
|
-
value: "australia-southeast1",
|
|
7060
|
-
label: "Australia Southeast (Sydney)"
|
|
7061
|
-
}
|
|
7062
|
-
];
|
|
7063
7223
|
const getFirebaseRuntimePackageInfo = () => {
|
|
7064
7224
|
const firebasePackageRoot = path.default.dirname(require.resolve("@hot-updater/firebase/package.json"));
|
|
7065
7225
|
return {
|
|
@@ -7093,10 +7253,14 @@ const mergeIndexes = (originalIndexes, newIndexes) => {
|
|
|
7093
7253
|
fieldOverrides: merge(originalIndexes.fieldOverrides, newIndexes.fieldOverrides)
|
|
7094
7254
|
};
|
|
7095
7255
|
};
|
|
7096
|
-
const deployFirestore = async (cwd) => {
|
|
7097
|
-
const original = await execa("npx", [
|
|
7256
|
+
const deployFirestore = async (cwd, nonInteractive = false, cliEnv) => {
|
|
7257
|
+
const original = await execa("npx", [
|
|
7258
|
+
"firebase",
|
|
7259
|
+
"firestore:indexes",
|
|
7260
|
+
...nonInteractive ? ["--non-interactive"] : []
|
|
7261
|
+
], {
|
|
7098
7262
|
cwd,
|
|
7099
|
-
|
|
7263
|
+
env: cliEnv
|
|
7100
7264
|
});
|
|
7101
7265
|
let originalIndexes = {
|
|
7102
7266
|
indexes: [],
|
|
@@ -7107,7 +7271,12 @@ const deployFirestore = async (cwd) => {
|
|
|
7107
7271
|
indexes: [],
|
|
7108
7272
|
fieldOverrides: []
|
|
7109
7273
|
};
|
|
7110
|
-
} catch {
|
|
7274
|
+
} catch {
|
|
7275
|
+
originalIndexes = {
|
|
7276
|
+
indexes: [],
|
|
7277
|
+
fieldOverrides: []
|
|
7278
|
+
};
|
|
7279
|
+
}
|
|
7111
7280
|
const newIndexes = JSON.parse(await fs.default.promises.readFile(path.default.join(cwd, "firestore.indexes.json"), "utf-8"));
|
|
7112
7281
|
const mergedIndexes = mergeIndexes(originalIndexes, newIndexes);
|
|
7113
7282
|
await fs.default.promises.writeFile(path.default.join(cwd, "firestore.indexes.json"), JSON.stringify(mergedIndexes, null, 2));
|
|
@@ -7116,11 +7285,12 @@ const deployFirestore = async (cwd) => {
|
|
|
7116
7285
|
"firebase",
|
|
7117
7286
|
"deploy",
|
|
7118
7287
|
"--only",
|
|
7119
|
-
"firestore"
|
|
7288
|
+
"firestore",
|
|
7289
|
+
...nonInteractive ? ["--non-interactive"] : []
|
|
7120
7290
|
], {
|
|
7121
7291
|
cwd,
|
|
7122
|
-
|
|
7123
|
-
|
|
7292
|
+
env: cliEnv,
|
|
7293
|
+
stdio: "inherit"
|
|
7124
7294
|
});
|
|
7125
7295
|
} catch (e) {
|
|
7126
7296
|
if (e instanceof ExecaError) _hot_updater_cli_tools.p.log.error(e.stderr || e.stdout || e.message);
|
|
@@ -7128,17 +7298,18 @@ const deployFirestore = async (cwd) => {
|
|
|
7128
7298
|
process.exit(1);
|
|
7129
7299
|
}
|
|
7130
7300
|
};
|
|
7131
|
-
const deployFunctions = async (cwd) => {
|
|
7301
|
+
const deployFunctions = async (cwd, nonInteractive = false, cliEnv) => {
|
|
7132
7302
|
try {
|
|
7133
7303
|
await execa("npx", [
|
|
7134
7304
|
"firebase",
|
|
7135
7305
|
"deploy",
|
|
7136
7306
|
"--only",
|
|
7137
|
-
"functions"
|
|
7307
|
+
"functions",
|
|
7308
|
+
...nonInteractive ? ["--non-interactive"] : []
|
|
7138
7309
|
], {
|
|
7139
7310
|
cwd,
|
|
7140
|
-
|
|
7141
|
-
|
|
7311
|
+
env: cliEnv,
|
|
7312
|
+
stdio: "inherit"
|
|
7142
7313
|
});
|
|
7143
7314
|
} catch (e) {
|
|
7144
7315
|
if (e instanceof ExecaError) _hot_updater_cli_tools.p.log.error(e.stderr || e.stdout || e.message);
|
|
@@ -7146,7 +7317,7 @@ const deployFunctions = async (cwd) => {
|
|
|
7146
7317
|
process.exit(1);
|
|
7147
7318
|
}
|
|
7148
7319
|
};
|
|
7149
|
-
const printTemplate = async (projectId, region) => {
|
|
7320
|
+
const printTemplate = async (projectId, region, cliEnv) => {
|
|
7150
7321
|
try {
|
|
7151
7322
|
const { stdout } = await execa("gcloud", [
|
|
7152
7323
|
"functions",
|
|
@@ -7157,7 +7328,7 @@ const printTemplate = async (projectId, region) => {
|
|
|
7157
7328
|
"--region",
|
|
7158
7329
|
region,
|
|
7159
7330
|
"--format=json"
|
|
7160
|
-
], {
|
|
7331
|
+
], { env: cliEnv });
|
|
7161
7332
|
const parsedData = JSON.parse(stdout);
|
|
7162
7333
|
const functionUrl = `${parsedData?.serviceConfig?.uri ?? parsedData.url}/api/check-update`;
|
|
7163
7334
|
_hot_updater_cli_tools.p.note((0, _hot_updater_cli_tools.transformTemplate)(SOURCE_TEMPLATE, { source: functionUrl }));
|
|
@@ -7169,13 +7340,20 @@ const printTemplate = async (projectId, region) => {
|
|
|
7169
7340
|
};
|
|
7170
7341
|
const checkIfGcloudCliInstalled = async () => {
|
|
7171
7342
|
try {
|
|
7172
|
-
await execa("gcloud", ["--version"]
|
|
7343
|
+
await execa("gcloud", ["--version"]);
|
|
7173
7344
|
return true;
|
|
7174
7345
|
} catch {
|
|
7175
7346
|
return false;
|
|
7176
7347
|
}
|
|
7177
7348
|
};
|
|
7178
|
-
const runInit = async ({ build }) => {
|
|
7349
|
+
const runInit = async ({ build, envFile }) => {
|
|
7350
|
+
const nonInteractive = envFile !== void 0;
|
|
7351
|
+
const initEnvSources = await (0, _hot_updater_cli_tools.readHotUpdaterInitEnv)(process.cwd(), envFile);
|
|
7352
|
+
const { managedEnv } = initEnvSources;
|
|
7353
|
+
const savedInputs = resolveFirebaseInitInputs((0, _hot_updater_cli_tools.getHotUpdaterInitInputEnv)(initEnvSources, nonInteractive));
|
|
7354
|
+
assertFirebaseNonInteractiveInputs(savedInputs, nonInteractive);
|
|
7355
|
+
let applicationCredentials = savedInputs.applicationCredentials;
|
|
7356
|
+
const cliEnv = nonInteractive ? getFirebaseCliEnv(applicationCredentials) : void 0;
|
|
7179
7357
|
if (!await checkIfGcloudCliInstalled()) {
|
|
7180
7358
|
_hot_updater_cli_tools.p.log.error("gcloud CLI is not installed");
|
|
7181
7359
|
_hot_updater_cli_tools.p.log.step("Please go to the following link to install the gcloud CLI");
|
|
@@ -7185,22 +7363,61 @@ const runInit = async ({ build }) => {
|
|
|
7185
7363
|
const { tmpDir, removeTmpDir, functionsDir } = await prepareFirebaseTemplate(path.default.dirname(path.default.dirname(require.resolve("@hot-updater/firebase/functions"))));
|
|
7186
7364
|
const functionsIndexPath = path.default.join(functionsDir, "index.cjs");
|
|
7187
7365
|
const runtimePackageInfo = await syncFunctionsPackageJson(functionsDir);
|
|
7188
|
-
const initializeVariable = await initFirebaseUser(tmpDir)
|
|
7189
|
-
|
|
7366
|
+
const initializeVariable = await initFirebaseUser(tmpDir, savedInputs.projectId, nonInteractive, cliEnv, async (projectId) => {
|
|
7367
|
+
applicationCredentials = await inputFirebaseApplicationCredentials({
|
|
7368
|
+
applicationCredentials,
|
|
7369
|
+
nonInteractive,
|
|
7370
|
+
projectId
|
|
7371
|
+
});
|
|
7372
|
+
return cliEnv;
|
|
7373
|
+
});
|
|
7374
|
+
const currentRegion = await resolveFirebaseRegion({
|
|
7375
|
+
cwd: tmpDir,
|
|
7376
|
+
discoverExistingProject: initializeVariable.status === "ready",
|
|
7377
|
+
nonInteractive,
|
|
7378
|
+
savedRegion: savedInputs.region,
|
|
7379
|
+
cliEnv
|
|
7380
|
+
});
|
|
7381
|
+
const resolvedInputs = {
|
|
7382
|
+
...savedInputs,
|
|
7383
|
+
applicationCredentials: applicationCredentials || void 0,
|
|
7384
|
+
projectId: initializeVariable.projectId,
|
|
7385
|
+
region: currentRegion
|
|
7386
|
+
};
|
|
7387
|
+
const persistedInputs = (0, _hot_updater_cli_tools.getInitProviderEnvVars)({
|
|
7388
|
+
includeConsentInputs: await (0, _hot_updater_cli_tools.confirmInitInputPersistence)({
|
|
7389
|
+
existingEnv: managedEnv,
|
|
7390
|
+
inputs: resolvedInputs,
|
|
7391
|
+
nonInteractive,
|
|
7392
|
+
provider: initProvider
|
|
7393
|
+
}),
|
|
7394
|
+
inputs: resolvedInputs,
|
|
7395
|
+
provider: initProvider
|
|
7396
|
+
});
|
|
7397
|
+
if (initializeVariable.status === "create") {
|
|
7398
|
+
await createFirebaseProject({
|
|
7399
|
+
cliEnv,
|
|
7400
|
+
projectId: initializeVariable.projectId
|
|
7401
|
+
});
|
|
7402
|
+
await (0, _hot_updater_cli_tools.makeEnv)(persistedInputs);
|
|
7403
|
+
await removeTmpDir();
|
|
7404
|
+
return;
|
|
7405
|
+
}
|
|
7406
|
+
const functionsCode = (0, _hot_updater_cli_tools.transformEnv)(functionsIndexPath, { REGION: currentRegion });
|
|
7407
|
+
await fs.default.promises.writeFile(functionsIndexPath, functionsCode);
|
|
7190
7408
|
await setEnv({
|
|
7191
7409
|
projectId: initializeVariable.projectId,
|
|
7192
7410
|
storageBucket: initializeVariable.storageBucket,
|
|
7193
|
-
build
|
|
7411
|
+
build,
|
|
7412
|
+
region: currentRegion,
|
|
7413
|
+
applicationCredentials: persistedInputs[initProvider.inputs.applicationCredentials.envKey]
|
|
7194
7414
|
});
|
|
7195
7415
|
if (runtimePackageInfo.serverPackageVersion !== runtimePackageInfo.currentPackageVersion) _hot_updater_cli_tools.p.note(`Using ${_hot_updater_cli_tools.HOT_UPDATER_SERVER_PACKAGE_VERSION_ENV}=${runtimePackageInfo.serverPackageVersion} for Firebase functions deploy.`);
|
|
7196
7416
|
await _hot_updater_cli_tools.p.tasks([{
|
|
7197
7417
|
title: "Installing dependencies...",
|
|
7198
7418
|
task: async () => {
|
|
7199
7419
|
try {
|
|
7200
|
-
await execa("npm", ["install"], {
|
|
7201
|
-
cwd: functionsDir,
|
|
7202
|
-
shell: true
|
|
7203
|
-
});
|
|
7420
|
+
await execa("npm", ["install"], { cwd: functionsDir });
|
|
7204
7421
|
return "Installed dependencies";
|
|
7205
7422
|
} catch (error) {
|
|
7206
7423
|
if (error instanceof ExecaError) _hot_updater_cli_tools.p.log.error(error.stderr || error.stdout || error.message);
|
|
@@ -7208,59 +7425,20 @@ const runInit = async ({ build }) => {
|
|
|
7208
7425
|
process.exit(1);
|
|
7209
7426
|
}
|
|
7210
7427
|
}
|
|
7211
|
-
}, {
|
|
7212
|
-
title: "Checking existing functions and setting region",
|
|
7213
|
-
task: async () => {
|
|
7214
|
-
let isFunctionsExist = false;
|
|
7215
|
-
try {
|
|
7216
|
-
const { stdout } = await execa("npx", [
|
|
7217
|
-
"firebase",
|
|
7218
|
-
"functions:list",
|
|
7219
|
-
"--json"
|
|
7220
|
-
], {
|
|
7221
|
-
cwd: tmpDir,
|
|
7222
|
-
shell: true
|
|
7223
|
-
});
|
|
7224
|
-
const hotUpdater = (JSON.parse(stdout).result || []).find((fn) => fn.id === "hot-updater");
|
|
7225
|
-
if (hotUpdater?.region) {
|
|
7226
|
-
currentRegion = hotUpdater.region;
|
|
7227
|
-
isFunctionsExist = true;
|
|
7228
|
-
}
|
|
7229
|
-
} catch {}
|
|
7230
|
-
if (!isFunctionsExist) {
|
|
7231
|
-
const selectedRegion = await _hot_updater_cli_tools.p.select({
|
|
7232
|
-
message: "Select Region",
|
|
7233
|
-
options: REGIONS,
|
|
7234
|
-
initialValue: REGIONS[0].value
|
|
7235
|
-
});
|
|
7236
|
-
if (_hot_updater_cli_tools.p.isCancel(selectedRegion)) {
|
|
7237
|
-
_hot_updater_cli_tools.p.cancel("Operation cancelled.");
|
|
7238
|
-
process.exit(1);
|
|
7239
|
-
}
|
|
7240
|
-
currentRegion = selectedRegion;
|
|
7241
|
-
}
|
|
7242
|
-
if (!currentRegion) {
|
|
7243
|
-
_hot_updater_cli_tools.p.log.error("Region is not set");
|
|
7244
|
-
await removeTmpDir();
|
|
7245
|
-
process.exit(1);
|
|
7246
|
-
}
|
|
7247
|
-
const code = (0, _hot_updater_cli_tools.transformEnv)(functionsIndexPath, { REGION: currentRegion });
|
|
7248
|
-
await fs.default.promises.writeFile(functionsIndexPath, code);
|
|
7249
|
-
return `Using ${isFunctionsExist ? "existing" : "new"} functions in region: ${currentRegion}`;
|
|
7250
|
-
}
|
|
7251
7428
|
}]);
|
|
7252
|
-
await deployFirestore(tmpDir);
|
|
7253
|
-
await deployFunctions(tmpDir);
|
|
7429
|
+
await deployFirestore(tmpDir, nonInteractive, cliEnv);
|
|
7430
|
+
await deployFunctions(tmpDir, nonInteractive, cliEnv);
|
|
7254
7431
|
await _hot_updater_cli_tools.p.tasks([{
|
|
7255
7432
|
title: "Check IAM policy",
|
|
7256
7433
|
async task(message) {
|
|
7257
7434
|
const functionsList = await execa("npx", [
|
|
7258
7435
|
"firebase",
|
|
7259
7436
|
"functions:list",
|
|
7260
|
-
"--json"
|
|
7437
|
+
"--json",
|
|
7438
|
+
...nonInteractive ? ["--non-interactive"] : []
|
|
7261
7439
|
], {
|
|
7262
7440
|
cwd: tmpDir,
|
|
7263
|
-
|
|
7441
|
+
env: cliEnv
|
|
7264
7442
|
});
|
|
7265
7443
|
const account = (JSON.parse(functionsList.stdout).result || []).find((fn) => fn.id === "hot-updater")?.serviceAccount;
|
|
7266
7444
|
if (!account) {
|
|
@@ -7273,7 +7451,7 @@ const runInit = async ({ build }) => {
|
|
|
7273
7451
|
"get-iam-policy",
|
|
7274
7452
|
initializeVariable.projectId,
|
|
7275
7453
|
"--format=json"
|
|
7276
|
-
], {
|
|
7454
|
+
], { env: cliEnv });
|
|
7277
7455
|
if (!JSON.parse(checkIam.stdout).bindings.some((binding) => binding.role === "roles/iam.serviceAccountTokenCreator" && binding.members.includes(`serviceAccount:${account}`))) try {
|
|
7278
7456
|
message("Adding IAM Service Account Token Creator role to the service account");
|
|
7279
7457
|
await execa("gcloud", [
|
|
@@ -7283,8 +7461,8 @@ const runInit = async ({ build }) => {
|
|
|
7283
7461
|
`--member=serviceAccount:${account}`,
|
|
7284
7462
|
"--role=roles/iam.serviceAccountTokenCreator"
|
|
7285
7463
|
], {
|
|
7286
|
-
|
|
7287
|
-
|
|
7464
|
+
env: cliEnv,
|
|
7465
|
+
stdio: "inherit"
|
|
7288
7466
|
});
|
|
7289
7467
|
_hot_updater_cli_tools.p.log.success("IAM Service Account Token Creator role has been added to the service account");
|
|
7290
7468
|
} catch {
|
|
@@ -7301,10 +7479,10 @@ const runInit = async ({ build }) => {
|
|
|
7301
7479
|
await removeTmpDir();
|
|
7302
7480
|
process.exit(1);
|
|
7303
7481
|
}
|
|
7304
|
-
await printTemplate(initializeVariable.projectId, currentRegion);
|
|
7482
|
+
await printTemplate(initializeVariable.projectId, currentRegion, cliEnv);
|
|
7305
7483
|
await removeTmpDir();
|
|
7306
7484
|
_hot_updater_cli_tools.p.log.message(`Next step: ${(0, _hot_updater_cli_tools.link)("https://hot-updater.dev/docs/managed/firebase#step-3-generated-configurations")}`);
|
|
7307
|
-
_hot_updater_cli_tools.p.log.message("Next step: Change GOOGLE_APPLICATION_CREDENTIALS=your-credentials.json in .env file");
|
|
7485
|
+
if (!applicationCredentials) _hot_updater_cli_tools.p.log.message("Next step: Change GOOGLE_APPLICATION_CREDENTIALS=your-credentials.json in .env file");
|
|
7308
7486
|
_hot_updater_cli_tools.p.log.success("Done! 🎉");
|
|
7309
7487
|
};
|
|
7310
7488
|
//#endregion
|