@modern-js/utils 2.26.0 → 2.28.0

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/cli/alias.js +3 -3
  3. package/dist/cjs/cli/constants/chainId.js +4 -0
  4. package/dist/cjs/cli/constants/index.js +0 -1
  5. package/dist/cjs/cli/is/config.js +11 -8
  6. package/dist/cjs/cli/prettyInstructions.js +3 -2
  7. package/dist/cjs/cli/require.js +2 -1
  8. package/dist/cjs/runtime/nestedRoutes.js +9 -5
  9. package/dist/cjs/runtime-browser/parsed.js +2 -1
  10. package/dist/cjs/universal/formatWebpack.js +55 -12
  11. package/dist/esm/cli/alias.js +27 -23
  12. package/dist/esm/cli/applyOptionsChain.js +8 -6
  13. package/dist/esm/cli/babel.js +50 -35
  14. package/dist/esm/cli/commands.js +7 -7
  15. package/dist/esm/cli/common.js +10 -5
  16. package/dist/esm/cli/constants/chainId.js +5 -1
  17. package/dist/esm/cli/constants/index.js +33 -38
  18. package/dist/esm/cli/ensure.js +4 -2
  19. package/dist/esm/cli/fs.js +56 -9
  20. package/dist/esm/cli/get/config.js +7 -7
  21. package/dist/esm/cli/get/data.js +102 -55
  22. package/dist/esm/cli/get/index.js +21 -6
  23. package/dist/esm/cli/is/config.js +43 -21
  24. package/dist/esm/cli/is/env.js +18 -6
  25. package/dist/esm/cli/is/platform.js +6 -2
  26. package/dist/esm/cli/is/project.js +73 -36
  27. package/dist/esm/cli/is/type.js +3 -1
  28. package/dist/esm/cli/logger.js +49 -38
  29. package/dist/esm/cli/monorepo.js +49 -36
  30. package/dist/esm/cli/package.js +156 -38
  31. package/dist/esm/cli/path.js +44 -20
  32. package/dist/esm/cli/pathSerializer.js +29 -15
  33. package/dist/esm/cli/port.js +89 -40
  34. package/dist/esm/cli/prettyInstructions.js +44 -32
  35. package/dist/esm/cli/require.js +22 -16
  36. package/dist/esm/cli/runtimeExports.js +21 -15
  37. package/dist/esm/cli/watch.js +94 -27
  38. package/dist/esm/compiled.js +3 -3
  39. package/dist/esm/import.js +4 -4
  40. package/dist/esm/runtime/nestedRoutes.js +49 -32
  41. package/dist/esm/runtime-browser/parsed.js +6 -5
  42. package/dist/esm/runtime-node/index.js +1 -1
  43. package/dist/esm/runtime-node/nestedRoutes.js +6 -4
  44. package/dist/esm/runtime-node/serialize.js +1 -1
  45. package/dist/esm/runtime-node/storage.js +12 -14
  46. package/dist/esm/universal/constants.js +3 -3
  47. package/dist/esm/universal/formatWebpack.js +54 -28
  48. package/dist/esm/universal/pluginDagSort.js +49 -26
  49. package/dist/esm-node/cli/alias.js +51 -0
  50. package/dist/esm-node/cli/applyOptionsChain.js +24 -0
  51. package/dist/esm-node/cli/babel.js +103 -0
  52. package/dist/esm-node/cli/commands.js +16 -0
  53. package/dist/esm-node/cli/common.js +10 -0
  54. package/dist/esm-node/cli/constants/chainId.js +184 -0
  55. package/dist/esm-node/cli/constants/index.js +102 -0
  56. package/dist/esm-node/cli/ensure.js +10 -0
  57. package/dist/esm-node/cli/fs.js +14 -0
  58. package/dist/esm-node/cli/get/config.js +16 -0
  59. package/dist/esm-node/cli/get/data.js +86 -0
  60. package/dist/esm-node/cli/get/index.js +13 -0
  61. package/dist/esm-node/cli/index.js +20 -0
  62. package/dist/esm-node/cli/is/config.js +43 -0
  63. package/dist/esm-node/cli/is/env.js +6 -0
  64. package/dist/esm-node/cli/is/index.js +5 -0
  65. package/dist/esm-node/cli/is/platform.js +2 -0
  66. package/dist/esm-node/cli/is/project.js +73 -0
  67. package/dist/esm-node/cli/is/type.js +25 -0
  68. package/dist/esm-node/cli/logger.js +103 -0
  69. package/dist/esm-node/cli/monorepo.js +70 -0
  70. package/dist/esm-node/cli/package.js +43 -0
  71. package/dist/esm-node/cli/path.js +49 -0
  72. package/dist/esm-node/cli/pathSerializer.js +46 -0
  73. package/dist/esm-node/cli/port.js +44 -0
  74. package/dist/esm-node/cli/prettyInstructions.js +78 -0
  75. package/dist/esm-node/cli/require.js +53 -0
  76. package/dist/esm-node/cli/runtimeExports.js +35 -0
  77. package/dist/esm-node/cli/watch.js +41 -0
  78. package/dist/esm-node/compiled.js +33 -0
  79. package/dist/esm-node/import.js +8 -0
  80. package/dist/esm-node/index.js +3 -0
  81. package/dist/esm-node/runtime/nestedRoutes.js +116 -0
  82. package/dist/esm-node/runtime/remixRouter.js +1 -0
  83. package/dist/esm-node/runtime/router.js +1 -0
  84. package/dist/esm-node/runtime-browser/index.js +1 -0
  85. package/dist/esm-node/runtime-browser/parsed.js +18 -0
  86. package/dist/esm-node/runtime-node/index.js +5 -0
  87. package/dist/esm-node/runtime-node/nestedRoutes.js +18 -0
  88. package/dist/esm-node/runtime-node/router.js +1 -0
  89. package/dist/esm-node/runtime-node/serialize.js +6 -0
  90. package/dist/esm-node/runtime-node/storage.js +38 -0
  91. package/dist/esm-node/universal/constants.js +3 -0
  92. package/dist/esm-node/universal/formatWebpack.js +99 -0
  93. package/dist/esm-node/universal/pluginDagSort.js +50 -0
  94. package/dist/types/cli/constants/chainId.d.ts +4 -0
  95. package/dist/types/universal/formatWebpack.d.ts +14 -1
  96. package/package.json +4 -4
