"use strict";
exports.id = 1808;
exports.ids = [1808];
exports.modules = {

/***/ 221945:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


/*
Where Data is Stored:

We centralize here determination of all directories on the filesystem
where data is stored for any of the components of CoCalc, run in any way.

All information here must be determinable when this module is initialized,
e.g., from environment variables or heuristics involving the filesystem.
In particular, nothing here can be impacted by command line flags
or content of a database.
*/
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.logs = exports.secrets = exports.projects = exports.pgdatabase = exports.pghost = exports.pgdata = exports.pguser = exports.data = exports.root = void 0;
const DEFINITION = `CoCalc Environment Variables:
- root -- if COCALC_ROOT is set then it; otherwise use [cocalc-source]/src/.
- data -- if the environment variable DATA is set, use that.  Otherwise, use {root}/data
- pgdata -- if env var PGDATA is set, use that; otherwise, it is {data}/postgres: where data data is stored (if running locally)
- pghost - if env var PGHOST is set, use that; otherwise, it is {data}/postgres/socket: what database connects to
- projects -- If env var PROJECTS is set, use that; otherwise, it is {data}"/projects/[project_id]";
              This is where project home directories are (or shared files for share server), and it MUST
              contain the string "[project_id]".
- secrets -- if env var SECRETS is set, use that; otherwise, it is {data}/secrets:  where to store secrets
- logs -- if env var LOGS is set, use that; otherwise, {data}/logs:  directory in which to store logs
`;
const path_1 = __webpack_require__(371017);
function determineRootFromPath() {
    const cur = __dirname;
    const search = "/src/";
    const i = cur.lastIndexOf(search);
    const root = (0, path_1.resolve)(cur.slice(0, i + search.length - 1));
    process.env.COCALC_ROOT = root;
    return root;
}
exports.root = process.env.COCALC_ROOT ?? determineRootFromPath();
exports.data = process.env.DATA ?? (0, path_1.join)(exports.root, "data");
exports.pguser = process.env.PGUSER ?? "smc";
exports.pgdata = process.env.PGDATA ?? (0, path_1.join)(exports.data, "postgres");
exports.pghost = process.env.PGHOST ?? (0, path_1.join)(exports.pgdata, "socket");
exports.pgdatabase = process.env.SMC_DB ?? process.env.PGDATABASE ?? "smc";
exports.projects = process.env.PROJECTS ?? (0, path_1.join)(exports.data, "projects", "[project_id]");
exports.secrets = process.env.SECRETS ?? (0, path_1.join)(exports.data, "secrets");
exports.logs = process.env.LOGS ?? (0, path_1.join)(exports.data, "logs");
function sanityChecks() {
    // Do a sanity check on projects:
    if (!exports.projects.includes("[project_id]")) {
        throw Error(`${DEFINITION}\n\nenv variable PROJECTS must contain "[project_id]" but it is "${process.env.PROJECTS}"`);
    }
}
sanityChecks();
//# sourceMappingURL=data.js.map

/***/ }),

/***/ 227554:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


