bun-workspaces 1.0.1-alpha → 1.0.1
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 +189 -70
- package/bin/cli.js +1 -2
- package/package.json +27 -30
- package/src/cli/commands/commandHandlerUtils.d.ts +49 -0
- package/src/cli/commands/commandHandlerUtils.mjs +91 -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 +351 -0
- package/src/cli/commands/commandsConfig.mjs +183 -0
- package/src/cli/commands/handleSimpleCommands.d.ts +15 -0
- package/src/cli/commands/handleSimpleCommands.mjs +174 -0
- package/src/cli/commands/index.d.ts +3 -0
- package/src/cli/commands/index.mjs +3 -0
- package/src/cli/commands/runScript/handleRunScript.d.ts +3 -0
- package/src/cli/commands/runScript/handleRunScript.mjs +249 -0
- package/src/cli/commands/runScript/index.d.ts +2 -0
- package/src/cli/commands/runScript/index.mjs +2 -0
- package/src/cli/commands/runScript/output/index.d.ts +1 -0
- package/src/cli/commands/runScript/output/index.mjs +1 -0
- package/src/cli/commands/runScript/output/outputStyle.d.ts +8 -0
- package/src/cli/commands/runScript/output/outputStyle.mjs +17 -0
- package/src/cli/commands/runScript/output/renderGroupedOutput.d.ts +73 -0
- package/src/cli/commands/runScript/output/renderGroupedOutput.mjs +308 -0
- package/src/cli/commands/runScript/output/renderPlainOutput.d.ts +24 -0
- package/src/cli/commands/runScript/output/renderPlainOutput.mjs +44 -0
- package/src/cli/commands/runScript/output/sanitizeChunk.d.ts +4 -0
- package/src/cli/commands/runScript/output/sanitizeChunk.mjs +101 -0
- package/src/cli/createCli.d.ts +25 -0
- package/src/cli/createCli.mjs +154 -0
- package/src/cli/fatalErrorLogger.d.ts +1 -0
- package/src/cli/fatalErrorLogger.mjs +7 -0
- package/src/cli/globalOptions/globalOptions.d.ts +40 -0
- package/src/cli/globalOptions/globalOptions.mjs +105 -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/cli/middleware.d.ts +72 -0
- package/src/cli/middleware.mjs +38 -0
- package/src/config/index.d.ts +3 -0
- package/src/config/index.mjs +3 -0
- package/src/config/rootConfig/errors.d.ts +1 -0
- package/src/config/rootConfig/errors.mjs +6 -0
- package/src/config/rootConfig/index.d.ts +5 -0
- package/src/config/rootConfig/index.mjs +5 -0
- package/src/config/rootConfig/loadRootConfig.d.ts +3 -0
- package/src/config/rootConfig/loadRootConfig.mjs +22 -0
- package/src/config/rootConfig/rootConfig.d.ts +17 -0
- package/src/config/rootConfig/rootConfig.mjs +43 -0
- package/src/config/rootConfig/rootConfigLocation.d.ts +2 -0
- package/src/config/rootConfig/rootConfigLocation.mjs +5 -0
- package/src/config/rootConfig/rootConfigSchema.d.ts +21 -0
- package/src/config/rootConfig/rootConfigSchema.mjs +24 -0
- package/src/config/userEnvVars/index.d.ts +1 -0
- package/src/config/userEnvVars/index.mjs +1 -0
- package/src/config/userEnvVars/userEnvVars.d.ts +13 -0
- package/src/config/userEnvVars/userEnvVars.mjs +10 -0
- package/src/config/util/ajvTypes.d.ts +10 -0
- package/src/config/util/ajvTypes.mjs +2 -0
- package/src/config/util/configLocation.d.ts +12 -0
- package/src/config/util/configLocation.mjs +11 -0
- package/src/config/util/index.d.ts +4 -0
- package/src/config/util/index.mjs +3 -0
- package/src/config/util/loadConfig.d.ts +16 -0
- package/src/config/util/loadConfig.mjs +118 -0
- package/src/config/util/validateConfig.d.ts +8 -0
- package/src/config/util/validateConfig.mjs +17 -0
- package/src/config/workspaceConfig/errors.d.ts +1 -0
- package/src/config/workspaceConfig/errors.mjs +6 -0
- package/src/config/workspaceConfig/index.d.ts +5 -0
- package/src/config/workspaceConfig/index.mjs +5 -0
- package/src/config/workspaceConfig/loadWorkspaceConfig.d.ts +3 -0
- package/src/config/workspaceConfig/loadWorkspaceConfig.mjs +25 -0
- package/src/config/workspaceConfig/workspaceConfig.d.ts +22 -0
- package/src/config/workspaceConfig/workspaceConfig.mjs +31 -0
- package/src/config/workspaceConfig/workspaceConfigLocation.d.ts +2 -0
- package/src/config/workspaceConfig/workspaceConfigLocation.mjs +5 -0
- package/src/config/workspaceConfig/workspaceConfigSchema.d.ts +25 -0
- package/src/config/workspaceConfig/workspaceConfigSchema.mjs +28 -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 +37 -0
- package/src/index.mjs +16 -0
- package/src/internal/bun/bunLock.d.ts +20 -0
- package/src/internal/bun/bunLock.mjs +70 -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/error/error.d.ts +13 -0
- package/src/internal/{error.ts → core/error/error.mjs} +16 -18
- package/src/internal/core/error/index.d.ts +1 -0
- package/src/internal/core/error/index.mjs +1 -0
- package/src/internal/core/index.d.ts +4 -0
- package/src/internal/core/index.mjs +4 -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 +49 -0
- package/src/internal/core/json/json.mjs +12 -0
- package/src/internal/core/json/jsonc.d.ts +9 -0
- package/src/internal/core/json/jsonc.mjs +117 -0
- package/src/internal/core/language/array/index.d.ts +1 -0
- package/src/internal/core/language/array/index.mjs +1 -0
- package/src/internal/core/language/array/optionalArray.d.ts +15 -0
- package/src/internal/core/language/array/optionalArray.mjs +8 -0
- package/src/internal/core/language/asyncIterable/asyncIterableQueue.d.ts +16 -0
- package/src/internal/core/language/asyncIterable/asyncIterableQueue.mjs +81 -0
- package/src/internal/core/language/asyncIterable/index.d.ts +2 -0
- package/src/internal/core/language/asyncIterable/index.mjs +2 -0
- package/src/internal/core/language/asyncIterable/mergeAsyncIterables.d.ts +5 -0
- package/src/internal/core/language/asyncIterable/mergeAsyncIterables.mjs +27 -0
- package/src/internal/core/language/events/typedEventTarget.d.ts +50 -0
- package/src/internal/core/language/events/typedEventTarget.mjs +14 -0
- package/src/internal/core/language/index.d.ts +5 -0
- package/src/internal/core/language/index.mjs +5 -0
- package/src/internal/core/language/regex/index.d.ts +1 -0
- package/src/internal/core/language/regex/index.mjs +1 -0
- package/src/internal/core/language/regex/regex.d.ts +3 -0
- package/src/internal/core/language/regex/regex.mjs +10 -0
- package/src/internal/core/language/string/id.d.ts +1 -0
- package/src/internal/core/language/string/id.mjs +10 -0
- package/src/internal/core/language/string/index.d.ts +1 -0
- package/src/internal/core/language/string/index.mjs +1 -0
- package/src/internal/core/language/string/utf/eastAsianWidth.d.ts +16 -0
- package/src/internal/core/language/string/utf/eastAsianWidth.mjs +326 -0
- package/src/internal/core/language/string/utf/visibleLength.d.ts +5 -0
- package/src/internal/core/language/string/utf/visibleLength.mjs +29 -0
- package/src/internal/core/language/types/index.d.ts +2 -0
- package/src/internal/core/language/types/index.mjs +1 -0
- package/src/internal/core/language/types/typeof.d.ts +102 -0
- package/src/internal/core/language/types/typeof.mjs +123 -0
- package/src/internal/core/language/types/types.d.ts +14 -0
- package/src/internal/core/language/types/types.mjs +2 -0
- package/src/internal/core/runtime/env.d.ts +6 -0
- package/src/internal/core/runtime/env.mjs +36 -0
- package/src/internal/core/runtime/index.d.ts +5 -0
- package/src/internal/core/runtime/index.mjs +5 -0
- package/src/internal/core/runtime/onExit.d.ts +4 -0
- package/src/internal/core/runtime/onExit.mjs +54 -0
- package/src/internal/core/runtime/os.d.ts +4 -0
- package/src/internal/core/runtime/os.mjs +7 -0
- package/src/internal/core/runtime/tempFile.d.ts +20 -0
- package/src/internal/core/runtime/tempFile.mjs +87 -0
- package/src/internal/core/runtime/terminal.d.ts +1 -0
- package/src/internal/core/runtime/terminal.mjs +4 -0
- package/src/internal/generated/ajv/validateRootConfig.mjs +1 -0
- package/src/internal/generated/ajv/validateWorkspaceConfig.mjs +1 -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 +45 -0
- package/src/internal/logger/logger.mjs +133 -0
- package/src/internal/version.d.ts +1 -0
- package/src/internal/version.mjs +6 -0
- package/src/project/errors.d.ts +5 -0
- package/src/project/errors.mjs +10 -0
- package/src/project/implementations/fileSystemProject.d.ts +148 -0
- package/src/project/implementations/fileSystemProject.mjs +455 -0
- package/src/project/implementations/memoryProject.d.ts +41 -0
- package/src/project/implementations/memoryProject.mjs +148 -0
- package/src/project/implementations/projectBase.d.ts +35 -0
- package/src/project/implementations/projectBase.mjs +197 -0
- package/src/project/index.d.ts +5 -0
- package/src/project/index.mjs +4 -0
- package/src/project/project.d.ts +75 -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/output/index.d.ts +3 -0
- package/src/runScript/output/index.mjs +2 -0
- package/src/runScript/output/multiProcessOutput.d.ts +14 -0
- package/src/runScript/output/multiProcessOutput.mjs +21 -0
- package/src/runScript/output/outputStream.d.ts +1 -0
- package/src/runScript/output/outputStream.mjs +1 -0
- package/src/runScript/output/processOutput.d.ts +33 -0
- package/src/runScript/output/processOutput.mjs +124 -0
- package/src/runScript/parallel.d.ts +15 -0
- package/src/runScript/parallel.mjs +56 -0
- package/src/runScript/recursion.d.ts +4 -0
- package/src/runScript/recursion.mjs +17 -0
- package/src/runScript/runScript.d.ts +45 -0
- package/src/runScript/runScript.mjs +89 -0
- package/src/runScript/runScripts.d.ts +65 -0
- package/src/runScript/runScripts.mjs +263 -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 +50 -0
- package/src/runScript/scriptRuntimeMetadata.d.ts +73 -0
- package/src/runScript/scriptRuntimeMetadata.mjs +61 -0
- package/src/runScript/scriptShellOption.d.ts +8 -0
- package/src/runScript/scriptShellOption.mjs +39 -0
- package/src/runScript/subprocesses.d.ts +11 -0
- package/src/runScript/subprocesses.mjs +34 -0
- package/src/workspaces/dependencyGraph/cycles.d.ts +9 -0
- package/src/workspaces/dependencyGraph/cycles.mjs +91 -0
- package/src/workspaces/dependencyGraph/index.d.ts +2 -0
- package/src/workspaces/dependencyGraph/index.mjs +2 -0
- package/src/workspaces/dependencyGraph/resolveDependencies.d.ts +18 -0
- package/src/workspaces/dependencyGraph/resolveDependencies.mjs +52 -0
- package/src/workspaces/errors.d.ts +13 -0
- package/src/workspaces/errors.mjs +18 -0
- package/src/workspaces/findWorkspaces.d.ts +24 -0
- package/src/workspaces/findWorkspaces.mjs +217 -0
- package/src/workspaces/index.d.ts +4 -0
- package/src/workspaces/index.mjs +3 -0
- package/src/workspaces/packageJson.d.ts +31 -0
- package/src/workspaces/packageJson.mjs +188 -0
- package/src/workspaces/{workspace.ts → workspace.d.ts} +11 -6
- package/src/workspaces/workspace.mjs +2 -0
- package/src/workspaces/workspacePattern.d.ts +21 -0
- package/src/workspaces/workspacePattern.mjs +104 -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 -396
- package/src/config/bunWorkspacesConfig.ts +0 -62
- package/src/config/configFile.ts +0 -33
- package/src/config/index.ts +0 -7
- 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 -145
- 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/errors.ts +0 -14
- 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,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getUserEnvVar,
|
|
3
|
+
getUserEnvVarName,
|
|
4
|
+
} from "../config/userEnvVars/index.mjs";
|
|
5
|
+
import { BunWorkspacesError } from "../internal/core/error/index.mjs"; // CONCATENATED MODULE: external "../config/userEnvVars/index.mjs"
|
|
6
|
+
// CONCATENATED MODULE: external "../internal/core/error/index.mjs"
|
|
7
|
+
// CONCATENATED MODULE: ./src/runScript/scriptShellOption.ts
|
|
8
|
+
|
|
9
|
+
const SCRIPT_SHELL_OPTIONS = ["bun", "system"];
|
|
10
|
+
const validateScriptShellOption = (shell, fromEnvVar = false) => {
|
|
11
|
+
if (!SCRIPT_SHELL_OPTIONS.includes(shell)) {
|
|
12
|
+
throw new BunWorkspacesError(
|
|
13
|
+
`Invalid shell option: ${shell} (accepted values: ${SCRIPT_SHELL_OPTIONS.join(", ")})${fromEnvVar ? ` (set by env var ${getUserEnvVarName("scriptShellDefault")})` : ""}`,
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
return shell;
|
|
17
|
+
};
|
|
18
|
+
const getScriptShellDefault = () => {
|
|
19
|
+
const shell = getUserEnvVar("scriptShellDefault");
|
|
20
|
+
return shell ? validateScriptShellOption(shell, true) : "bun";
|
|
21
|
+
};
|
|
22
|
+
const resolveScriptShell = (shell) => {
|
|
23
|
+
if (
|
|
24
|
+
!shell ||
|
|
25
|
+
shell === "default" ||
|
|
26
|
+
shell === "undefined" ||
|
|
27
|
+
shell === "null"
|
|
28
|
+
) {
|
|
29
|
+
return getScriptShellDefault();
|
|
30
|
+
}
|
|
31
|
+
return validateScriptShellOption(shell);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export {
|
|
35
|
+
SCRIPT_SHELL_OPTIONS,
|
|
36
|
+
getScriptShellDefault,
|
|
37
|
+
resolveScriptShell,
|
|
38
|
+
validateScriptShellOption,
|
|
39
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**Essentially a wrapper around `Bun.spawn` that ensures all
|
|
2
|
+
* the subprocess is killed when the main process exits for any
|
|
3
|
+
* handle-able exit code or signal. */
|
|
4
|
+
export declare const createSubprocess: <
|
|
5
|
+
In extends Bun.SpawnOptions.Writable,
|
|
6
|
+
Out extends Bun.SpawnOptions.Readable,
|
|
7
|
+
Err extends Bun.SpawnOptions.Readable,
|
|
8
|
+
>(
|
|
9
|
+
argv: string[],
|
|
10
|
+
options: Bun.Spawn.SpawnOptions<In, Out, Err>,
|
|
11
|
+
) => Bun.Subprocess<In, Out, Err>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { IS_WINDOWS, runOnExit } from "../internal/core/index.mjs";
|
|
2
|
+
import { logger } from "../internal/logger/index.mjs"; // CONCATENATED MODULE: external "../internal/core/index.mjs"
|
|
3
|
+
// CONCATENATED MODULE: external "../internal/logger/index.mjs"
|
|
4
|
+
// CONCATENATED MODULE: ./src/runScript/subprocesses.ts
|
|
5
|
+
|
|
6
|
+
const SUBPROCESS_REGISTRY = {};
|
|
7
|
+
runOnExit((codeOrSignal) => {
|
|
8
|
+
Object.values(SUBPROCESS_REGISTRY).forEach((subprocess) => {
|
|
9
|
+
/**
|
|
10
|
+
* @todo Windows support for killing subprocesses is needed.
|
|
11
|
+
* subprocess.kill() will throw with not-implemented error
|
|
12
|
+
*/ if (!subprocess.killed && subprocess.exitCode === null && !IS_WINDOWS) {
|
|
13
|
+
logger.debug(
|
|
14
|
+
`Killing subprocess ${subprocess.pid} with signal ${codeOrSignal}`,
|
|
15
|
+
);
|
|
16
|
+
subprocess.kill(codeOrSignal);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
/**Essentially a wrapper around `Bun.spawn` that ensures all
|
|
21
|
+
* the subprocess is killed when the main process exits for any
|
|
22
|
+
* handle-able exit code or signal. */ const createSubprocess = (
|
|
23
|
+
argv,
|
|
24
|
+
options,
|
|
25
|
+
) => {
|
|
26
|
+
const subprocess = Bun.spawn(argv, options);
|
|
27
|
+
SUBPROCESS_REGISTRY[subprocess.pid] = subprocess;
|
|
28
|
+
subprocess.exited.finally(() => {
|
|
29
|
+
delete SUBPROCESS_REGISTRY[subprocess.pid];
|
|
30
|
+
});
|
|
31
|
+
return subprocess;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { createSubprocess };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Workspace } from "../workspace";
|
|
2
|
+
export type DependencyCycleEdge = {
|
|
3
|
+
dependency: string;
|
|
4
|
+
dependent: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const preventDependencyCycles: (workspaces: Workspace[]) => {
|
|
7
|
+
workspaces: Workspace[];
|
|
8
|
+
cycles: DependencyCycleEdge[];
|
|
9
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// CONCATENATED MODULE: ./src/workspaces/dependencyGraph/cycles.ts
|
|
2
|
+
const preventDependencyCycles = (workspaces) => {
|
|
3
|
+
const byName = new Map(workspaces.map((n) => [n.name, n]));
|
|
4
|
+
// memo: name -> chains that end at `name`
|
|
5
|
+
const memo = new Map();
|
|
6
|
+
// recursion stack in order (root -> ... -> current)
|
|
7
|
+
const stack = [];
|
|
8
|
+
const inStack = new Set();
|
|
9
|
+
// dedupe cycle edges
|
|
10
|
+
const cyclesKeyed = new Map();
|
|
11
|
+
// all nodes that participate in at least one cycle
|
|
12
|
+
const cycleNodeSet = new Set();
|
|
13
|
+
const recordCycleEdge = (dependency, dependent) => {
|
|
14
|
+
const key = `${dependency}\u0000${dependent}`;
|
|
15
|
+
if (!cyclesKeyed.has(key))
|
|
16
|
+
cyclesKeyed.set(key, {
|
|
17
|
+
dependency,
|
|
18
|
+
dependent,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
const chainsTo = (name) => {
|
|
22
|
+
const cached = memo.get(name);
|
|
23
|
+
if (cached) return cached;
|
|
24
|
+
stack.push(name);
|
|
25
|
+
inStack.add(name);
|
|
26
|
+
const node = byName.get(name);
|
|
27
|
+
const deps = node?.dependencies ?? [];
|
|
28
|
+
const result = [];
|
|
29
|
+
if (deps.length === 0) {
|
|
30
|
+
memo.set(name, result);
|
|
31
|
+
inStack.delete(name);
|
|
32
|
+
stack.pop();
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
for (const dep of deps) {
|
|
36
|
+
// Cycle edge: current `name` depends on `dep`, and `dep` is already in the active stack
|
|
37
|
+
if (inStack.has(dep)) {
|
|
38
|
+
recordCycleEdge(dep, name);
|
|
39
|
+
// Mark every node between `dep` and `name` (inclusive) as a cycle participant.
|
|
40
|
+
// `name` is already at stack[stack.length - 1] since it was pushed above.
|
|
41
|
+
const depIndex = stack.indexOf(dep);
|
|
42
|
+
for (let i = depIndex; i < stack.length; i++)
|
|
43
|
+
cycleNodeSet.add(stack[i]);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
// Missing dependency name: treat as a leaf chain [dep, name]
|
|
47
|
+
if (!byName.has(dep)) {
|
|
48
|
+
result.push([dep, name]);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const depChains = chainsTo(dep);
|
|
52
|
+
if (depChains.length === 0) {
|
|
53
|
+
// dep is a leaf => base chain
|
|
54
|
+
result.push([dep, name]);
|
|
55
|
+
} else {
|
|
56
|
+
// extend each dep chain with current dependent
|
|
57
|
+
for (const c of depChains) result.push([...c, name]);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
memo.set(name, result);
|
|
61
|
+
inStack.delete(name);
|
|
62
|
+
stack.pop();
|
|
63
|
+
return result;
|
|
64
|
+
};
|
|
65
|
+
workspaces.forEach((workspace) => {
|
|
66
|
+
chainsTo(workspace.name);
|
|
67
|
+
});
|
|
68
|
+
workspaces = workspaces.map((workspace) => ({
|
|
69
|
+
...workspace,
|
|
70
|
+
}));
|
|
71
|
+
const cycles = [...cyclesKeyed.values()];
|
|
72
|
+
// Remove all dependency/dependent edges between workspaces that share a cycle.
|
|
73
|
+
// This leaves no opinionated "winner": if two workspaces are in the same cycle,
|
|
74
|
+
// all edges between them are stripped.
|
|
75
|
+
for (const workspace of workspaces) {
|
|
76
|
+
if (cycleNodeSet.has(workspace.name)) {
|
|
77
|
+
workspace.dependencies = workspace.dependencies.filter(
|
|
78
|
+
(d) => !cycleNodeSet.has(d),
|
|
79
|
+
);
|
|
80
|
+
workspace.dependents = workspace.dependents.filter(
|
|
81
|
+
(d) => !cycleNodeSet.has(d),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
workspaces,
|
|
87
|
+
cycles,
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export { preventDependencyCycles };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ResolvedWorkspaceConfig } from "../../config";
|
|
2
|
+
import {
|
|
3
|
+
type BunCatalogSet,
|
|
4
|
+
type ResolvedPackageJsonContent,
|
|
5
|
+
} from "../packageJson";
|
|
6
|
+
import type { Workspace } from "../workspace";
|
|
7
|
+
export type WorkspaceMap = {
|
|
8
|
+
[workspaceName: string]: {
|
|
9
|
+
workspace: Workspace;
|
|
10
|
+
config: ResolvedWorkspaceConfig;
|
|
11
|
+
packageJson: ResolvedPackageJsonContent;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export declare const resolveWorkspaceDependencies: (
|
|
15
|
+
workspaceMap: WorkspaceMap,
|
|
16
|
+
includeRootWorkspace: boolean,
|
|
17
|
+
catalogs?: BunCatalogSet,
|
|
18
|
+
) => Workspace[];
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { resolveCatalogDependencyVersion } from "../packageJson.mjs"; // CONCATENATED MODULE: external "../packageJson.mjs"
|
|
2
|
+
// CONCATENATED MODULE: ./src/workspaces/dependencyGraph/resolveDependencies.ts
|
|
3
|
+
|
|
4
|
+
const resolveWorkspaceDependencies = (
|
|
5
|
+
workspaceMap,
|
|
6
|
+
includeRootWorkspace,
|
|
7
|
+
catalogs,
|
|
8
|
+
) => {
|
|
9
|
+
const workspacePackages = Object.values(workspaceMap).filter(
|
|
10
|
+
({ workspace }) => includeRootWorkspace || !workspace.isRoot,
|
|
11
|
+
);
|
|
12
|
+
const workspacesWithDependencies = workspacePackages.map(
|
|
13
|
+
({ workspace, packageJson }) => {
|
|
14
|
+
for (const dependencyMap of [
|
|
15
|
+
packageJson.dependencies,
|
|
16
|
+
packageJson.devDependencies,
|
|
17
|
+
packageJson.peerDependencies,
|
|
18
|
+
packageJson.optionalDependencies,
|
|
19
|
+
]) {
|
|
20
|
+
for (const [dependencyName, dependencyVersion] of Object.entries(
|
|
21
|
+
dependencyMap,
|
|
22
|
+
)) {
|
|
23
|
+
const resolvedVersion =
|
|
24
|
+
catalogs && dependencyVersion.startsWith("catalog:")
|
|
25
|
+
? (resolveCatalogDependencyVersion(
|
|
26
|
+
dependencyName,
|
|
27
|
+
dependencyVersion,
|
|
28
|
+
catalogs,
|
|
29
|
+
) ?? dependencyVersion)
|
|
30
|
+
: dependencyVersion;
|
|
31
|
+
if (
|
|
32
|
+
resolvedVersion.startsWith("workspace:") &&
|
|
33
|
+
workspaceMap[dependencyName]
|
|
34
|
+
) {
|
|
35
|
+
workspace.dependencies.push(dependencyName);
|
|
36
|
+
workspaceMap[dependencyName].workspace.dependents.push(
|
|
37
|
+
workspace.name,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return workspace;
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
return workspacesWithDependencies.map((workspace) => {
|
|
46
|
+
workspace.dependencies = [...new Set(workspace.dependencies)].sort();
|
|
47
|
+
workspace.dependents = [...new Set(workspace.dependents)].sort();
|
|
48
|
+
return workspace;
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export { resolveWorkspaceDependencies };
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
| "RootWorkspaceNotFound"
|
|
13
|
+
>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineErrors } from "../internal/core/index.mjs"; // CONCATENATED MODULE: external "../internal/core/index.mjs"
|
|
2
|
+
// CONCATENATED MODULE: ./src/workspaces/errors.ts
|
|
3
|
+
|
|
4
|
+
const WORKSPACE_ERRORS = defineErrors(
|
|
5
|
+
"PackageNotFound",
|
|
6
|
+
"InvalidPackageJson",
|
|
7
|
+
"DuplicateWorkspaceName",
|
|
8
|
+
"InvalidWorkspaceName",
|
|
9
|
+
"NoWorkspaceName",
|
|
10
|
+
"InvalidScripts",
|
|
11
|
+
"InvalidWorkspaces",
|
|
12
|
+
"InvalidWorkspacePattern",
|
|
13
|
+
"AliasConflict",
|
|
14
|
+
"AliasedWorkspaceNotFound",
|
|
15
|
+
"RootWorkspaceNotFound",
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
export { WORKSPACE_ERRORS };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type WorkspaceMap } from "./dependencyGraph/resolveDependencies";
|
|
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
|
+
/** Whether to include the root workspace as a normal workspace.*/
|
|
8
|
+
includeRootWorkspace?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare const sortWorkspaces: (workspaces: Workspace[]) => Workspace[];
|
|
11
|
+
export declare const findWorkspaces: ({
|
|
12
|
+
rootDirectory,
|
|
13
|
+
workspaceGlobs: _workspaceGlobs,
|
|
14
|
+
includeRootWorkspace,
|
|
15
|
+
}: FindWorkspacesOptions) => {
|
|
16
|
+
workspaces: Workspace[];
|
|
17
|
+
workspaceMap: WorkspaceMap;
|
|
18
|
+
rootWorkspace: Workspace;
|
|
19
|
+
};
|
|
20
|
+
export declare const validateWorkspaceAliases: (
|
|
21
|
+
workspaces: Workspace[],
|
|
22
|
+
workspaceAliases: Record<string, string>,
|
|
23
|
+
rootWorkspaceName: string,
|
|
24
|
+
) => void;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import bun from "bun";
|
|
4
|
+
import {
|
|
5
|
+
createDefaultWorkspaceConfig,
|
|
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 { logger } from "../internal/logger/logger.mjs";
|
|
11
|
+
import { resolveWorkspaceDependencies } from "./dependencyGraph/resolveDependencies.mjs";
|
|
12
|
+
import { WORKSPACE_ERRORS } from "./errors.mjs";
|
|
13
|
+
import {
|
|
14
|
+
resolvePackageJsonContent,
|
|
15
|
+
resolvePackageJsonPath,
|
|
16
|
+
} from "./packageJson.mjs"; // CONCATENATED MODULE: external "fs"
|
|
17
|
+
// CONCATENATED MODULE: external "path"
|
|
18
|
+
// CONCATENATED MODULE: external "bun"
|
|
19
|
+
// CONCATENATED MODULE: external "../config/index.mjs"
|
|
20
|
+
// CONCATENATED MODULE: external "../internal/bun/index.mjs"
|
|
21
|
+
// CONCATENATED MODULE: external "../internal/core/index.mjs"
|
|
22
|
+
// CONCATENATED MODULE: external "../internal/logger/logger.mjs"
|
|
23
|
+
// CONCATENATED MODULE: external "./dependencyGraph/resolveDependencies.mjs"
|
|
24
|
+
// CONCATENATED MODULE: external "./errors.mjs"
|
|
25
|
+
// CONCATENATED MODULE: external "./packageJson.mjs"
|
|
26
|
+
// CONCATENATED MODULE: ./src/workspaces/findWorkspaces.ts
|
|
27
|
+
|
|
28
|
+
const sortWorkspaces = (workspaces) =>
|
|
29
|
+
[...workspaces]
|
|
30
|
+
.sort((a, b) =>
|
|
31
|
+
a.isRoot
|
|
32
|
+
? -1
|
|
33
|
+
: a.path.localeCompare(b.path) || a.name.localeCompare(b.name),
|
|
34
|
+
)
|
|
35
|
+
.reduce((acc, workspace, i, arr) => {
|
|
36
|
+
const previousWorkspace = arr[i - 1];
|
|
37
|
+
if (previousWorkspace && previousWorkspace.path === workspace.path) {
|
|
38
|
+
return acc;
|
|
39
|
+
}
|
|
40
|
+
return [...acc, workspace];
|
|
41
|
+
}, []);
|
|
42
|
+
const getRootPackageJsonWorkspaceData = ({ rootDirectory }) => {
|
|
43
|
+
const packageJsonPath = path.join(rootDirectory, "package.json");
|
|
44
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
45
|
+
throw new WORKSPACE_ERRORS.PackageNotFound(
|
|
46
|
+
`No package.json found for project root at ${packageJsonPath}`,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
const { workspaces, catalog, catalogs } = resolvePackageJsonContent(
|
|
50
|
+
packageJsonPath,
|
|
51
|
+
rootDirectory,
|
|
52
|
+
["workspaces"],
|
|
53
|
+
);
|
|
54
|
+
return {
|
|
55
|
+
workspaceGlobs: workspaces ?? [],
|
|
56
|
+
catalog,
|
|
57
|
+
catalogs,
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
const validateWorkspace = (workspace, workspaces) => {
|
|
61
|
+
if (workspaces.find((ws) => ws.path === workspace.path)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
if (workspaces.find((ws) => ws.name === workspace.name)) {
|
|
65
|
+
throw new WORKSPACE_ERRORS.DuplicateWorkspaceName(
|
|
66
|
+
`Duplicate workspace name found: ${JSON.stringify(workspace.name)}`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
};
|
|
71
|
+
const findWorkspaces = ({
|
|
72
|
+
rootDirectory,
|
|
73
|
+
workspaceGlobs: _workspaceGlobs,
|
|
74
|
+
includeRootWorkspace = false,
|
|
75
|
+
}) => {
|
|
76
|
+
rootDirectory = path.resolve(rootDirectory);
|
|
77
|
+
logger.debug(`Finding workspaces in ${rootDirectory}`);
|
|
78
|
+
let workspaces = [];
|
|
79
|
+
const workspaceMap = {};
|
|
80
|
+
logger.debug(`Reading bun.lock`);
|
|
81
|
+
const bunLock = readBunLockfile(rootDirectory);
|
|
82
|
+
if (bunLock instanceof BunWorkspacesError) {
|
|
83
|
+
if (bunLock instanceof BUN_LOCK_ERRORS.BunLockNotFound) {
|
|
84
|
+
bunLock.message =
|
|
85
|
+
`No bun.lock found at ${rootDirectory}. Check that this is the directory of your project and that you've ran 'bun install'.` +
|
|
86
|
+
" If you have ran 'bun install', you may simply have no workspaces or dependencies in your project.";
|
|
87
|
+
}
|
|
88
|
+
throw bunLock;
|
|
89
|
+
}
|
|
90
|
+
const { workspaceGlobs, catalog, catalogs } = _workspaceGlobs
|
|
91
|
+
? {
|
|
92
|
+
workspaceGlobs: _workspaceGlobs,
|
|
93
|
+
catalog: {},
|
|
94
|
+
catalogs: {},
|
|
95
|
+
}
|
|
96
|
+
: getRootPackageJsonWorkspaceData({
|
|
97
|
+
rootDirectory,
|
|
98
|
+
});
|
|
99
|
+
const bunCatalogs = {
|
|
100
|
+
defaultCatalog: catalog,
|
|
101
|
+
namedCatalogs: catalogs,
|
|
102
|
+
};
|
|
103
|
+
let rootWorkspace;
|
|
104
|
+
const workspaceAliases = {};
|
|
105
|
+
for (const workspacePath of Object.keys(bunLock.workspaces).map((p) =>
|
|
106
|
+
path.join(rootDirectory, p),
|
|
107
|
+
)) {
|
|
108
|
+
const packageJsonPath = resolvePackageJsonPath(workspacePath);
|
|
109
|
+
if (packageJsonPath) {
|
|
110
|
+
const packageJsonContent = resolvePackageJsonContent(
|
|
111
|
+
packageJsonPath,
|
|
112
|
+
rootDirectory,
|
|
113
|
+
["name", "scripts"],
|
|
114
|
+
);
|
|
115
|
+
const workspaceConfig = loadWorkspaceConfig(
|
|
116
|
+
path.dirname(packageJsonPath),
|
|
117
|
+
);
|
|
118
|
+
if (workspaceConfig) {
|
|
119
|
+
for (const alias of workspaceConfig.aliases) {
|
|
120
|
+
workspaceAliases[alias] = packageJsonContent.name;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const relativePath = path.relative(
|
|
124
|
+
rootDirectory,
|
|
125
|
+
path.dirname(packageJsonPath),
|
|
126
|
+
);
|
|
127
|
+
const matchPattern =
|
|
128
|
+
workspaceGlobs.find((glob) => new bun.Glob(glob).match(relativePath)) ??
|
|
129
|
+
"";
|
|
130
|
+
const isRootWorkspace = workspacePath === rootDirectory;
|
|
131
|
+
if (!matchPattern && !isRootWorkspace) {
|
|
132
|
+
logger.debug(`No match pattern found for ${relativePath}`);
|
|
133
|
+
}
|
|
134
|
+
const workspace = {
|
|
135
|
+
name: packageJsonContent.name ?? "",
|
|
136
|
+
isRoot: isRootWorkspace,
|
|
137
|
+
matchPattern: workspacePath === rootDirectory ? "" : matchPattern,
|
|
138
|
+
path: path.relative(rootDirectory, path.dirname(packageJsonPath)),
|
|
139
|
+
scripts: Object.keys(packageJsonContent.scripts ?? {}).sort(),
|
|
140
|
+
aliases: [
|
|
141
|
+
...new Set(
|
|
142
|
+
Object.entries(workspaceAliases ?? {})
|
|
143
|
+
.filter(([_, value]) => value === packageJsonContent.name)
|
|
144
|
+
.map(([key]) => key)
|
|
145
|
+
.concat(workspaceConfig?.aliases ?? []),
|
|
146
|
+
),
|
|
147
|
+
],
|
|
148
|
+
dependencies: [],
|
|
149
|
+
dependents: [],
|
|
150
|
+
};
|
|
151
|
+
if (workspace.isRoot) {
|
|
152
|
+
logger.debug(`Found root workspace: ${workspace.name}`);
|
|
153
|
+
rootWorkspace = workspace;
|
|
154
|
+
}
|
|
155
|
+
if (validateWorkspace(workspace, workspaces)) {
|
|
156
|
+
if (!workspace.isRoot || includeRootWorkspace) {
|
|
157
|
+
workspaces.push(workspace);
|
|
158
|
+
}
|
|
159
|
+
workspaceMap[workspace.name] = {
|
|
160
|
+
workspace,
|
|
161
|
+
config: workspaceConfig ?? createDefaultWorkspaceConfig(),
|
|
162
|
+
packageJson: packageJsonContent,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (!rootWorkspace) {
|
|
168
|
+
throw new WORKSPACE_ERRORS.RootWorkspaceNotFound("No root workspace found");
|
|
169
|
+
}
|
|
170
|
+
workspaces = sortWorkspaces(
|
|
171
|
+
resolveWorkspaceDependencies(
|
|
172
|
+
workspaceMap,
|
|
173
|
+
includeRootWorkspace,
|
|
174
|
+
bunCatalogs,
|
|
175
|
+
),
|
|
176
|
+
);
|
|
177
|
+
validateWorkspaceAliases(workspaces, workspaceAliases, rootWorkspace.name);
|
|
178
|
+
logger.debug(
|
|
179
|
+
`Found ${workspaces.length} workspaces: ${workspaces.map((ws) => ws.name).join(", ")}`,
|
|
180
|
+
);
|
|
181
|
+
return {
|
|
182
|
+
workspaces,
|
|
183
|
+
workspaceMap,
|
|
184
|
+
rootWorkspace,
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
const validateWorkspaceAliases = (
|
|
188
|
+
workspaces,
|
|
189
|
+
workspaceAliases,
|
|
190
|
+
rootWorkspaceName,
|
|
191
|
+
) => {
|
|
192
|
+
for (const [alias, name] of Object.entries(workspaceAliases ?? {})) {
|
|
193
|
+
if (workspaces.find((ws) => ws.name === alias)) {
|
|
194
|
+
throw new WORKSPACE_ERRORS.AliasConflict(
|
|
195
|
+
`Alias ${JSON.stringify(alias)} conflicts with workspace name ${JSON.stringify(name)}`,
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
const workspaceWithDuplicateAlias = workspaces.find(
|
|
199
|
+
(ws) => ws.name !== name && ws.aliases.includes(alias),
|
|
200
|
+
);
|
|
201
|
+
if (workspaceWithDuplicateAlias) {
|
|
202
|
+
throw new WORKSPACE_ERRORS.AliasConflict(
|
|
203
|
+
`Workspaces ${JSON.stringify(name)} and ${JSON.stringify(workspaceWithDuplicateAlias.name)} have the same alias ${JSON.stringify(alias)}`,
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
if (
|
|
207
|
+
!workspaces.find((ws) => ws.name === name) &&
|
|
208
|
+
name !== rootWorkspaceName
|
|
209
|
+
) {
|
|
210
|
+
throw new WORKSPACE_ERRORS.AliasedWorkspaceNotFound(
|
|
211
|
+
`Workspace ${JSON.stringify(name)} was aliased by ${JSON.stringify(alias)} but was not found`,
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export { findWorkspaces, sortWorkspaces, validateWorkspaceAliases };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare const resolvePackageJsonPath: (directoryItem: string) => string;
|
|
2
|
+
export type BunCatalog = Record<string, string>;
|
|
3
|
+
export type BunCatalogSet = {
|
|
4
|
+
defaultCatalog: BunCatalog;
|
|
5
|
+
namedCatalogs: Record<string, BunCatalog>;
|
|
6
|
+
};
|
|
7
|
+
export type ResolvedPackageJsonContent = {
|
|
8
|
+
name: string;
|
|
9
|
+
workspaces: string[];
|
|
10
|
+
catalog: BunCatalog;
|
|
11
|
+
catalogs: Record<string, BunCatalog>;
|
|
12
|
+
scripts: Record<string, string>;
|
|
13
|
+
dependencies: Record<string, string>;
|
|
14
|
+
devDependencies: Record<string, string>;
|
|
15
|
+
peerDependencies: Record<string, string>;
|
|
16
|
+
optionalDependencies: Record<string, string>;
|
|
17
|
+
} & Record<string, unknown>;
|
|
18
|
+
/**
|
|
19
|
+
* Resolve a `catalog:` or `catalog:name` version reference for a given package name.
|
|
20
|
+
* Returns the resolved version string, or null if the catalog or package is not found.
|
|
21
|
+
*/
|
|
22
|
+
export declare const resolveCatalogDependencyVersion: (
|
|
23
|
+
packageName: string,
|
|
24
|
+
catalogRef: string,
|
|
25
|
+
catalogs: BunCatalogSet,
|
|
26
|
+
) => string | null;
|
|
27
|
+
export declare const resolvePackageJsonContent: (
|
|
28
|
+
packageJsonPath: string,
|
|
29
|
+
rootDirectory: string,
|
|
30
|
+
validations: ("workspaces" | "name" | "scripts")[],
|
|
31
|
+
) => ResolvedPackageJsonContent;
|