/**
* Various tools.
*
* @module utils
* @license Apache-2.0
* @copyright Mat. 2018-present
*/
import { handleException } from "../func/tools";
import { quote } from "../string/transform";
import { access } from "../struct/data";
import {
isObject,
isString,
} from "../type/check";
import { toBool } from "../type/conv";
import {
dependencies,
description,
homepage,
license,
name,
version,
} from "../../dist/package.json";
/**
* Determine runtime environment (is it development or not?).
* `devEnv() -> true/false`
*
* When `strict` is not set to `true` then "development environment"
* can be simulated by storing value of any type under "dev" key
* in browser's sessionStorage, e.g. `sessionStorage[dev] = true`.
*
* @function devEnv
* @param {Boolean} [strict=false]
* @returns {Boolean}
*/
export const devEnv = (strict = false) =>
(
// if you're in browser and not in strict mode
// then check if there is "dev" key in `sessionStorage`
isBrowser() && !strict ?
handleException(
() => Object.prototype.hasOwnProperty.call(
sessionStorage, "dev",
),
() => false,
) : false
) || (
// or if there is a `string` under `process.env.NODE_ENV`
// and it is not equal to "production"
isString(access(getProcess(), ["env", "NODE_ENV"])) &&
access(getProcess(), ["env", "NODE_ENV"]) !== "production"
) || (
// or, maybe, you're not in browser
// and there is no `string` under `process.env.NODE_ENV`,
// which happens in "bare" node.js console
!isBrowser() &&
!isString(access(getProcess(), ["env", "NODE_ENV"]))
) || (
// or... you're in babel context and appropriate env. var is set
!isBrowser() &&
access(
getProcess(), ["env", "BABEL_ENV"], "production",
) !== "production"
);
/**
* Get useful library configuration variables.
*
* @function getLibConfig
* @returns {Object}
*/
export const getLibConfig = () => ({
dependencies,
description,
homepage,
license,
name,
version,
});
/**
* Return global `process` variable if it exists.
* Also give "transform-inline-environment-variables" plugin a chance.
*
* @function getProcess
* @returns {Object}
*/
export const getProcess = () => (
envvars => handleException(
() =>
// eslint-disable-next-line no-undef
isObject(process) ? {
...process,
// eslint-disable-next-line no-undef
browser: toBool(process.browser),
env: {
...process.env,
...envvars,
},
} : {
browser: true,
env: envvars,
},
() => ({
browser: true,
env: envvars,
}),
)
)({
NODE_ENV: handleException(
// eslint-disable-next-line no-undef
() => process.env.NODE_ENV,
),
BABEL_ENV: handleException(
// eslint-disable-next-line no-undef
() => process.env.BABEL_ENV,
),
DEBUG: handleException(
// eslint-disable-next-line no-undef
() => process.env.DEBUG,
),
});
/**
* Check current runtime environment.
*
* @function isBrowser
* @returns {Boolean}
*/
export const isBrowser = () => toBool(getProcess().browser);
/**
* Assign argument to the global object.
* Async-console-dev-helper.
*
* @function to_
* @param {String} name
* @returns {Function} (*) => *
*/
export const to_ = (name = "_") =>
val => {
// eslint-disable-next-line no-console
console.log(`${name} = ${quote(typeof val, "[]")}`);
handleException(
() => {
(window ?? self)[name] = val;
// eslint-disable-next-line no-console
console.log(val);
},
() => {
if (!isBrowser()) {
// hide the repl require from webpack
const { repl } = eval("require(\"repl\")");
repl.context[name] = val;
// eslint-disable-next-line no-console
console.log(val);
repl.context.process.stdout.write(repl._prompt);
}
},
);
return val;
};