/*
Debug logger for any node.js server.

There is used both by the hub(s) and project(s).

This is an implementation of basically how winston works for us,
but using the vastly simpler super-popular debug module.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.setCounter = exports.getLogger = void 0;
// setting env var must come *BEFORE* debug is loaded the first time
process.env.DEBUG_HIDE_DATE = "yes"; // since we supply it ourselves
// otherwise, maybe stuff like this works: (debug as any).inspectOpts["hideDate"] = true;
const debug_1 = __importDefault(__webpack_require__(511050));
const fs_1 = __webpack_require__(657147);
const util_1 = __webpack_require__(473837);
const path_1 = __webpack_require__(371017);
const data_1 = __webpack_require__(221945);
const COCALC = (0, debug_1.default)("cocalc");
function myFormat(...args) {
    if (args.length > 1 && typeof args[0] == "string" && !args[0].includes("%")) {
        // This is something where we didn't use printf formatting.
        const v = [];
        for (const x of args) {
            try {
                v.push(typeof x == "object" ? JSON.stringify(x) : `${x}`);
            }
            catch (_) {
                // better to not crash everything just for logging
                v.push(`${x}`);
            }
        }
        return v.join(" ");
    }
    // use printf formatting.
    return (0, util_1.format)(...args);
}
function defaultTransports() {
    if (process.env.SMC_TEST) {
        return {};
    }
    else if (process.env.COCALC_DOCKER) {
        return { file: "/var/log/hub/log" };
    }
    else if (true) {
        return { console: true };
    }
    else {}
}
function initTransports() {
    if (!process.env.DEBUG) {
        // if DEBUG isn't set then the debug logger will be silent anyways.
        return;
    }
    const transports = defaultTransports();
    if (process.env.DEBUG_CONSOLE != null) {
        transports.console =
            process.env.DEBUG_CONSOLE != "no" && process.env.DEBUG_CONSOLE != "false";
    }
    if (process.env.DEBUG_FILE != null) {
        transports.file = process.env.DEBUG_FILE;
    }
    let fileStream;
    if (transports.file) {
        // ensure directory exists
        (0, fs_1.mkdirSync)((0, path_1.dirname)(transports.file), { recursive: true });
        // create the file stream; using a stream ensures
        // that everything is written in the right order with
        // no corruption/collision between different logging.
        fileStream = (0, fs_1.createWriteStream)(transports.file);
    }
    let firstLog = true;
    COCALC.log = (...args) => {
        if (!transports.file && !transports.console)
            return;
        if (firstLog && transports.file) {
            console.error(`***\n\nLogging to "${transports.file}"${transports.console ? " and console.error" : ""} via the debug module\nwith  DEBUG='${process.env.DEBUG}'.\nUse   DEBUG_FILE='path' and DEBUG_CONSOLE=[yes|no] to override.\nUsing DEBUG='cocalc:*,-cocalc:silly:*' to control log levels.\n\n***`);
            firstLog = false;
        }
        // Similar as in debug source code, except I stuck a timestamp
        // at the beginning, which I like... except also aware of
        // non-printf formatting.
        const line = `${new Date().toISOString()}: ${myFormat(...args)}\n`;
        if (transports.console) {
            // the console transport:
            console.error(line);
        }
        if (transports.file) {
            // the file transport
            fileStream.write(line);
        }
    };
}
initTransports();
const DEBUGGERS = {
    error: COCALC.extend("error"),
    warn: COCALC.extend("warn"),
    info: COCALC.extend("info"),
    http: COCALC.extend("http"),
    verbose: COCALC.extend("verbose"),
    debug: COCALC.extend("debug"),
    silly: COCALC.extend("silly"),
};
const LEVELS = [
    "error",
    "warn",
    "info",
    "http",
    "verbose",
    "debug",
    "silly",
];
class Logger {
    constructor(name) {
        this.debuggers = {};
        this.name = name;
        for (const level of LEVELS) {
            this.debuggers[level] = DEBUGGERS[level].extend(name);
            this[level] = (...args) => {
                this.counter("error");
                // @ts-ignore
                this.debuggers[level](...args);
            };
        }
    }
    extend(name) {
        return new Logger(`${this.name}:${name}`);
    }
    counter(level) {
        if (counter == null)
            return;
        counter.labels(this.name, level).inc(1);
    }
}
const cache = {};
function getLogger(name) {
    if (cache[name] != null) {
        return cache[name];
    }
    // smash it over since we build Logger pretty generically so typescript
    // doesn't get it.  But we care that all *client* code uses the WinstonLogger
    // interface.
    return (cache[name] = new Logger(name));
}
exports["default"] = getLogger;
exports.getLogger = getLogger;
let counter = undefined;
function setCounter(f) {
    counter = f;
}
exports.setCounter = setCounter;
//# sourceMappingURL=logger.js.map

/***/ }),

/***/ 789615:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


/*
 *  This file is part of CoCalc: Copyright © 2022 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.STATEMENT_TIMEOUT_MS = void 0;
// Constants related to the database.
const logger_1 = __importDefault(__webpack_require__(227554));
const L = (0, logger_1.default)("db:consts");
/**
 * this is a limit for each query, unless timeout_s is specified.
 * https://postgresqlco.nf/en/doc/param/statement_timeout/
 */
exports.STATEMENT_TIMEOUT_MS = 1000 *
    (process.env.PG_STATEMENT_TIMEOUT_S
        ? parseInt(process.env.PG_STATEMENT_TIMEOUT_S)
        : 30);
L.debug(`STATEMENT_TIMEOUT_MS=${exports.STATEMENT_TIMEOUT_MS}ms`);
//# sourceMappingURL=consts.js.map

/***/ }),

/***/ 755376:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


