bun-workspaces 1.0.0-alpha.3 → 1.0.0-alpha.30
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/LICENSE.md +1 -1
- package/README.md +131 -77
- package/bin/cli.js +1 -2
- package/package.json +24 -30
- package/src/cli/commands/commandHandlerUtils.d.ts +41 -0
- package/src/cli/commands/commandHandlerUtils.mjs +59 -0
- package/src/cli/commands/commands.d.ts +10 -0
- package/src/cli/commands/commands.mjs +23 -0
- package/src/cli/commands/commandsConfig.d.ts +312 -0
- package/src/cli/commands/commandsConfig.mjs +155 -0
- package/src/cli/commands/handleRunScript.d.ts +3 -0
- package/src/cli/commands/handleRunScript.mjs +217 -0
- package/src/cli/commands/handleSimpleCommands.d.ts +15 -0
- package/src/cli/commands/handleSimpleCommands.mjs +170 -0
- package/src/cli/commands/index.d.ts +2 -0
- package/src/cli/commands/index.mjs +2 -0
- package/src/cli/createCli.d.ts +19 -0
- package/src/cli/createCli.mjs +113 -0
- package/src/cli/fatalErrorLogger.d.ts +1 -0
- package/src/cli/fatalErrorLogger.mjs +7 -0
- package/src/cli/globalOptions/globalOptions.d.ts +38 -0
- package/src/cli/globalOptions/globalOptions.mjs +120 -0
- package/src/cli/globalOptions/globalOptionsConfig.d.ts +43 -0
- package/src/cli/globalOptions/globalOptionsConfig.mjs +34 -0
- package/src/cli/globalOptions/index.d.ts +2 -0
- package/src/cli/globalOptions/index.mjs +2 -0
- package/src/cli/index.d.ts +3 -0
- package/src/cli/index.mjs +3 -0
- package/src/config/bunWorkspacesConfig.d.ts +17 -0
- package/src/config/bunWorkspacesConfig.mjs +50 -0
- package/src/config/configFile.d.ts +8 -0
- package/src/config/configFile.mjs +43 -0
- package/src/config/errors.d.ts +3 -0
- package/src/config/errors.mjs +10 -0
- package/src/config/{index.ts → index.d.ts} +1 -0
- package/src/config/index.mjs +11 -0
- package/src/config/userEnvVars.d.ts +9 -0
- package/src/config/userEnvVars.mjs +9 -0
- package/src/config/workspaceConfig/errors.d.ts +3 -0
- package/src/config/workspaceConfig/errors.mjs +9 -0
- package/src/config/workspaceConfig/index.d.ts +4 -0
- package/src/config/workspaceConfig/index.mjs +4 -0
- package/src/config/workspaceConfig/loadWorkspaceConfig.d.ts +5 -0
- package/src/config/workspaceConfig/loadWorkspaceConfig.mjs +82 -0
- package/src/config/workspaceConfig/workspaceConfig.d.ts +25 -0
- package/src/config/workspaceConfig/workspaceConfig.mjs +80 -0
- package/src/config/workspaceConfig/workspaceConfigLocation.d.ts +2 -0
- package/src/config/workspaceConfig/workspaceConfigLocation.mjs +5 -0
- package/src/doctor/doctor.d.ts +35 -0
- package/src/doctor/doctor.mjs +52 -0
- package/src/doctor/index.d.ts +1 -0
- package/src/doctor/index.mjs +1 -0
- package/src/index.d.ts +31 -0
- package/src/index.mjs +9 -0
- package/src/internal/bun/bunLock.d.ts +20 -0
- package/src/internal/bun/bunLock.mjs +72 -0
- package/src/internal/bun/bunVersion.d.ts +21 -0
- package/src/internal/bun/bunVersion.mjs +43 -0
- package/src/internal/bun/index.d.ts +2 -0
- package/src/internal/bun/index.mjs +2 -0
- package/src/internal/core/asyncIterable/asyncIterableQueue.d.ts +15 -0
- package/src/internal/core/asyncIterable/asyncIterableQueue.mjs +73 -0
- package/src/internal/core/asyncIterable/mergeAsyncIterables.d.ts +5 -0
- package/src/internal/core/asyncIterable/mergeAsyncIterables.mjs +27 -0
- package/src/internal/core/error.d.ts +9 -0
- package/src/internal/{error.ts → core/error.mjs} +7 -16
- package/src/internal/core/index.d.ts +7 -0
- package/src/internal/core/index.mjs +6 -0
- package/src/internal/core/json/index.d.ts +2 -0
- package/src/internal/core/json/index.mjs +2 -0
- package/src/internal/core/json/json.d.ts +9 -0
- package/src/internal/core/json/json.mjs +6 -0
- package/src/internal/core/json/jsonc.d.ts +9 -0
- package/src/internal/core/json/jsonc.mjs +117 -0
- package/src/internal/core/optionalArray.d.ts +15 -0
- package/src/internal/core/optionalArray.mjs +8 -0
- package/src/internal/core/regex.d.ts +3 -0
- package/src/internal/core/regex.mjs +10 -0
- package/src/internal/core/types.d.ts +6 -0
- package/src/internal/core/types.mjs +3 -0
- package/src/internal/logger/index.d.ts +1 -0
- package/src/internal/logger/index.mjs +1 -0
- package/src/internal/logger/logger.d.ts +44 -0
- package/src/internal/logger/logger.mjs +110 -0
- package/src/internal/runtime/env.d.ts +5 -0
- package/src/internal/runtime/env.mjs +29 -0
- package/src/internal/runtime/index.d.ts +2 -0
- package/src/internal/runtime/index.mjs +2 -0
- package/src/internal/runtime/onExit.d.ts +6 -0
- package/src/internal/runtime/onExit.mjs +24 -0
- package/src/internal/runtime/os.d.ts +4 -0
- package/src/internal/runtime/os.mjs +7 -0
- package/src/internal/runtime/tempFile.d.ts +16 -0
- package/src/internal/runtime/tempFile.mjs +50 -0
- package/src/project/errors.d.ts +3 -0
- package/src/project/errors.mjs +9 -0
- package/src/project/implementations/fileSystemProject.d.ts +106 -0
- package/src/project/implementations/fileSystemProject.mjs +227 -0
- package/src/project/implementations/memoryProject.d.ts +32 -0
- package/src/project/implementations/memoryProject.mjs +46 -0
- package/src/project/implementations/projectBase.d.ts +28 -0
- package/src/project/implementations/projectBase.mjs +117 -0
- package/src/project/index.d.ts +5 -0
- package/src/project/index.mjs +4 -0
- package/src/project/project.d.ts +64 -0
- package/src/project/project.mjs +6 -0
- package/src/runScript/index.d.ts +7 -0
- package/src/runScript/index.mjs +7 -0
- package/src/runScript/outputChunk.d.ts +22 -0
- package/src/runScript/outputChunk.mjs +30 -0
- package/src/runScript/parallel.d.ts +12 -0
- package/src/runScript/parallel.mjs +52 -0
- package/src/runScript/runScript.d.ts +37 -0
- package/src/runScript/runScript.mjs +60 -0
- package/src/runScript/runScripts.d.ts +48 -0
- package/src/runScript/runScripts.mjs +124 -0
- package/src/runScript/scriptCommand.d.ts +33 -0
- package/src/runScript/scriptCommand.mjs +19 -0
- package/src/runScript/scriptExecution.d.ts +9 -0
- package/src/runScript/scriptExecution.mjs +51 -0
- package/src/runScript/scriptRuntimeMetadata.d.ts +75 -0
- package/src/runScript/scriptRuntimeMetadata.mjs +62 -0
- package/src/runScript/scriptShellOption.d.ts +7 -0
- package/src/runScript/scriptShellOption.mjs +36 -0
- package/src/workspaces/errors.d.ts +12 -0
- package/src/workspaces/{errors.ts → errors.mjs} +5 -2
- package/src/workspaces/findWorkspaces.d.ts +22 -0
- package/src/workspaces/findWorkspaces.mjs +168 -0
- package/src/workspaces/index.d.ts +4 -0
- package/src/workspaces/index.mjs +3 -0
- package/src/workspaces/packageJson.d.ts +15 -0
- package/src/workspaces/packageJson.mjs +135 -0
- package/src/workspaces/{workspace.ts → workspace.d.ts} +5 -6
- package/src/workspaces/workspace.mjs +2 -0
- package/bun.lock +0 -576
- package/src/cli/cli.ts +0 -87
- package/src/cli/globalOptions.ts +0 -122
- package/src/cli/index.ts +0 -1
- package/src/cli/projectCommands.ts +0 -390
- package/src/config/bunWorkspacesConfig.ts +0 -62
- package/src/config/configFile.ts +0 -33
- package/src/index.ts +0 -3
- package/src/internal/bunVersion.ts +0 -26
- package/src/internal/env.ts +0 -25
- package/src/internal/logger.ts +0 -180
- package/src/internal/regex.ts +0 -5
- package/src/project/errors.ts +0 -6
- package/src/project/index.ts +0 -6
- package/src/project/project.ts +0 -155
- package/src/project/scriptCommand.ts +0 -40
- package/src/workspaces/findWorkspaces.ts +0 -137
- package/src/workspaces/index.ts +0 -7
- package/src/workspaces/packageJson.ts +0 -166
- package/tsconfig.json +0 -28
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { IS_WINDOWS } from "../internal/runtime/index.mjs"; // CONCATENATED MODULE: external "../internal/runtime/index.mjs"
|
|
2
|
+
// CONCATENATED MODULE: ./src/runScript/scriptRuntimeMetadata.ts
|
|
3
|
+
|
|
4
|
+
const SCRIPT_RUNTIME_METADATA_CONFIG = {
|
|
5
|
+
projectPath: {
|
|
6
|
+
inlineName: ["<projectPath>"],
|
|
7
|
+
envVarName: "BW_PROJECT_PATH",
|
|
8
|
+
},
|
|
9
|
+
projectName: {
|
|
10
|
+
inlineName: ["<projectName>"],
|
|
11
|
+
envVarName: "BW_PROJECT_NAME",
|
|
12
|
+
},
|
|
13
|
+
workspacePath: {
|
|
14
|
+
inlineName: ["<workspacePath>"],
|
|
15
|
+
envVarName: "BW_WORKSPACE_PATH",
|
|
16
|
+
},
|
|
17
|
+
workspaceRelativePath: {
|
|
18
|
+
inlineName: ["<workspaceRelativePath>"],
|
|
19
|
+
envVarName: "BW_WORKSPACE_RELATIVE_PATH",
|
|
20
|
+
},
|
|
21
|
+
scriptName: {
|
|
22
|
+
inlineName: ["<scriptName>"],
|
|
23
|
+
envVarName: "BW_SCRIPT_NAME",
|
|
24
|
+
},
|
|
25
|
+
workspaceName: {
|
|
26
|
+
/** @todo @deprecated Deprecate <workspace> in favor of <workspaceName> in major release */ inlineName:
|
|
27
|
+
["<workspaceName>", "<workspace>"],
|
|
28
|
+
envVarName: "BW_WORKSPACE_NAME",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
const getScriptRuntimeMetadataConfig = (key) =>
|
|
32
|
+
SCRIPT_RUNTIME_METADATA_CONFIG[key];
|
|
33
|
+
const createScriptRuntimeEnvVars = (metadata) =>
|
|
34
|
+
Object.entries(SCRIPT_RUNTIME_METADATA_CONFIG).reduce((acc, [key, value]) => {
|
|
35
|
+
acc[value.envVarName] = metadata[key];
|
|
36
|
+
return acc;
|
|
37
|
+
}, {});
|
|
38
|
+
const interpolateScriptRuntimeMetadata = (text, metadata, shell) =>
|
|
39
|
+
text.replace(
|
|
40
|
+
new RegExp(
|
|
41
|
+
Object.values(SCRIPT_RUNTIME_METADATA_CONFIG)
|
|
42
|
+
.flatMap((value) => value.inlineName)
|
|
43
|
+
.join("|"),
|
|
44
|
+
"g",
|
|
45
|
+
),
|
|
46
|
+
(match) => {
|
|
47
|
+
const key = Object.entries(SCRIPT_RUNTIME_METADATA_CONFIG).find(
|
|
48
|
+
([_, value]) => value.inlineName.includes(match),
|
|
49
|
+
)?.[0];
|
|
50
|
+
const value = metadata[key];
|
|
51
|
+
if (IS_WINDOWS && shell === "bun") {
|
|
52
|
+
return value.replace(/\\/g, "\\\\");
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
createScriptRuntimeEnvVars,
|
|
60
|
+
getScriptRuntimeMetadataConfig,
|
|
61
|
+
interpolateScriptRuntimeMetadata,
|
|
62
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const SCRIPT_SHELL_OPTIONS: readonly ["bun", "system"];
|
|
2
|
+
export type ScriptShellOption = (typeof SCRIPT_SHELL_OPTIONS)[number];
|
|
3
|
+
export declare const validateScriptShellOption: (
|
|
4
|
+
shell: string,
|
|
5
|
+
) => ScriptShellOption;
|
|
6
|
+
export declare const getScriptShellDefault: () => "bun" | "system";
|
|
7
|
+
export declare const resolveScriptShell: (shell?: string) => ScriptShellOption;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getUserEnvVar } from "../config/userEnvVars.mjs";
|
|
2
|
+
import { BunWorkspacesError } from "../internal/core/index.mjs"; // CONCATENATED MODULE: external "../config/userEnvVars.mjs"
|
|
3
|
+
// CONCATENATED MODULE: external "../internal/core/index.mjs"
|
|
4
|
+
// CONCATENATED MODULE: ./src/runScript/scriptShellOption.ts
|
|
5
|
+
|
|
6
|
+
const SCRIPT_SHELL_OPTIONS = ["bun", "system"];
|
|
7
|
+
const validateScriptShellOption = (shell) => {
|
|
8
|
+
if (!SCRIPT_SHELL_OPTIONS.includes(shell)) {
|
|
9
|
+
throw new BunWorkspacesError(
|
|
10
|
+
`Invalid shell option: ${shell} (accepted values: ${SCRIPT_SHELL_OPTIONS.join(", ")})`,
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
return shell;
|
|
14
|
+
};
|
|
15
|
+
const getScriptShellDefault = () => {
|
|
16
|
+
const shell = getUserEnvVar("scriptShellDefault");
|
|
17
|
+
return shell ? validateScriptShellOption(shell) : "bun";
|
|
18
|
+
};
|
|
19
|
+
const resolveScriptShell = (shell) => {
|
|
20
|
+
if (
|
|
21
|
+
!shell ||
|
|
22
|
+
shell === "default" ||
|
|
23
|
+
shell === "undefined" ||
|
|
24
|
+
shell === "null"
|
|
25
|
+
) {
|
|
26
|
+
return getScriptShellDefault();
|
|
27
|
+
}
|
|
28
|
+
return validateScriptShellOption(shell);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
SCRIPT_SHELL_OPTIONS,
|
|
33
|
+
getScriptShellDefault,
|
|
34
|
+
resolveScriptShell,
|
|
35
|
+
validateScriptShellOption,
|
|
36
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const WORKSPACE_ERRORS: import("../internal/core").DefinedErrors<
|
|
2
|
+
| "PackageNotFound"
|
|
3
|
+
| "InvalidPackageJson"
|
|
4
|
+
| "DuplicateWorkspaceName"
|
|
5
|
+
| "InvalidWorkspaceName"
|
|
6
|
+
| "NoWorkspaceName"
|
|
7
|
+
| "InvalidScripts"
|
|
8
|
+
| "InvalidWorkspaces"
|
|
9
|
+
| "InvalidWorkspacePattern"
|
|
10
|
+
| "AliasConflict"
|
|
11
|
+
| "AliasedWorkspaceNotFound"
|
|
12
|
+
>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { defineErrors } from "../internal/
|
|
1
|
+
import { defineErrors } from "../internal/core/index.mjs"; // CONCATENATED MODULE: external "../internal/core/index.mjs"
|
|
2
|
+
// CONCATENATED MODULE: ./src/workspaces/errors.ts
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
const WORKSPACE_ERRORS = defineErrors(
|
|
4
5
|
"PackageNotFound",
|
|
5
6
|
"InvalidPackageJson",
|
|
6
7
|
"DuplicateWorkspaceName",
|
|
@@ -12,3 +13,5 @@ export const ERRORS = defineErrors(
|
|
|
12
13
|
"AliasConflict",
|
|
13
14
|
"AliasedWorkspaceNotFound",
|
|
14
15
|
);
|
|
16
|
+
|
|
17
|
+
export { WORKSPACE_ERRORS };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ProjectConfig, type ResolvedWorkspaceConfig } from "../config";
|
|
2
|
+
import type { Workspace } from "./workspace";
|
|
3
|
+
export interface FindWorkspacesOptions {
|
|
4
|
+
rootDirectory: string;
|
|
5
|
+
/** If provided, will override the workspaces found in the package.json. Mainly for testing purposes */
|
|
6
|
+
workspaceGlobs?: string[];
|
|
7
|
+
/** @deprecated due to config file changes */
|
|
8
|
+
workspaceAliases?: ProjectConfig["workspaceAliases"];
|
|
9
|
+
}
|
|
10
|
+
export declare const sortWorkspaces: (workspaces: Workspace[]) => Workspace[];
|
|
11
|
+
export declare const findWorkspaces: ({
|
|
12
|
+
rootDirectory,
|
|
13
|
+
workspaceGlobs: _workspaceGlobs,
|
|
14
|
+
workspaceAliases,
|
|
15
|
+
}: FindWorkspacesOptions) => {
|
|
16
|
+
workspaces: Workspace[];
|
|
17
|
+
workspaceConfigMap: Record<string, ResolvedWorkspaceConfig>;
|
|
18
|
+
};
|
|
19
|
+
export declare const validateWorkspaceAliases: (
|
|
20
|
+
workspaces: Workspace[],
|
|
21
|
+
workspaceAliases: ProjectConfig["workspaceAliases"],
|
|
22
|
+
) => void;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { Glob } from "bun";
|
|
4
|
+
import {
|
|
5
|
+
createWorkspaceConfig,
|
|
6
|
+
loadWorkspaceConfig,
|
|
7
|
+
} from "../config/index.mjs";
|
|
8
|
+
import { BUN_LOCK_ERRORS, readBunLockfile } from "../internal/bun/index.mjs";
|
|
9
|
+
import { BunWorkspacesError } from "../internal/core/index.mjs";
|
|
10
|
+
import { WORKSPACE_ERRORS } from "./errors.mjs";
|
|
11
|
+
import {
|
|
12
|
+
resolvePackageJsonContent,
|
|
13
|
+
resolvePackageJsonPath,
|
|
14
|
+
} from "./packageJson.mjs"; // CONCATENATED MODULE: external "fs"
|
|
15
|
+
// CONCATENATED MODULE: external "path"
|
|
16
|
+
// CONCATENATED MODULE: external "bun"
|
|
17
|
+
// CONCATENATED MODULE: external "../config/index.mjs"
|
|
18
|
+
// CONCATENATED MODULE: external "../internal/bun/index.mjs"
|
|
19
|
+
// CONCATENATED MODULE: external "../internal/core/index.mjs"
|
|
20
|
+
// CONCATENATED MODULE: external "./errors.mjs"
|
|
21
|
+
// CONCATENATED MODULE: external "./packageJson.mjs"
|
|
22
|
+
// CONCATENATED MODULE: ./src/workspaces/findWorkspaces.ts
|
|
23
|
+
|
|
24
|
+
const sortWorkspaces = (workspaces) =>
|
|
25
|
+
[...workspaces]
|
|
26
|
+
.sort(
|
|
27
|
+
(a, b) => a.name.localeCompare(b.name) || a.path.localeCompare(b.path),
|
|
28
|
+
)
|
|
29
|
+
.reduce((acc, workspace, i, arr) => {
|
|
30
|
+
const previousWorkspace = arr[i - 1];
|
|
31
|
+
if (previousWorkspace && previousWorkspace.path === workspace.path) {
|
|
32
|
+
return acc;
|
|
33
|
+
}
|
|
34
|
+
return [...acc, workspace];
|
|
35
|
+
}, []);
|
|
36
|
+
const getWorkspaceGlobsFromRoot = ({ rootDirectory }) => {
|
|
37
|
+
const packageJsonPath = path.join(rootDirectory, "package.json");
|
|
38
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
39
|
+
throw new WORKSPACE_ERRORS.PackageNotFound(
|
|
40
|
+
`No package.json found for project root at ${packageJsonPath}`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
const packageJson = resolvePackageJsonContent(
|
|
44
|
+
packageJsonPath,
|
|
45
|
+
rootDirectory,
|
|
46
|
+
["workspaces"],
|
|
47
|
+
);
|
|
48
|
+
return packageJson.workspaces ?? [];
|
|
49
|
+
};
|
|
50
|
+
const validateWorkspace = (workspace, workspaces) => {
|
|
51
|
+
if (workspaces.find((ws) => ws.path === workspace.path)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
if (workspaces.find((ws) => ws.name === workspace.name)) {
|
|
55
|
+
throw new WORKSPACE_ERRORS.DuplicateWorkspaceName(
|
|
56
|
+
`Duplicate workspace name found: ${JSON.stringify(workspace.name)}`,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
};
|
|
61
|
+
const findWorkspaces = ({
|
|
62
|
+
rootDirectory,
|
|
63
|
+
workspaceGlobs: _workspaceGlobs,
|
|
64
|
+
workspaceAliases = {},
|
|
65
|
+
}) => {
|
|
66
|
+
rootDirectory = path.resolve(rootDirectory);
|
|
67
|
+
let workspaces = [];
|
|
68
|
+
const excludedWorkspacePaths = [];
|
|
69
|
+
const workspaceConfigMap = {};
|
|
70
|
+
const bunLock = readBunLockfile(rootDirectory);
|
|
71
|
+
if (bunLock instanceof BunWorkspacesError) {
|
|
72
|
+
if (bunLock instanceof BUN_LOCK_ERRORS.BunLockNotFound) {
|
|
73
|
+
bunLock.message =
|
|
74
|
+
`No bun.lock found at ${rootDirectory}. Check that this is the directory of your project and that you've ran 'bun install'.` +
|
|
75
|
+
"If you have ran 'bun install', you may simply have no workspaces or dependencies in your project.";
|
|
76
|
+
}
|
|
77
|
+
throw bunLock;
|
|
78
|
+
}
|
|
79
|
+
const workspaceGlobs =
|
|
80
|
+
_workspaceGlobs ??
|
|
81
|
+
getWorkspaceGlobsFromRoot({
|
|
82
|
+
rootDirectory,
|
|
83
|
+
});
|
|
84
|
+
for (const workspacePath of Object.keys(bunLock.workspaces).map((p) =>
|
|
85
|
+
path.join(rootDirectory, p),
|
|
86
|
+
)) {
|
|
87
|
+
if (workspacePath === rootDirectory) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const packageJsonPath = resolvePackageJsonPath(workspacePath);
|
|
91
|
+
if (packageJsonPath) {
|
|
92
|
+
const packageJsonContent = resolvePackageJsonContent(
|
|
93
|
+
packageJsonPath,
|
|
94
|
+
rootDirectory,
|
|
95
|
+
["name", "scripts"],
|
|
96
|
+
);
|
|
97
|
+
const workspaceConfig = loadWorkspaceConfig(
|
|
98
|
+
path.dirname(packageJsonPath),
|
|
99
|
+
);
|
|
100
|
+
if (workspaceConfig) {
|
|
101
|
+
for (const alias of workspaceConfig.aliases) {
|
|
102
|
+
workspaceAliases[alias] = packageJsonContent.name;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const relativePath = path.relative(
|
|
106
|
+
rootDirectory,
|
|
107
|
+
path.dirname(packageJsonPath),
|
|
108
|
+
);
|
|
109
|
+
const matchPattern =
|
|
110
|
+
workspaceGlobs.find((glob) => new Glob(glob).match(relativePath)) ?? "";
|
|
111
|
+
if (_workspaceGlobs && !matchPattern) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const workspace = {
|
|
115
|
+
name: packageJsonContent.name ?? "",
|
|
116
|
+
matchPattern,
|
|
117
|
+
path: path.relative(rootDirectory, path.dirname(packageJsonPath)),
|
|
118
|
+
scripts: Object.keys(packageJsonContent.scripts ?? {}).sort(),
|
|
119
|
+
aliases: [
|
|
120
|
+
...new Set(
|
|
121
|
+
Object.entries(workspaceAliases ?? {})
|
|
122
|
+
.filter(([_, value]) => value === packageJsonContent.name)
|
|
123
|
+
.map(([key]) => key)
|
|
124
|
+
.concat(workspaceConfig?.aliases ?? []),
|
|
125
|
+
),
|
|
126
|
+
],
|
|
127
|
+
};
|
|
128
|
+
if (
|
|
129
|
+
!excludedWorkspacePaths.includes(workspace.path) &&
|
|
130
|
+
validateWorkspace(workspace, workspaces)
|
|
131
|
+
) {
|
|
132
|
+
workspaces.push(workspace);
|
|
133
|
+
workspaceConfigMap[workspace.name] =
|
|
134
|
+
workspaceConfig ?? createWorkspaceConfig();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
workspaces = sortWorkspaces(workspaces);
|
|
139
|
+
validateWorkspaceAliases(workspaces, workspaceAliases);
|
|
140
|
+
return {
|
|
141
|
+
workspaces,
|
|
142
|
+
workspaceConfigMap,
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
const validateWorkspaceAliases = (workspaces, workspaceAliases) => {
|
|
146
|
+
for (const [alias, name] of Object.entries(workspaceAliases ?? {})) {
|
|
147
|
+
if (workspaces.find((ws) => ws.name === alias)) {
|
|
148
|
+
throw new WORKSPACE_ERRORS.AliasConflict(
|
|
149
|
+
`Alias ${JSON.stringify(alias)} conflicts with workspace name ${JSON.stringify(name)}`,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
const workspaceWithDuplicateAlias = workspaces.find(
|
|
153
|
+
(ws) => ws.name !== name && ws.aliases.includes(alias),
|
|
154
|
+
);
|
|
155
|
+
if (workspaceWithDuplicateAlias) {
|
|
156
|
+
throw new WORKSPACE_ERRORS.AliasConflict(
|
|
157
|
+
`Workspaces ${JSON.stringify(name)} and ${JSON.stringify(workspaceWithDuplicateAlias.name)} have the same alias ${JSON.stringify(alias)}`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
if (!workspaces.find((ws) => ws.name === name)) {
|
|
161
|
+
throw new WORKSPACE_ERRORS.AliasedWorkspaceNotFound(
|
|
162
|
+
`Workspace ${JSON.stringify(name)} was aliased by ${JSON.stringify(alias)} but was not found`,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export { findWorkspaces, sortWorkspaces, validateWorkspaceAliases };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const resolvePackageJsonPath: (directoryItem: string) => string;
|
|
2
|
+
export type ResolvedPackageJsonContent = {
|
|
3
|
+
name: string;
|
|
4
|
+
workspaces: string[];
|
|
5
|
+
scripts: Record<string, string>;
|
|
6
|
+
} & Record<string, unknown>;
|
|
7
|
+
export declare const scanWorkspaceGlob: (
|
|
8
|
+
globPattern: string,
|
|
9
|
+
rootDirectory: string,
|
|
10
|
+
) => IterableIterator<string>;
|
|
11
|
+
export declare const resolvePackageJsonContent: (
|
|
12
|
+
packageJsonPath: string,
|
|
13
|
+
rootDirectory: string,
|
|
14
|
+
validations: ("workspaces" | "name" | "scripts")[],
|
|
15
|
+
) => ResolvedPackageJsonContent;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { Glob } from "bun";
|
|
4
|
+
import { logger } from "../internal/logger/index.mjs";
|
|
5
|
+
import { WORKSPACE_ERRORS } from "./errors.mjs"; // CONCATENATED MODULE: external "fs"
|
|
6
|
+
// CONCATENATED MODULE: external "path"
|
|
7
|
+
// CONCATENATED MODULE: external "bun"
|
|
8
|
+
// CONCATENATED MODULE: external "../internal/logger/index.mjs"
|
|
9
|
+
// CONCATENATED MODULE: external "./errors.mjs"
|
|
10
|
+
// CONCATENATED MODULE: ./src/workspaces/packageJson.ts
|
|
11
|
+
|
|
12
|
+
const resolvePackageJsonPath = (directoryItem) => {
|
|
13
|
+
if (path.basename(directoryItem) === "package.json") {
|
|
14
|
+
return directoryItem;
|
|
15
|
+
}
|
|
16
|
+
if (fs.existsSync(path.join(directoryItem, "package.json"))) {
|
|
17
|
+
return path.join(directoryItem, "package.json");
|
|
18
|
+
}
|
|
19
|
+
return "";
|
|
20
|
+
};
|
|
21
|
+
const scanWorkspaceGlob = (globPattern, rootDirectory) =>
|
|
22
|
+
new Glob(globPattern).scanSync({
|
|
23
|
+
cwd: rootDirectory,
|
|
24
|
+
absolute: true,
|
|
25
|
+
onlyFiles: false,
|
|
26
|
+
});
|
|
27
|
+
const validateJsonRoot = (json) => {
|
|
28
|
+
if (!json || typeof json !== "object" || Array.isArray(json)) {
|
|
29
|
+
throw new WORKSPACE_ERRORS.InvalidPackageJson(
|
|
30
|
+
`Expected package.json to be an object, got ${typeof json}`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const validateName = (json) => {
|
|
35
|
+
if (typeof json.name !== "string") {
|
|
36
|
+
throw new WORKSPACE_ERRORS.NoWorkspaceName(
|
|
37
|
+
`Expected package.json to have a string "name" field${json.name !== undefined ? ` (Received ${json.name})` : ""}`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
if (!json.name.trim()) {
|
|
41
|
+
throw new WORKSPACE_ERRORS.NoWorkspaceName(
|
|
42
|
+
`Expected package.json to have a non-empty "name" field`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
if (json.name.includes("*")) {
|
|
46
|
+
throw new WORKSPACE_ERRORS.InvalidWorkspaceName(
|
|
47
|
+
`Package name cannot contain the character '*' (workspace: "${json.name}")`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return json.name;
|
|
51
|
+
};
|
|
52
|
+
const validateWorkspacePattern = (workspacePattern, rootDirectory) => {
|
|
53
|
+
if (typeof workspacePattern !== "string") {
|
|
54
|
+
throw new WORKSPACE_ERRORS.InvalidWorkspacePattern(
|
|
55
|
+
`Expected workspace pattern to be a string, got ${typeof workspacePattern}`,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
if (!workspacePattern.trim()) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
const absolutePattern = path.resolve(rootDirectory, workspacePattern);
|
|
62
|
+
if (!absolutePattern.startsWith(rootDirectory)) {
|
|
63
|
+
throw new WORKSPACE_ERRORS.InvalidWorkspacePattern(
|
|
64
|
+
`Cannot resolve workspace pattern outside of root directory ${rootDirectory}: ${absolutePattern}`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
};
|
|
69
|
+
const validateWorkspacePatterns = (json, rootDirectory) => {
|
|
70
|
+
const workspaces = [];
|
|
71
|
+
if (json.workspaces) {
|
|
72
|
+
if (!Array.isArray(json.workspaces)) {
|
|
73
|
+
throw new WORKSPACE_ERRORS.InvalidWorkspaces(
|
|
74
|
+
`Expected package.json to have an array "workspaces" field`,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
for (const workspacePattern of json.workspaces) {
|
|
78
|
+
if (validateWorkspacePattern(workspacePattern, rootDirectory)) {
|
|
79
|
+
workspaces.push(workspacePattern);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return workspaces;
|
|
84
|
+
};
|
|
85
|
+
const validateScripts = (json) => {
|
|
86
|
+
if (
|
|
87
|
+
json.scripts &&
|
|
88
|
+
(typeof json.scripts !== "object" || Array.isArray(json.scripts))
|
|
89
|
+
) {
|
|
90
|
+
throw new WORKSPACE_ERRORS.InvalidScripts(
|
|
91
|
+
`Expected package.json to have an object "scripts" field`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
if (json.scripts) {
|
|
95
|
+
for (const value of Object.values(json.scripts)) {
|
|
96
|
+
if (typeof value !== "string") {
|
|
97
|
+
throw new WORKSPACE_ERRORS.InvalidScripts(
|
|
98
|
+
`Expected workspace "${json.name}" script "${json.scripts}" to be a string, got ${typeof value}`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
...json.scripts,
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
const resolvePackageJsonContent = (
|
|
108
|
+
packageJsonPath,
|
|
109
|
+
rootDirectory,
|
|
110
|
+
validations,
|
|
111
|
+
) => {
|
|
112
|
+
rootDirectory = path.resolve(rootDirectory);
|
|
113
|
+
let json = {};
|
|
114
|
+
try {
|
|
115
|
+
json = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
116
|
+
} catch (error) {
|
|
117
|
+
logger.error(error);
|
|
118
|
+
throw new WORKSPACE_ERRORS.InvalidPackageJson(
|
|
119
|
+
`Failed to read and parse package.json at ${packageJsonPath}: ${error.message}`,
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
validateJsonRoot(json);
|
|
123
|
+
return {
|
|
124
|
+
...json,
|
|
125
|
+
name: validations.includes("name") ? validateName(json) : (json.name ?? ""),
|
|
126
|
+
workspaces: validations.includes("workspaces")
|
|
127
|
+
? validateWorkspacePatterns(json, rootDirectory)
|
|
128
|
+
: (json?.workspaces ?? []),
|
|
129
|
+
scripts: validations.includes("scripts")
|
|
130
|
+
? validateScripts(json)
|
|
131
|
+
: (json.scripts ?? {}),
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export { resolvePackageJsonContent, resolvePackageJsonPath, scanWorkspaceGlob };
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export interface Workspace {
|
|
1
|
+
/** Metadata about a nested package within a Bun monorepo */
|
|
2
|
+
export type Workspace = {
|
|
4
3
|
/** The name of the workspace from its `package.json` */
|
|
5
4
|
name: string;
|
|
6
5
|
/** The relative path to the workspace from the root `package.json` */
|
|
7
6
|
path: string;
|
|
8
7
|
/** The pattern from `"workspaces"` in the root `package.json`that this workspace was matched from*/
|
|
9
8
|
matchPattern: string;
|
|
10
|
-
/** The
|
|
11
|
-
|
|
9
|
+
/** The scripts available in package.json */
|
|
10
|
+
scripts: string[];
|
|
12
11
|
/** Aliases assigned to the workspace via the `"workspaceAliases"` field in the config */
|
|
13
12
|
aliases: string[];
|
|
14
|
-
}
|
|
13
|
+
};
|