GSI - Employe Self Service Mobile
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

417 lines
20 KiB

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createServerResponseProxy = exports.prepareFrameworks = exports.findDependency = exports.discover = exports.relativeRequire = exports.WebFrameworks = exports.NODE_VERSION = exports.DEFAULT_REGION = exports.FIREBASE_ADMIN_VERSION = exports.FIREBASE_FUNCTIONS_VERSION = exports.FIREBASE_FRAMEWORKS_VERSION = void 0;
const path_1 = require("path");
const process_1 = require("process");
const child_process_1 = require("child_process");
const fs_1 = require("fs");
const url_1 = require("url");
const http_1 = require("http");
const promises_1 = require("fs/promises");
const fs_extra_1 = require("fs-extra");
const clc = require("colorette");
const process = require("node:process");
const semver = require("semver");
const projectUtils_1 = require("../projectUtils");
const config_1 = require("../hosting/config");
const api_1 = require("../hosting/api");
const apps_1 = require("../management/apps");
const prompt_1 = require("../prompt");
const types_1 = require("../emulator/types");
const defaultCredentials_1 = require("../defaultCredentials");
const auth_1 = require("../auth");
const functionsEmulatorShared_1 = require("../emulator/functionsEmulatorShared");
const constants_1 = require("../emulator/constants");
const error_1 = require("../error");
const requireHostingSite_1 = require("../requireHostingSite");
const experiments = require("../experiments");
const ensureTargeted_1 = require("../functions/ensureTargeted");
const implicitInit_1 = require("../hosting/implicitInit");
const { dynamicImport } = require(true && "../dynamicImport");
const SupportLevelWarnings = {
["experimental"]: clc.yellow(`This is an experimental integration, proceed with caution.`),
["community-supported"]: clc.yellow(`This is a community-supported integration, support is best effort.`),
};
exports.FIREBASE_FRAMEWORKS_VERSION = "^0.6.0";
exports.FIREBASE_FUNCTIONS_VERSION = "^3.23.0";
exports.FIREBASE_ADMIN_VERSION = "^11.0.1";
exports.DEFAULT_REGION = "us-central1";
exports.NODE_VERSION = parseInt(process.versions.node, 10).toString();
const DEFAULT_FIND_DEP_OPTIONS = {
cwd: process.cwd(),
omitDev: true,
};
const NPM_COMMAND = process.platform === "win32" ? "npm.cmd" : "npm";
exports.WebFrameworks = Object.fromEntries((0, fs_1.readdirSync)(__dirname)
.filter((path) => (0, fs_1.statSync)((0, path_1.join)(__dirname, path)).isDirectory())
.map((path) => [path, require((0, path_1.join)(__dirname, path))])
.filter(([, obj]) => obj.name && obj.discover && obj.build && obj.type !== undefined && obj.support));
function relativeRequire(dir, mod) {
try {
const path = require.resolve(mod, { paths: [dir] });
if ((0, path_1.extname)(path) === ".mjs") {
return dynamicImport((0, url_1.pathToFileURL)(path).toString());
}
else {
return require(path);
}
}
catch (e) {
const path = (0, path_1.relative)(process.cwd(), dir);
console.error(`Could not load dependency ${mod} in ${path.startsWith("..") ? path : `./${path}`}, have you run \`npm install\`?`);
throw e;
}
}
exports.relativeRequire = relativeRequire;
async function discover(dir, warn = true) {
const allFrameworkTypes = [
...new Set(Object.values(exports.WebFrameworks).map(({ type }) => type)),
].sort();
for (const discoveryType of allFrameworkTypes) {
const frameworksDiscovered = [];
for (const framework in exports.WebFrameworks) {
if (exports.WebFrameworks[framework]) {
const { discover, type } = exports.WebFrameworks[framework];
if (type !== discoveryType)
continue;
const result = await discover(dir);
if (result)
frameworksDiscovered.push(Object.assign({ framework }, result));
}
}
if (frameworksDiscovered.length > 1) {
if (warn)
console.error("Multiple conflicting frameworks discovered.");
return;
}
if (frameworksDiscovered.length === 1)
return frameworksDiscovered[0];
}
if (warn)
console.warn("Could not determine the web framework in use.");
return;
}
exports.discover = discover;
function scanDependencyTree(searchingFor, dependencies = {}) {
for (const [name, dependency] of Object.entries(dependencies)) {
if (name === searchingFor)
return dependency;
const result = scanDependencyTree(searchingFor, dependency.dependencies);
if (result)
return result;
}
return;
}
function findDependency(name, options = {}) {
const { cwd, depth, omitDev } = Object.assign(Object.assign({}, DEFAULT_FIND_DEP_OPTIONS), options);
const env = Object.assign({}, process.env);
delete env.NODE_ENV;
const result = (0, child_process_1.spawnSync)(NPM_COMMAND, [
"list",
name,
"--json",
...(omitDev ? ["--omit", "dev"] : []),
...(depth === undefined ? [] : ["--depth", depth.toString(10)]),
], { cwd, env });
if (!result.stdout)
return;
const json = JSON.parse(result.stdout.toString());
return scanDependencyTree(name, json.dependencies);
}
exports.findDependency = findDependency;
async function prepareFrameworks(targetNames, context, options, emulators = []) {
var _a;
var _b, _c, _d, _e;
const nodeVersion = process.version;
if (!semver.satisfies(nodeVersion, ">=16.0.0")) {
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.`);
}
const project = (0, projectUtils_1.needProjectId)(context);
const { projectRoot } = options;
const account = (0, auth_1.getProjectDefaultAccount)(projectRoot);
if (!options.site) {
try {
await (0, requireHostingSite_1.requireHostingSite)(options);
}
catch (_f) {
options.site = project;
}
}
const configs = (0, config_1.hostingConfig)(options);
let firebaseDefaults = undefined;
if (configs.length === 0) {
return;
}
for (const config of configs) {
const { source, site, public: publicDir } = config;
if (!source) {
continue;
}
config.rewrites || (config.rewrites = []);
config.redirects || (config.redirects = []);
config.headers || (config.headers = []);
(_a = config.cleanUrls) !== null && _a !== void 0 ? _a : (config.cleanUrls = true);
const dist = (0, path_1.join)(projectRoot, ".firebase", site);
const hostingDist = (0, path_1.join)(dist, "hosting");
const functionsDist = (0, path_1.join)(dist, "functions");
if (publicDir) {
throw new Error(`hosting.public and hosting.source cannot both be set in firebase.json`);
}
const getProjectPath = (...args) => (0, path_1.join)(projectRoot, source, ...args);
const functionName = `ssr${site.toLowerCase().replace(/-/g, "")}`;
const usesFirebaseAdminSdk = !!findDependency("firebase-admin", { cwd: getProjectPath() });
const usesFirebaseJsSdk = !!findDependency("@firebase/app", { cwd: getProjectPath() });
if (usesFirebaseAdminSdk) {
process.env.GOOGLE_CLOUD_PROJECT = project;
if (account && !process.env.GOOGLE_APPLICATION_CREDENTIALS) {
const defaultCredPath = await (0, defaultCredentials_1.getCredentialPathAsync)(account);
if (defaultCredPath)
process.env.GOOGLE_APPLICATION_CREDENTIALS = defaultCredPath;
}
}
emulators.forEach((info) => {
if (usesFirebaseAdminSdk) {
if (info.name === types_1.Emulators.FIRESTORE)
process.env[constants_1.Constants.FIRESTORE_EMULATOR_HOST] = (0, functionsEmulatorShared_1.formatHost)(info);
if (info.name === types_1.Emulators.AUTH)
process.env[constants_1.Constants.FIREBASE_AUTH_EMULATOR_HOST] = (0, functionsEmulatorShared_1.formatHost)(info);
if (info.name === types_1.Emulators.DATABASE)
process.env[constants_1.Constants.FIREBASE_DATABASE_EMULATOR_HOST] = (0, functionsEmulatorShared_1.formatHost)(info);
if (info.name === types_1.Emulators.STORAGE)
process.env[constants_1.Constants.FIREBASE_STORAGE_EMULATOR_HOST] = (0, functionsEmulatorShared_1.formatHost)(info);
}
if (usesFirebaseJsSdk && types_1.EMULATORS_SUPPORTED_BY_USE_EMULATOR.includes(info.name)) {
firebaseDefaults || (firebaseDefaults = {});
firebaseDefaults.emulatorHosts || (firebaseDefaults.emulatorHosts = {});
firebaseDefaults.emulatorHosts[info.name] = (0, functionsEmulatorShared_1.formatHost)(info);
}
});
let firebaseConfig = null;
if (usesFirebaseJsSdk) {
const sites = await (0, api_1.listSites)(project);
const selectedSite = sites.find((it) => it.name && it.name.split("/").pop() === site);
if (selectedSite) {
const { appId } = selectedSite;
if (appId) {
firebaseConfig = await (0, apps_1.getAppConfig)(appId, apps_1.AppPlatform.WEB);
firebaseDefaults || (firebaseDefaults = {});
firebaseDefaults.config = firebaseConfig;
}
else {
const defaultConfig = await (0, implicitInit_1.implicitInit)(options);
if (defaultConfig.json) {
console.warn(`No Firebase app associated with site ${site}, injecting project default config.
You can link a Web app to a Hosting site here https://console.firebase.google.com/project/${project}/settings/general/web`);
firebaseDefaults || (firebaseDefaults = {});
firebaseDefaults.config = JSON.parse(defaultConfig.json);
}
else {
console.warn(`No Firebase app associated with site ${site}, unable to provide authenticated server context.
You can link a Web app to a Hosting site here https://console.firebase.google.com/project/${project}/settings/general/web`);
if (!options.nonInteractive) {
const continueDeploy = await (0, prompt_1.promptOnce)({
type: "confirm",
default: true,
message: "Would you like to continue with the deploy?",
});
if (!continueDeploy)
(0, process_1.exit)(1);
}
}
}
}
}
if (firebaseDefaults)
process.env.__FIREBASE_DEFAULTS__ = JSON.stringify(firebaseDefaults);
const results = await discover(getProjectPath());
if (!results)
throw new Error("Epic fail.");
const { framework, mayWantBackend, publicDirectory } = results;
const { build, ɵcodegenPublicDirectory, ɵcodegenFunctionsDirectory: codegenProdModeFunctionsDirectory, getDevModeHandle, name, support, } = exports.WebFrameworks[framework];
console.log(`Detected a ${name} codebase. ${SupportLevelWarnings[support] || ""}\n`);
const isDevMode = context._name === "serve" || context._name === "emulators:start";
const hostingEmulatorInfo = emulators.find((e) => e.name === types_1.Emulators.HOSTING);
const devModeHandle = isDevMode &&
getDevModeHandle &&
(await getDevModeHandle(getProjectPath(), hostingEmulatorInfo));
let codegenFunctionsDirectory;
if (devModeHandle) {
config.public = (0, path_1.relative)(projectRoot, publicDirectory);
options.frameworksDevModeHandle = devModeHandle;
if (mayWantBackend && firebaseDefaults) {
codegenFunctionsDirectory = codegenDevModeFunctionsDirectory;
}
}
else {
const { wantsBackend = false, rewrites = [], redirects = [], headers = [], } = (await build(getProjectPath())) || {};
config.rewrites.push(...rewrites);
config.redirects.push(...redirects);
config.headers.push(...headers);
if (await (0, fs_extra_1.pathExists)(hostingDist))
await (0, promises_1.rm)(hostingDist, { recursive: true });
await (0, fs_extra_1.mkdirp)(hostingDist);
await ɵcodegenPublicDirectory(getProjectPath(), hostingDist);
config.public = (0, path_1.relative)(projectRoot, hostingDist);
if (wantsBackend)
codegenFunctionsDirectory = codegenProdModeFunctionsDirectory;
}
config.webFramework = `${framework}${codegenFunctionsDirectory ? "_ssr" : ""}`;
if (codegenFunctionsDirectory) {
if (firebaseDefaults)
firebaseDefaults._authTokenSyncURL = "/__session";
const rewrite = {
source: "**",
function: {
functionId: functionName,
},
};
if (experiments.isEnabled("pintags")) {
rewrite.function.pinTag = true;
}
config.rewrites.push(rewrite);
const codebase = `firebase-frameworks-${site}`;
const existingFunctionsConfig = options.config.get("functions")
? [].concat(options.config.get("functions"))
: [];
options.config.set("functions", [
...existingFunctionsConfig,
{
source: (0, path_1.relative)(projectRoot, functionsDist),
codebase,
},
]);
if (!targetNames.includes("functions")) {
targetNames.unshift("functions");
}
if (options.only) {
options.only = (0, ensureTargeted_1.ensureTargeted)(options.only, codebase);
}
if (await (0, fs_extra_1.pathExists)(functionsDist)) {
const functionsDistStat = await (0, fs_extra_1.stat)(functionsDist);
if (functionsDistStat === null || functionsDistStat === void 0 ? void 0 : functionsDistStat.isDirectory()) {
const files = await (0, promises_1.readdir)(functionsDist);
for (const file of files) {
if (file !== "node_modules" && file !== "package-lock.json")
await (0, promises_1.rm)((0, path_1.join)(functionsDist, file), { recursive: true });
}
}
else {
await (0, promises_1.rm)(functionsDist);
}
}
else {
await (0, fs_extra_1.mkdirp)(functionsDist);
}
const { packageJson, bootstrapScript, frameworksEntry = framework, } = await codegenFunctionsDirectory(getProjectPath(), functionsDist);
await (0, promises_1.writeFile)((0, path_1.join)(functionsDist, "functions.yaml"), JSON.stringify({
endpoints: {
[functionName]: {
platform: "gcfv2",
region: [exports.DEFAULT_REGION],
labels: {},
httpsTrigger: {},
entryPoint: "ssr",
},
},
specVersion: "v1alpha1",
requiredAPIs: [],
}, null, 2));
packageJson.main = "server.js";
delete packageJson.devDependencies;
packageJson.dependencies || (packageJson.dependencies = {});
(_b = packageJson.dependencies)["firebase-frameworks"] || (_b["firebase-frameworks"] = exports.FIREBASE_FRAMEWORKS_VERSION);
(_c = packageJson.dependencies)["firebase-functions"] || (_c["firebase-functions"] = exports.FIREBASE_FUNCTIONS_VERSION);
(_d = packageJson.dependencies)["firebase-admin"] || (_d["firebase-admin"] = exports.FIREBASE_ADMIN_VERSION);
packageJson.engines || (packageJson.engines = {});
(_e = packageJson.engines).node || (_e.node = exports.NODE_VERSION);
await (0, promises_1.writeFile)((0, path_1.join)(functionsDist, "package.json"), JSON.stringify(packageJson, null, 2));
await (0, promises_1.writeFile)((0, path_1.join)(functionsDist, ".env"), `__FIREBASE_FRAMEWORKS_ENTRY__=${frameworksEntry}
${firebaseDefaults ? `__FIREBASE_DEFAULTS__=${JSON.stringify(firebaseDefaults)}\n` : ""}`);
await (0, promises_1.copyFile)(getProjectPath("package-lock.json"), (0, path_1.join)(functionsDist, "package-lock.json")).catch(() => {
});
if (await (0, fs_extra_1.pathExists)(getProjectPath(".npmrc"))) {
await (0, promises_1.copyFile)(getProjectPath(".npmrc"), (0, path_1.join)(functionsDist, ".npmrc"));
}
(0, child_process_1.execSync)(`${NPM_COMMAND} i --omit dev --no-audit`, {
cwd: functionsDist,
stdio: "inherit",
});
if (bootstrapScript)
await (0, promises_1.writeFile)((0, path_1.join)(functionsDist, "bootstrap.js"), bootstrapScript);
await (0, promises_1.writeFile)((0, path_1.join)(functionsDist, "server.js"), `const { onRequest } = require('firebase-functions/v2/https');
const server = import('firebase-frameworks');
exports.ssr = onRequest((req, res) => server.then(it => it.handle(req, res)));
`);
}
else {
config.rewrites.push({
source: "**",
destination: "/index.html",
});
}
if (firebaseDefaults) {
const encodedDefaults = Buffer.from(JSON.stringify(firebaseDefaults)).toString("base64url");
const expires = new Date(new Date().getTime() + 60000000000);
const sameSite = "Strict";
const path = `/`;
config.headers.push({
source: "**/*.js",
headers: [
{
key: "Set-Cookie",
value: `__FIREBASE_DEFAULTS__=${encodedDefaults}; SameSite=${sameSite}; Expires=${expires.toISOString()}; Path=${path};`,
},
],
});
}
}
}
exports.prepareFrameworks = prepareFrameworks;
function codegenDevModeFunctionsDirectory() {
const packageJson = {};
return Promise.resolve({ packageJson, frameworksEntry: "_devMode" });
}
function createServerResponseProxy(req, res, next) {
const proxiedRes = new http_1.ServerResponse(req);
const buffer = [];
proxiedRes.write = new Proxy(proxiedRes.write.bind(proxiedRes), {
apply: (target, thisArg, args) => {
target.call(thisArg, ...args);
buffer.push(["write", args]);
},
});
proxiedRes.setHeader = new Proxy(proxiedRes.setHeader.bind(proxiedRes), {
apply: (target, thisArg, args) => {
target.call(thisArg, ...args);
buffer.push(["setHeader", args]);
},
});
proxiedRes.removeHeader = new Proxy(proxiedRes.removeHeader.bind(proxiedRes), {
apply: (target, thisArg, args) => {
target.call(thisArg, ...args);
buffer.push(["removeHeader", args]);
},
});
proxiedRes.writeHead = new Proxy(proxiedRes.writeHead.bind(proxiedRes), {
apply: (target, thisArg, args) => {
target.call(thisArg, ...args);
buffer.push(["writeHead", args]);
},
});
proxiedRes.end = new Proxy(proxiedRes.end.bind(proxiedRes), {
apply: (target, thisArg, args) => {
target.call(thisArg, ...args);
if (proxiedRes.statusCode === 404) {
next();
}
else {
for (const [fn, args] of buffer) {
res[fn](...args);
}
res.end(...args);
}
},
});
return proxiedRes;
}
exports.createServerResponseProxy = createServerResponseProxy;