/*
 *  This file is part of CoCalc: Copyright © 2021 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
/*
Caches queries for a certain amount of time.
Also, if there are multiple queries coming in
at the same time for the same thing, only
one actually goes to the database.

IMPORTANT: This *only* caches a query if the query actually
returns at least one row.  If the query returns nothing,
that fact is not cached.  This is usually what we want, e.g.,
if somebody access https://cocalc.com/wstein/myproject, and
notices that myproject isn't the set name, then they may
set it and immediately try  https://cocalc.com/wstein/myproject again.
In that case, we don't want to the cache to mean that they don't
see the page for a while. On the other hand, if querying for the
project that myproject resolves to is cached for a minute that is
fine, since this would only be a problem when they change the name
of multiple projects.
*/
const lru_cache_1 = __importDefault(__webpack_require__(35240));
const hof_1 = __webpack_require__(111735);
const pool_1 = __importDefault(__webpack_require__(63248));
const logger_1 = __importDefault(__webpack_require__(227554));
const L = (0, logger_1.default)("db:pool:cached");
const MAX_AGE_S = {
    short: 5,
    medium: 15,
    long: 30,
    minutes: 10 * 60,
    infinite: 60 * 60 * 24 * 365, // effectively forever; e.g., getting path from share id is really just a reversed sha1 hash, so can't change.
};
const caches = new Map();
for (const length in MAX_AGE_S) {
    caches[length] = new lru_cache_1.default({
        max: 1000,
        maxAge: 1000 * MAX_AGE_S[length],
    });
}
const cachedQuery = (0, hof_1.reuseInFlight)(async (length, ...args) => {
    const cache = caches[length];
    if (cache == null) {
        throw Error(`invalid cache "${length}"`);
    }
    const key = JSON.stringify(args);
    if (cache.has(key)) {
        // console.log(`YES - using cache for ${key}`);
        return cache.get(key);
    }
    // console.log(`NOT using cache for ${key}`);
    const pool = (0, pool_1.default)();
    try {
        // @ts-ignore - no clue how to typescript this.
        const result = await pool.query(...args);
        if (result.rows.length > 0) {
            // We only cache query if it returned something.
            cache.set(key, result);
        }
        return result;
    }
    catch (err) {
        L.error(`cachedQuery error: ${err}`);
        throw err;
    }
});
function getCachedPool(length) {
    return {
        query: async (...args) => await cachedQuery(length, ...args),
    }; // obviously not really a Pool, but is enough for what we're doing.
}
exports["default"] = getCachedPool;
//# sourceMappingURL=cached.js.map

/***/ }),

/***/ 541808:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.timeInSeconds = exports.getClient = void 0;
const pool_1 = __importStar(__webpack_require__(63248));
Object.defineProperty(exports, "getClient", ({ enumerable: true, get: function () { return pool_1.getClient; } }));
exports["default"] = pool_1.default;
var util_1 = __webpack_require__(258813);
Object.defineProperty(exports, "timeInSeconds", ({ enumerable: true, get: function () { return util_1.timeInSeconds; } }));
//# sourceMappingURL=index.js.map

/***/ }),

/***/ 184457:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
const path_1 = __webpack_require__(371017);
const data_1 = __webpack_require__(221945);
const fs_1 = __webpack_require__(657147);
function dbPassword() {
    const filename = (0, path_1.join)(data_1.secrets, "postgres");
    try {
        // fine to use sync, since reading db password happens only on startup
        return (0, fs_1.readFileSync)(filename).toString().trim();
    }
    catch {
        return undefined;
    }
}
exports["default"] = dbPassword;
//# sourceMappingURL=password.js.map

/***/ }),

/***/ 63248:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


/*
 *  This file is part of CoCalc: Copyright © 2021 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getClient = void 0;
const data_1 = __webpack_require__(221945);
const pg_1 = __webpack_require__(810758);
const logger_1 = __webpack_require__(227554);
const consts_1 = __webpack_require__(789615);
const cached_1 = __importDefault(__webpack_require__(755376));
const password_1 = __importDefault(__webpack_require__(184457));
const L = (0, logger_1.getLogger)("db:pool");
__exportStar(__webpack_require__(258813), exports);
let pool = undefined;
function getPool(cacheLength) {
    if (cacheLength != null) {
        return (0, cached_1.default)(cacheLength);
    }
    if (pool == null) {
        L.debug(`creating a new Pool(host:${data_1.pghost}, database:${data_1.pgdatabase}, user:${data_1.pguser}, statement_timeout:${consts_1.STATEMENT_TIMEOUT_MS}ms)`);
        pool = new pg_1.Pool({
            password: (0, password_1.default)(),
            user: data_1.pguser,
            host: data_1.pghost,
            database: data_1.pgdatabase,
            statement_timeout: consts_1.STATEMENT_TIMEOUT_MS, // fixes https://github.com/sagemathinc/cocalc/issues/6014
        });
    }
    return pool;
}
exports["default"] = getPool;
function getClient() {
    return new pg_1.Client({ password: (0, password_1.default)(), user: data_1.pguser, host: data_1.pghost, database: data_1.pgdatabase });
}
exports.getClient = getClient;
//# sourceMappingURL=pool.js.map

/***/ }),

/***/ 258813:
/***/ ((__unused_webpack_module, exports) => {


/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.expireTime = exports.timeInSeconds = void 0;
// Postgres 14 is different than 13 an earlier.
// extract(epoch from timestamp) returns a "numeric", which is converted to a string by the pg driver.
// we convert this explicitly to a floating point number to get the ms since epoch.
// Note: JavaScript's new Date(...) has no hesitation converting from a float.
function timeInSeconds(field, asField) {
    return ` (EXTRACT(EPOCH FROM ${field})*1000)::FLOAT as ${asField ?? field} `;
}
exports.timeInSeconds = timeInSeconds;
// Given number of seconds **in the future**.
function expireTime(ttl_s = 0) {
    return new Date(new Date().valueOf() + ttl_s * 1000);
}
exports.expireTime = expireTime;
//# sourceMappingURL=util.js.map

/***/ })

};
;