@@ -0,0 +1,43 @@
1
+ import { isEmpty } from "./type";
2
+ export const isSSR = (config) => {
3
+ var _server, _server1;
4
+ const { server } = config;
5
+ if ((_server = server) === null || _server === void 0 ? void 0 : _server.ssr) {
6
+ return true;
7
+ }
8
+ if (((_server1 = server) === null || _server1 === void 0 ? void 0 : _server1.ssrByEntries) && !isEmpty(server.ssrByEntries)) {
9
+ for (const name of Object.keys(server.ssrByEntries)) {
10
+ if (server.ssrByEntries[name]) {
11
+ return true;
12
+ }
13
+ }
14
+ }
15
+ return false;
16
+ };
17
+ export const isUseSSRBundle = (config) => {
18
+ var _output;
19
+ const { output } = config;
20
+ if ((_output = output) === null || _output === void 0 ? void 0 : _output.ssg) {
21
+ return true;
22
+ }
23
+ return isSSR(config);
24
+ };
25
+ export const isServiceWorker = (config) => {
26
+ var _deploy_worker, _deploy, _output;
27
+ const { output, deploy } = config;
28
+ if (((_deploy = deploy) === null || _deploy === void 0 ? void 0 : (_deploy_worker = _deploy.worker) === null || _deploy_worker === void 0 ? void 0 : _deploy_worker.ssr) && (((_output = output) === null || _output === void 0 ? void 0 : _output.ssg) || isSSR(config))) {
29
+ return true;
30
+ }
31
+ return false;
32
+ };
33
+ export const isRouterV5 = (config) => {
34
+ var _config_runtime, _config_runtime_router, _config_runtime1, _config;
35
+ return typeof ((_config_runtime = config.runtime) === null || _config_runtime === void 0 ? void 0 : _config_runtime.router) !== "boolean" && ((_config = config) === null || _config === void 0 ? void 0 : (_config_runtime1 = _config.runtime) === null || _config_runtime1 === void 0 ? void 0 : (_config_runtime_router = _config_runtime1.router) === null || _config_runtime_router === void 0 ? void 0 : _config_runtime_router.mode) === "react-router-5";
36
+ };
37
+ export const isSSGEntry = (config, entryName, entrypoints) => {
38
+ var _ssgConfig, _ssgConfig1;
39
+ const ssgConfig = config.output.ssg;
40
+ const useSSG = isSingleEntry(entrypoints) ? Boolean(ssgConfig) : ssgConfig === true || typeof ((_ssgConfig = ssgConfig) === null || _ssgConfig === void 0 ? void 0 : _ssgConfig[0]) === "function" || Boolean((_ssgConfig1 = ssgConfig) === null || _ssgConfig1 === void 0 ? void 0 : _ssgConfig1[entryName]);
41
+ return useSSG;
42
+ };
43
+ export const isSingleEntry = (entrypoints) => entrypoints.length === 1 && entrypoints[0].entryName === "main";
@@ -0,0 +1,6 @@
1
+ export const getNodeEnv = () => process.env.NODE_ENV || "development";
2
+ export const isDev = () => getNodeEnv() === "development";
3
+ export const isProd = () => getNodeEnv() === "production";
4
+ export const isTest = () => getNodeEnv() === "test";
5
+ export const isProdProfile = () => isProd() && process.argv.includes("--profile");
6
+ export const isFastRefresh = () => isDev() && process.env.FAST_REFRESH !== "false";
@@ -0,0 +1,5 @@
1
+ export * from "./env";
2
+ export * from "./platform";
3
+ export * from "./type";
4
+ export * from "./config";
5
+ export * from "./project";
@@ -0,0 +1,2 @@
1
+ export const isNodeJS = () => typeof process !== "undefined" && process.versions != null && process.versions.node != null && process.versions.electron == null;
2
+ export const isBrowser = () => typeof window !== "undefined";
@@ -0,0 +1,73 @@
1
+ import path from "path";
2
+ import pkgUp from "../../../compiled/pkg-up";
3
+ import { getArgv } from "../commands";
4
+ import { fs, minimist, semver } from "../../compiled";
5
+ import { createDebugger } from "../common";
6
+ import { ensureArray } from "../ensure";
7
+ const debug = createDebugger("judge-depExists");
8
+ export const isDepExists = (appDirectory, name) => {
9
+ const pkgPath = path.resolve(appDirectory, "./package.json");
10
+ if (!fs.existsSync(pkgPath)) {
11
+ debug(`can't find package.json under: %s`, appDirectory);
12
+ return false;
13
+ }
14
+ const json = require(pkgPath);
15
+ const { dependencies = {}, devDependencies = {} } = json;
16
+ return dependencies.hasOwnProperty(name) || devDependencies.hasOwnProperty(name);
17
+ };
18
+ export const isPackageInstalled = (name, resolvePaths) => {
19
+ try {
20
+ require.resolve(name, {
21
+ paths: ensureArray(resolvePaths)
22
+ });
23
+ return true;
24
+ } catch (err) {
25
+ return false;
26
+ }
27
+ };
28
+ export const isApiOnly = async (appDirectory, entryDir, apiDir) => {
29
+ const existApi = await fs.pathExists(apiDir !== null && apiDir !== void 0 ? apiDir : path.join(appDirectory, "api"));
30
+ const existSrc = await fs.pathExists(path.join(appDirectory, entryDir !== null && entryDir !== void 0 ? entryDir : "src"));
31
+ const options = minimist(getArgv());
32
+ if (options["api-only"]) {
33
+ return true;
34
+ }
35
+ return existApi && !existSrc;
36
+ };
37
+ export const isWebOnly = async () => {
38
+ const options = minimist(getArgv());
39
+ return Boolean(options["web-only"]);
40
+ };
41
+ export const isBeyondReact17 = (cwd) => {
42
+ const pkgPath = pkgUp.sync({
43
+ cwd
44
+ });
45
+ if (!pkgPath) {
46
+ return false;
47
+ }
48
+ const pkgInfo = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
49
+ const deps = {
50
+ ...pkgInfo.devDependencies,
51
+ ...pkgInfo.dependencies
52
+ };
53
+ if (typeof deps.react !== "string") {
54
+ return false;
55
+ }
56
+ return semver.satisfies(semver.minVersion(deps.react), ">=17.0.0");
57
+ };
58
+ export const isReact18 = (cwd) => {
59
+ const pkgPath = path.join(cwd, "package.json");
60
+ if (!fs.existsSync(pkgPath)) {
61
+ return false;
62
+ }
63
+ const pkgInfo = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
64
+ const deps = {
65
+ ...pkgInfo.devDependencies,
66
+ ...pkgInfo.dependencies
67
+ };
68
+ if (typeof deps.react !== "string") {
69
+ return false;
70
+ }
71
+ return semver.satisfies(semver.minVersion(deps.react), ">=18.0.0");
72
+ };
73
+ export const isTypescript = (root) => fs.existsSync(path.resolve(root, "./tsconfig.json"));
@@ -0,0 +1,25 @@
1
+ export function isString(str) {
2
+ return typeof str === "string";
3
+ }
4
+ export function isUndefined(obj) {
5
+ return typeof obj === "undefined";
6
+ }
7
+ export function isArray(obj) {
8
+ return Array.isArray(obj);
9
+ }
10
+ export function isFunction(func) {
11
+ return typeof func === "function";
12
+ }
13
+ export function isObject(obj) {
14
+ return obj !== null && typeof obj === "object";
15
+ }
16
+ export function isPlainObject(obj) {
17
+ return isObject(obj) && Object.prototype.toString.call(obj) === "[object Object]";
18
+ }
19
+ export function isPromise(obj) {
20
+ return Boolean(obj) && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function";
21
+ }
22
+ export function isRegExp(obj) {
23
+ return Object.prototype.toString.call(obj) === "[object RegExp]";
24
+ }
25
+ export const isEmpty = (o) => Object.entries(o).length === 0 && o.constructor === Object;
@@ -0,0 +1,103 @@
1
+ import chalk from "../../compiled/chalk";
2
+ const LOG_LEVEL = {
3
+ error: 0,
4
+ warn: 1,
5
+ info: 2,
6
+ debug: 3,
7
+ log: 4
8
+ };
9
+ const LOG_TYPES = {
10
+ error: {
11
+ color: "red",
12
+ label: "error",
13
+ level: "error"
14
+ },
15
+ info: {
16
+ color: "cyan",
17
+ label: "info",
18
+ level: "info"
19
+ },
20
+ success: {
21
+ color: "green",
22
+ label: "Success",
23
+ level: "info"
24
+ },
25
+ warn: {
26
+ color: "yellow",
27
+ label: "warn",
28
+ level: "warn"
29
+ },
30
+ debug: {
31
+ color: "red",
32
+ label: "debug",
33
+ level: "debug"
34
+ },
35
+ log: {
36
+ level: "log"
37
+ }
38
+ };
39
+ const DEFAULT_CONFIG = {
40
+ displayLabel: true,
41
+ uppercaseLabel: false
42
+ };
43
+ class Logger {
44
+ _log(type, message, ...args) {
45
+ if (message === void 0 || message === null) {
46
+ console.log();
47
+ return;
48
+ }
49
+ if (LOG_LEVEL[type] > LOG_LEVEL[this.level]) {
50
+ return;
51
+ }
52
+ let label = "";
53
+ let text = "";
54
+ const logType = this.types[type];
55
+ if (this.config.displayLabel && logType.label) {
56
+ label = this.config.uppercaseLabel ? logType.label.toUpperCase() : logType.label;
57
+ label = label.padEnd(this.longestLabel.length);
58
+ label = chalk.bold(logType.color ? chalk[logType.color](label) : label);
59
+ }
60
+ if (message instanceof Error) {
61
+ if (message.stack) {
62
+ const [name, ...rest] = message.stack.split("\n");
63
+ text = `${name}
64
+ ${chalk.grey(rest.join("\n"))}`;
65
+ } else {
66
+ text = message.message;
67
+ }
68
+ } else {
69
+ text = `${message}`;
70
+ }
71
+ const log = label.length > 0 ? `${label} ${text}` : text;
72
+ console.log(log, ...args);
73
+ }
74
+ getLongestLabel() {
75
+ let longestLabel = "";
76
+ Object.keys(this.types).forEach((type) => {
77
+ const { label = "" } = this.types[type];
78
+ if (label.length > longestLabel.length) {
79
+ longestLabel = label;
80
+ }
81
+ });
82
+ return longestLabel;
83
+ }
84
+ constructor(options = {}) {
85
+ this.level = options.level || LOG_TYPES.log.level;
86
+ this.config = {
87
+ ...DEFAULT_CONFIG,
88
+ ...options.config || {}
89
+ };
90
+ this.types = {
91
+ ...LOG_TYPES,
92
+ ...options.types || {}
93
+ };
94
+ this.longestLabel = this.getLongestLabel();
95
+ Object.keys(this.types).forEach((type) => {
96
+ this[type] = this._log.bind(this, type);
97
+ });
98
+ }
99
+ }
100
+ const logger = new Logger();
101
+ logger.Logger = Logger;
102
+ export { Logger };
103
+ export { logger };
@@ -0,0 +1,70 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { glob, yaml } from "../compiled";
4
+ const PACKAGE_MAX_DEPTH = 5;
5
+ const WORKSPACE_FILES = {
6
+ YARN: "package.json",
7
+ PNPM: "pnpm-workspace.yaml",
8
+ LERNA: "lerna.json"
9
+ };
10
+ export const isLerna = (root) => fs.existsSync(path.join(root, WORKSPACE_FILES.LERNA));
11
+ export const isYarnWorkspaces = (root) => {
12
+ var _json_workspaces;
13
+ const pkg = path.join(root, WORKSPACE_FILES.YARN);
14
+ if (!fs.existsSync(pkg)) {
15
+ return false;
16
+ }
17
+ const json = JSON.parse(fs.readFileSync(pkg, "utf8"));
18
+ return Boolean((_json_workspaces = json.workspaces) === null || _json_workspaces === void 0 ? void 0 : _json_workspaces.packages);
19
+ };
20
+ export const isPnpmWorkspaces = (root) => fs.existsSync(path.join(root, WORKSPACE_FILES.PNPM));
21
+ export const isMonorepo = (root) => isLerna(root) || isYarnWorkspaces(root) || isPnpmWorkspaces(root);
22
+ export const isModernjsMonorepo = (root) => {
23
+ const pkgJsonPath = path.join(root, "package.json");
24
+ if (!fs.existsSync(pkgJsonPath)) {
25
+ return false;
26
+ }
27
+ const json = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
28
+ const deps = {
29
+ ...json.dependencies || {},
30
+ ...json.devDependencies || {}
31
+ };
32
+ return Boolean(deps["@modern-js/monorepo-tools"]);
33
+ };
34
+ export const findMonorepoRoot = (appDirectory, maxDepth = PACKAGE_MAX_DEPTH) => {
35
+ let inMonorepo = false;
36
+ for (let depth = 0; depth < maxDepth; depth++) {
37
+ if (isMonorepo(appDirectory)) {
38
+ inMonorepo = true;
39
+ break;
40
+ }
41
+ appDirectory = path.dirname(appDirectory);
42
+ }
43
+ return inMonorepo ? appDirectory : void 0;
44
+ };
45
+ export const getMonorepoPackages = (root) => {
46
+ let packages = [];
47
+ if (isYarnWorkspaces(root)) {
48
+ const json = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
49
+ ({ packages } = json.workspaces);
50
+ } else if (isLerna(root)) {
51
+ const json = JSON.parse(fs.readFileSync(path.resolve(root, "lerna.json"), "utf8"));
52
+ ({ packages } = json);
53
+ } else {
54
+ ({ packages } = yaml.load(fs.readFileSync(path.join(root, WORKSPACE_FILES.PNPM), "utf8")));
55
+ }
56
+ if (packages) {
57
+ return packages.map((name) => (
58
+ // The trailing / ensures only dirs are picked up
59
+ glob.sync(path.join(root, `${name}/`), {
60
+ ignore: [
61
+ "**/node_modules/**"
62
+ ]
63
+ })
64
+ )).reduce((acc, val) => acc.concat(val), []).filter((filepath) => fs.existsSync(path.resolve(filepath, "package.json"))).map((filepath) => ({
65
+ path: filepath,
66
+ name: JSON.parse(fs.readFileSync(path.resolve(filepath, "package.json"), "utf8")).name
67
+ }));
68
+ }
69
+ return [];
70
+ };
@@ -0,0 +1,43 @@
1
+ import { execa } from "../compiled";
2
+ export async function getPnpmVersion() {
3
+ const { stdout } = await execa("pnpm", [
4
+ "--version"
5
+ ]);
6
+ return stdout;
7
+ }
8
+ export async function canUseNpm() {
9
+ try {
10
+ await execa("npm", [
11
+ "--version"
12
+ ], {
13
+ env: process.env
14
+ });
15
+ return true;
16
+ } catch (e) {
17
+ return false;
18
+ }
19
+ }
20
+ export async function canUseYarn() {
21
+ try {
22
+ await execa("yarn", [
23
+ "--version"
24
+ ], {
25
+ env: process.env
26
+ });
27
+ return true;
28
+ } catch (e) {
29
+ return false;
30
+ }
31
+ }
32
+ export async function canUsePnpm() {
33
+ try {
34
+ await execa("pnpm", [
35
+ "--version"
36
+ ], {
37
+ env: process.env
38
+ });
39
+ return true;
40
+ } catch (e) {
41
+ return false;
42
+ }
43
+ }
@@ -0,0 +1,49 @@
1
+ import path from "path";
2
+ import os from "os";
3
+ import fs from "fs";
4
+ import { nanoid, upath, lodash as _ } from "../compiled";
5
+ export const isPathString = (test) => path.posix.basename(test) !== test || path.win32.basename(test) !== test;
6
+ export const isRelativePath = (test) => /^\.\.?($|[\\/])/.test(test);
7
+ export const normalizeOutputPath = (s) => s.replace(/\\/g, "\\\\");
8
+ export const normalizeToPosixPath = (p) => upath.normalizeSafe(path.normalize(p || "")).replace(/^([a-zA-Z]+):/, (_2, m) => `/${m.toLowerCase()}`);
9
+ export const getTemplatePath = (prefix) => {
10
+ const tmpRoot = fs.realpathSync(os.tmpdir());
11
+ const parts = [
12
+ tmpRoot
13
+ ];
14
+ prefix && parts.push(prefix);
15
+ parts.push(nanoid());
16
+ return path.resolve(...parts);
17
+ };
18
+ export function compilePathMatcherRegExp(match) {
19
+ if (typeof match !== "string") {
20
+ return match;
21
+ }
22
+ const escaped = _.escapeRegExp(match);
23
+ return new RegExp(`(?<=\\W|^)${escaped}(?=\\W|$)`);
24
+ }
25
+ export const _joinPathParts = (_part, i, parts) => _(parts).filter((part) => ![
26
+ "/",
27
+ "\\"
28
+ ].includes(part)).tap((parts2) => parts2.unshift("")).slice(0, i + 2).join("/");
29
+ export function upwardPaths(start) {
30
+ return _(start).split(/[/\\]/).filter(Boolean).map(_joinPathParts).reverse().push("/").value();
31
+ }
32
+ export function getRealTemporaryDirectory() {
33
+ let ret = null;
34
+ try {
35
+ ret = os.tmpdir();
36
+ ret = fs.realpathSync(ret);
37
+ } catch {
38
+ }
39
+ return ret;
40
+ }
41
+ export function splitPathString(str) {
42
+ return str.split(/[\\/]/);
43
+ }
44
+ export const removeLeadingSlash = (s) => s.replace(/^\/+/, "");
45
+ export const removeTailSlash = (s) => s.replace(/\/+$/, "");
46
+ export const removeSlash = (s) => removeLeadingSlash(removeTailSlash(s));
47
+ export const cutNameByHyphen = (s) => {
48
+ return s.split(/[-_]/)[0];
49
+ };
@@ -0,0 +1,46 @@
1
+ import os from "os";
2
+ import _ from "../../compiled/lodash";
3
+ import { compilePathMatcherRegExp, normalizeToPosixPath, getRealTemporaryDirectory, splitPathString, upwardPaths } from "./path";
4
+ export const matchUpwardPathsAsUnknown = (p) => _(upwardPaths(normalizeToPosixPath(p))).map((match) => ({
5
+ match,
6
+ mark: "unknown"
7
+ })).slice(1, -1).value();
8
+ export function applyPathMatcher(matcher, str, options = {}) {
9
+ const regex = compilePathMatcherRegExp(matcher.match);
10
+ const replacer = (substring, ...args) => {
11
+ if (options.minPartials && splitPathString(substring).length < options.minPartials) {
12
+ return substring;
13
+ }
14
+ const ret = typeof matcher.mark === "string" ? matcher.mark : matcher.mark(substring, ...args);
15
+ return `<${_.snakeCase(ret).toUpperCase()}>`;
16
+ };
17
+ return str.replace(regex, replacer);
18
+ }
19
+ export function applyMatcherReplacement(matchers, str, options = {}) {
20
+ return matchers.reduce((ret, matcher) => {
21
+ return applyPathMatcher(matcher, ret, options);
22
+ }, str);
23
+ }
24
+ export const createDefaultPathMatchers = (root) => {
25
+ const ret = [
26
+ {
27
+ match: RegExp("(?<=\\/)(\\.pnpm\\/.+?\\/node_modules)(?=\\/)"),
28
+ mark: "pnpmInner"
29
+ }
30
+ ];
31
+ const tmpdir = getRealTemporaryDirectory();
32
+ tmpdir && ret.push({
33
+ match: tmpdir,
34
+ mark: "temp"
35
+ });
36
+ ret.push({
37
+ match: os.tmpdir(),
38
+ mark: "temp"
39
+ });
40
+ ret.push({
41
+ match: os.homedir(),
42
+ mark: "home"
43
+ });
44
+ ret.push(...matchUpwardPathsAsUnknown(root));
45
+ return ret;
46
+ };
@@ -0,0 +1,44 @@
1
+ import net from "net";
2
+ import { chalk } from "../compiled";
3
+ import { logger } from "./logger";
4
+ export const getPort = async (port, { tryLimits = 20, strictPort = false } = {}) => {
5
+ if (typeof port === "string") {
6
+ port = parseInt(port, 10);
7
+ }
8
+ if (strictPort) {
9
+ tryLimits = 1;
10
+ }
11
+ const original = port;
12
+ let found = false;
13
+ let attempts = 0;
14
+ while (!found && attempts <= tryLimits) {
15
+ try {
16
+ await new Promise((resolve, reject) => {
17
+ const server = net.createServer();
18
+ server.unref();
19
+ server.on("error", reject);
20
+ server.listen({
21
+ port,
22
+ host: "0.0.0.0"
23
+ }, () => {
24
+ found = true;
25
+ server.close(resolve);
26
+ });
27
+ });
28
+ } catch (e) {
29
+ if (e.code !== "EADDRINUSE") {
30
+ throw e;
31
+ }
32
+ port++;
33
+ attempts++;
34
+ }
35
+ }
36
+ if (port !== original) {
37
+ if (strictPort) {
38
+ throw new Error(`Port "${original}" is occupied, please choose another one.`);
39
+ } else {
40
+ logger.info(`Something is already running on port ${original}. ${chalk.yellow(`Use port ${port} instead.`)}`);
41
+ }
42
+ }
43
+ return port;
44
+ };
@@ -0,0 +1,78 @@
1
+ import os from "os";
2
+ import { chalk } from "../compiled";
3
+ import { isDev, isSingleEntry } from "./is";
4
+ import { DEFAULT_DEV_HOST } from "./constants";
5
+ const normalizeUrl = (url) => url.replace(/([^:]\/)\/+/g, "$1");
6
+ const getIpv4Interfaces = () => {
7
+ const interfaces = os.networkInterfaces();
8
+ const ipv4Interfaces = [];
9
+ Object.keys(interfaces).forEach((key) => {
10
+ interfaces[key].forEach((detail) => {
11
+ const familyV4Value = typeof detail.family === "string" ? "IPv4" : 4;
12
+ if (detail.family === familyV4Value) {
13
+ ipv4Interfaces.push(detail);
14
+ }
15
+ });
16
+ });
17
+ return ipv4Interfaces;
18
+ };
19
+ export const getAddressUrls = (protocol = "http", port, host) => {
20
+ const LOCAL_LABEL = "Local: ";
21
+ const NETWORK_LABEL = "Network: ";
22
+ const isLocalhost = (url) => {
23
+ var _url;
24
+ return (_url = url) === null || _url === void 0 ? void 0 : _url.includes("localhost");
25
+ };
26
+ if (host && host !== DEFAULT_DEV_HOST) {
27
+ return [
28
+ {
29
+ label: isLocalhost(host) ? LOCAL_LABEL : NETWORK_LABEL,
30
+ url: `${protocol}://${host}:${port}`
31
+ }
32
+ ];
33
+ }
34
+ const ipv4Interfaces = getIpv4Interfaces();
35
+ return ipv4Interfaces.reduce((memo, detail) => {
36
+ if (isLocalhost(detail.address) || detail.internal) {
37
+ memo.push({
38
+ label: LOCAL_LABEL,
39
+ url: `${protocol}://localhost:${port}`
40
+ });
41
+ } else {
42
+ memo.push({
43
+ label: NETWORK_LABEL,
44
+ url: `${protocol}://${detail.address}:${port}`
45
+ });
46
+ }
47
+ return memo;
48
+ }, []);
49
+ };
50
+ export const prettyInstructions = (appContext, config) => {
51
+ var _appContext_builder_context_devServer, _appContext_builder, _config_dev;
52
+ const { entrypoints, serverRoutes, port, apiOnly, checkedEntries } = appContext;
53
+ const isHttps = isDev() && ((_appContext_builder = appContext.builder) === null || _appContext_builder === void 0 ? void 0 : (_appContext_builder_context_devServer = _appContext_builder.context.devServer) === null || _appContext_builder_context_devServer === void 0 ? void 0 : _appContext_builder_context_devServer.https);
54
+ const urls = getAddressUrls(isHttps ? "https" : "http", port, (_config_dev = config.dev) === null || _config_dev === void 0 ? void 0 : _config_dev.host);
55
+ const routes = !apiOnly ? serverRoutes.filter((route) => route.entryName) : serverRoutes;
56
+ let message = "App running at:\n\n";
57
+ if (isSingleEntry(entrypoints) || apiOnly) {
58
+ message += urls.map(({ label, url }) => ` ${chalk.bold(`> ${label.padEnd(10)}`)}${chalk.cyanBright(normalizeUrl(`${url}/${routes[0].urlPath}`))}
59
+ `).join("");
60
+ } else {
61
+ const maxNameLength = Math.max(...routes.map((r) => r.entryName.length));
62
+ urls.forEach(({ label, url }) => {
63
+ message += ` ${chalk.bold(`> ${label}`)}
64
+ `;
65
+ routes.forEach(({ entryName, urlPath, isSSR }) => {
66
+ if (!checkedEntries.includes(entryName)) {
67
+ return;
68
+ }
69
+ message += ` ${chalk.yellowBright(isSSR ? "λ" : "○")} ${chalk.yellowBright(entryName.padEnd(maxNameLength + 8))}${chalk.cyanBright(normalizeUrl(`${url}/${urlPath}`))}
70
+ `;
71
+ });
72
+ });
73
+ message += "\n";
74
+ message += chalk.cyanBright(" λ (Server) server-side renders at runtime\n");
75
+ message += chalk.cyanBright(" ○ (Static) client-side renders as static HTML\n");
76
+ }
77
+ return message;
78
+ };
@@ -0,0 +1,53 @@
1
+ import { findExists } from "./fs";
2
+ export const compatRequire = (filePath, interop = true) => {
3
+ var _mod;
4
+ const mod = require(filePath);
5
+ const rtnESMDefault = interop && ((_mod = mod) === null || _mod === void 0 ? void 0 : _mod.__esModule);
6
+ return rtnESMDefault ? mod.default : mod;
7
+ };
8
+ export const dynamicImport = new Function("modulePath", "return import(modulePath)");
9
+ export const requireExistModule = (filename, opt) => {
10
+ const final = {
11
+ extensions: [
12
+ ".ts",
13
+ ".js"
14
+ ],
15
+ interop: true,
16
+ ...opt
17
+ };
18
+ const exist = findExists(final.extensions.map((ext) => `${filename}${ext}`));
19
+ if (!exist) {
20
+ return null;
21
+ }
22
+ return compatRequire(exist, final.interop);
23
+ };
24
+ export const cleanRequireCache = (filelist) => {
25
+ filelist.forEach((filepath) => {
26
+ delete require.cache[filepath];
27
+ });
28
+ };
29
+ export function deleteRequireCache(path) {
30
+ if (require.cache[path]) {
31
+ delete require.cache[path];
32
+ }
33
+ if (module.children) {
34
+ module.children = module.children.filter((item) => item.filename !== path);
35
+ }
36
+ }
37
+ export const tryResolve = (name, resolvePath) => {
38
+ let filePath = "";
39
+ try {
40
+ filePath = require.resolve(name, {
41
+ paths: [
42
+ resolvePath
43
+ ]
44
+ });
45
+ delete require.cache[filePath];
46
+ } catch (err) {
47
+ if (err.code === "MODULE_NOT_FOUND") {
48
+ throw new Error(`Can not find module ${name}.`);
49
+ }
50
+ throw err;
51
+ }
52
+ return filePath;
53
+ };
@@ -0,0 +1,35 @@
1
+ import path from "path";
2
+ import { fs } from "../compiled";
3
+ import { normalizeOutputPath } from "./path";
4
+ const memo = (fn) => {
5
+ const cache = /* @__PURE__ */ new Map();
6
+ return (...params) => {
7
+ const stringifiedParams = JSON.stringify(params);
8
+ const cachedResult = cache.get(stringifiedParams);
9
+ if (cachedResult) {
10
+ return cachedResult;
11
+ }
12
+ const res = fn(...params);
13
+ cache.set(stringifiedParams, res);
14
+ return res;
15
+ };
16
+ };
17
+ export const createRuntimeExportsUtils = memo((pwd = "", namespace = "index") => {
18
+ const entryExportFile = path.join(pwd, `.runtime-exports/${namespace}.js`);
19
+ const addExport = (statement) => {
20
+ statement = normalizeOutputPath(statement);
21
+ try {
22
+ fs.ensureFileSync(entryExportFile);
23
+ if (!fs.readFileSync(entryExportFile, "utf8").includes(statement)) {
24
+ fs.appendFileSync(entryExportFile, `${statement}
25
+ `);
26
+ }
27
+ } catch {
28
+ }
29
+ };
30
+ const getPath = () => entryExportFile;
31
+ return {
32
+ addExport,
33
+ getPath
34
+ };
35
+ });