bun-workspaces 1.0.0-alpha.36 → 1.0.0-alpha.38

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 (32) hide show
  1. package/README.md +24 -13
  2. package/package.json +1 -1
  3. package/src/cli/commands/commandHandlerUtils.mjs +2 -0
  4. package/src/cli/commands/commands.mjs +3 -3
  5. package/src/cli/commands/commandsConfig.d.ts +16 -0
  6. package/src/cli/commands/commandsConfig.mjs +10 -0
  7. package/src/cli/commands/index.d.ts +1 -0
  8. package/src/cli/commands/index.mjs +2 -1
  9. package/src/cli/commands/runScript/formatRunScriptOutput.d.ts +19 -0
  10. package/src/cli/commands/runScript/formatRunScriptOutput.mjs +126 -0
  11. package/src/cli/commands/{handleRunScript.d.ts → runScript/handleRunScript.d.ts} +1 -1
  12. package/src/cli/commands/{handleRunScript.mjs → runScript/handleRunScript.mjs} +34 -20
  13. package/src/cli/commands/runScript/index.d.ts +2 -0
  14. package/src/cli/commands/runScript/index.mjs +2 -0
  15. package/src/config/util/loadConfig.d.ts +1 -1
  16. package/src/index.d.ts +5 -1
  17. package/src/index.mjs +8 -1
  18. package/src/internal/logger/logger.d.ts +0 -6
  19. package/src/internal/logger/logger.mjs +0 -24
  20. package/src/project/implementations/fileSystemProject.d.ts +42 -9
  21. package/src/project/implementations/fileSystemProject.mjs +50 -3
  22. package/src/runScript/output/multiProcessOutput.d.ts +14 -0
  23. package/src/runScript/output/multiProcessOutput.mjs +21 -0
  24. package/src/runScript/output/processOutput.d.ts +33 -0
  25. package/src/runScript/output/processOutput.mjs +124 -0
  26. package/src/runScript/outputChunk.d.ts +5 -3
  27. package/src/runScript/outputChunk.mjs +2 -2
  28. package/src/runScript/runScript.d.ts +10 -1
  29. package/src/runScript/runScript.mjs +20 -14
  30. package/src/runScript/runScripts.d.ts +20 -3
  31. package/src/runScript/runScripts.mjs +175 -32
  32. package/src/workspaces/dependencyGraph/cycles.mjs +17 -11
package/README.md CHANGED
@@ -67,6 +67,13 @@ bw run lint my-alias-a my-alias-b # Run by alias (set by optional config)
67
67
  bw run lint "my-workspace-*" # Run for matching workspace names
68
68
  bw run lint "alias:my-alias-pattern-*" "path:my-glob/**/*" # Use matching specifiers
69
69
 
70
+ # A workspace's script will wait until any workspaces it depends on have completed
71
+ # Similar to Bun's --filter behavior
72
+ bw run lint --dep-order
73
+
74
+ # Continue running scripts even if a dependency fails
75
+ bw run lint --dep-order --ignore-dep-failure
76
+
70
77
  bw run lint --args="--my-appended-args" # Add args to each script call
71
78
  bw run lint --args="--my-arg=<workspaceName>" # Use the workspace name in args
72
79
 
@@ -120,11 +127,10 @@ const runSingleScript = async () => {
120
127
  });
121
128
 
122
129
  // Get a stream of the script subprocess's output
123
- for await (const { outputChunk } of output) {
124
- // outputChunk.raw // The raw output content (Uint8Array)
125
- // outputChunk.decode() // The output chunk's content (string)
126
- // outputChunk.decode({ stripAnsi: true }) // Text with ANSI codes sanitized (string)
127
- // outputChunk.streamName // The output stream, "stdout" or "stderr"
130
+ for await (const { chunk, metadata } of output.text()) {
131
+ // console.log(chunk); // the content (string)
132
+ // console.log(metadata.streamName); // "stdout" or "stderr"
133
+ // console.log(metadata.workspace); // the workspace that the output came from
128
134
  }
129
135
 
130
136
  // Get data about the script execution after it exits
@@ -155,16 +161,21 @@ const runManyScripts = async () => {
155
161
 
156
162
  // Optional. Whether to run the scripts in parallel
157
163
  parallel: true,
164
+
165
+ // Optional. When true, a workspace's script will wait
166
+ // until any workspaces it depends on have completed
167
+ dependencyOrder: true,
168
+
169
+ // Optional. When true and dependencyOrder is true,
170
+ // continue running scripts even if a dependency fails
171
+ ignoreDependencyFailure: true,
158
172
  });
159
173
 
160
174
  // Get a stream of script output
161
- for await (const { outputChunk, scriptMetadata } of output) {
162
- // outputChunk.decode() // the output chunk's content (string)
163
- // outputChunk.decode({ stripAnsi: true }) // text with ANSI codes sanitized (string)
164
- // outputChunk.streamName // "stdout" or "stderr"
165
- // The metadata can distinguish which workspace script
166
- // the current output chunk came from
167
- // scriptMetadata.workspace // Workspace object
175
+ for await (const { chunk, metadata } of output.text()) {
176
+ // console.log(chunk); // the content (string)
177
+ // console.log(metadata.streamName); // "stdout" or "stderr"
178
+ // console.log(metadata.workspace); // the workspace that the output came from
168
179
  }
169
180
 
170
181
  // Get final summary data and script exit details after all scripts have completed
@@ -191,7 +202,7 @@ const runManyScripts = async () => {
191
202
  };
192
203
  ```
193
204
 
194
- _`bun-workspaces` is independent from the [Bun](https://bun.sh) project and is not affiliated with or endorsed by Anthropic. This project aims to enhance enhance the experience of Bun for its users._
205
+ _`bun-workspaces` is independent from the [Bun](https://bun.sh) project and is not affiliated with or endorsed by Anthropic. This project aims to enhance the experience of Bun for its users._
195
206
 
196
207
  Developed By:
197
208
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bun-workspaces",
3
- "version": "1.0.0-alpha.36",
3
+ "version": "1.0.0-alpha.38",
4
4
  "description": "A monorepo management tool for Bun, with a CLI and API to enhance Bun's native workspaces.",
5
5
  "license": "MIT",
6
6
  "main": "src/index.mjs",
@@ -19,6 +19,8 @@ const createWorkspaceInfoLines = (workspace) => [
19
19
  ` - Path: ${workspace.path}`,
20
20
  ` - Glob Match: ${workspace.matchPattern}`,
21
21
  ` - Scripts: ${workspace.scripts.join(", ")}`,
22
+ ` - Dependencies: ${workspace.dependencies.join(", ")}`,
23
+ ` - Dependents: ${workspace.dependents.join(", ")}`,
22
24
  ];
23
25
  const createScriptInfoLines = (script, workspaces) => [
24
26
  `Script: ${script}`,
@@ -1,12 +1,12 @@
1
- import { runScript } from "./handleRunScript.mjs";
2
1
  import {
3
2
  doctor,
4
3
  listScripts,
5
4
  listWorkspaces,
6
5
  scriptInfo,
7
6
  workspaceInfo,
8
- } from "./handleSimpleCommands.mjs"; // CONCATENATED MODULE: external "./handleRunScript.mjs"
9
- // CONCATENATED MODULE: external "./handleSimpleCommands.mjs"
7
+ } from "./handleSimpleCommands.mjs";
8
+ import { runScript } from "./runScript/index.mjs"; // CONCATENATED MODULE: external "./handleSimpleCommands.mjs"
9
+ // CONCATENATED MODULE: external "./runScript/index.mjs"
10
10
  // CONCATENATED MODULE: ./src/cli/commands/commands.ts
11
11
 
12
12
  const defineGlobalCommands = (context) => {
@@ -161,6 +161,14 @@ export declare const CLI_COMMANDS_CONFIG: {
161
161
  readonly values: ["bun", "system", "default"];
162
162
  readonly description: "When using --inline, the shell to use to run the script";
163
163
  };
164
+ readonly depOrder: {
165
+ readonly flags: ["-d", "--dep-order"];
166
+ readonly description: "Scripts for dependent workspaces run only after their dependencies";
167
+ };
168
+ readonly ignoreDepFailure: {
169
+ readonly flags: ["-f", "--ignore-dep-failure"];
170
+ readonly description: "In dependency order, continue running scripts even if a dependency fails";
171
+ };
164
172
  readonly jsonOutfile: {
165
173
  readonly flags: ["-j", "--json-outfile <file>"];
166
174
  readonly description: "Output results in a JSON file";
@@ -304,6 +312,14 @@ export declare const getCliCommandConfig: (commandName: CliCommandName) =>
304
312
  readonly values: ["bun", "system", "default"];
305
313
  readonly description: "When using --inline, the shell to use to run the script";
306
314
  };
315
+ readonly depOrder: {
316
+ readonly flags: ["-d", "--dep-order"];
317
+ readonly description: "Scripts for dependent workspaces run only after their dependencies";
318
+ };
319
+ readonly ignoreDepFailure: {
320
+ readonly flags: ["-f", "--ignore-dep-failure"];
321
+ readonly description: "In dependency order, continue running scripts even if a dependency fails";
322
+ };
307
323
  readonly jsonOutfile: {
308
324
  readonly flags: ["-j", "--json-outfile <file>"];
309
325
  readonly description: "Output results in a JSON file";
@@ -141,6 +141,16 @@ const CLI_COMMANDS_CONFIG = {
141
141
  values: [...SCRIPT_SHELL_OPTIONS, "default"],
142
142
  description: `When using --inline, the shell to use to run the script`,
143
143
  },
144
+ depOrder: {
145
+ flags: ["-d", "--dep-order"],
146
+ description:
147
+ "Scripts for dependent workspaces run only after their dependencies",
148
+ },
149
+ ignoreDepFailure: {
150
+ flags: ["-f", "--ignore-dep-failure"],
151
+ description:
152
+ "In dependency order, continue running scripts even if a dependency fails",
153
+ },
144
154
  jsonOutfile: {
145
155
  flags: ["-j", "--json-outfile <file>"],
146
156
  description: "Output results in a JSON file",
@@ -1,2 +1,3 @@
1
1
  export * from "./commands";
2
2
  export * from "./commandsConfig";
3
+ export * from "./runScript";
@@ -1,2 +1,3 @@
1
1
  export * from "./commands.mjs";
2
- export * from "./commandsConfig.mjs"; // CONCATENATED MODULE: ./src/cli/commands/index.ts
2
+ export * from "./commandsConfig.mjs";
3
+ export * from "./runScript/index.mjs"; // CONCATENATED MODULE: ./src/cli/commands/index.ts
@@ -0,0 +1,19 @@
1
+ import type {
2
+ RunScriptAcrossWorkspacesProcessOutput,
3
+ RunWorkspaceScriptMetadata,
4
+ } from "../../../project";
5
+ import type { OutputStreamName } from "../../../runScript";
6
+ export type FormatRunScriptOutputOptions = {
7
+ stripDisruptiveControls?: boolean;
8
+ prefix?: boolean;
9
+ scriptName: string;
10
+ };
11
+ export declare function formatRunScriptOutput(
12
+ output: RunScriptAcrossWorkspacesProcessOutput,
13
+ { scriptName, stripDisruptiveControls, prefix }: FormatRunScriptOutputOptions,
14
+ ): AsyncGenerator<{
15
+ line: string;
16
+ metadata: RunWorkspaceScriptMetadata & {
17
+ streamName: OutputStreamName;
18
+ };
19
+ }>;
@@ -0,0 +1,126 @@
1
+ // CONCATENATED MODULE: ./src/cli/commands/runScript/formatRunScriptOutput.ts
2
+ const sanitizeChunk = (input, stripDisruptiveControls = false) => {
3
+ if (!stripDisruptiveControls) {
4
+ return input.replace(/\r\n/g, "\n");
5
+ }
6
+ // 1) Normalize newline-ish controls
7
+ let s = input
8
+ .replace(/\r\n/g, "\n")
9
+ .replace(/\r/g, "\n")
10
+ .replace(/\f/g, "\n")
11
+ .replace(/\v/g, "\n");
12
+ // 2) Remove disruptive single-byte controls (except \n, \t)
13
+ // - backspace, bell, and C1 controls
14
+ // eslint-disable-next-line no-control-regex
15
+ s = s.replace(/[\b\x07\x80-\x9F]/g, "");
16
+ // 3) Strip ANSI sequences, keeping only SGR (CSI ... m)
17
+ //
18
+ // We'll scan rather than rely on one giant regex so we can:
19
+ // - keep SGR exactly
20
+ // - drop any other ESC sequence
21
+ // - handle incomplete ESC sequences conservatively (drop the ESC byte itself)
22
+ //
23
+ // ESC = \x1B
24
+ const ESC = "\x1B";
25
+ let out = "";
26
+ for (let i = 0; i < s.length; i++) {
27
+ const ch = s[i];
28
+ if (ch !== ESC) {
29
+ out += ch;
30
+ continue;
31
+ }
32
+ // If ESC is last char, drop it
33
+ if (i + 1 >= s.length) break;
34
+ const next = s[i + 1];
35
+ // Keep only CSI ... m (ESC [ ... m)
36
+ if (next === "[") {
37
+ // Find final byte of CSI sequence (per spec: 0x40-0x7E).
38
+ // We only keep it if the final byte is 'm'.
39
+ let j = i + 2;
40
+ while (j < s.length) {
41
+ const code = s.charCodeAt(j);
42
+ if (code >= 0x40 && code <= 0x7e) break; // final byte
43
+ j++;
44
+ }
45
+ // If we didn't find a final byte, drop the ESC and stop (incomplete)
46
+ if (j >= s.length) break;
47
+ const finalByte = s[j];
48
+ if (finalByte === "m") {
49
+ // Keep full SGR sequence
50
+ out += s.slice(i, j + 1);
51
+ }
52
+ // else: drop the entire CSI sequence
53
+ i = j; // advance past sequence
54
+ continue;
55
+ }
56
+ // All other ESC sequences: drop them.
57
+ //
58
+ // For 2-byte sequences (like ESC c), we can just drop ESC+next.
59
+ // For string-terminated families (OSC/DCS/APC/PM/SOS), we should skip until terminator.
60
+ //
61
+ // OSC: ESC ] ... (BEL or ESC \)
62
+ // DCS: ESC P ... (ST = ESC \)
63
+ // APC: ESC _ ... (ST)
64
+ // PM : ESC ^ ... (ST)
65
+ // SOS: ESC X ... (ST)
66
+ if (
67
+ next === "]" ||
68
+ next === "P" ||
69
+ next === "_" ||
70
+ next === "^" ||
71
+ next === "X"
72
+ ) {
73
+ let j = i + 2;
74
+ while (j < s.length) {
75
+ const c = s[j];
76
+ // BEL terminator (OSC can end with BEL)
77
+ if (c === "\x07") {
78
+ j++;
79
+ break;
80
+ }
81
+ // ST terminator: ESC \
82
+ if (c === ESC && j + 1 < s.length && s[j + 1] === "\\") {
83
+ j += 2;
84
+ break;
85
+ }
86
+ j++;
87
+ }
88
+ i = j - 1; // -1 because loop will i++
89
+ continue;
90
+ }
91
+ // Fallback: treat as a 2-byte escape and drop ESC + next.
92
+ i += 1;
93
+ }
94
+ return out;
95
+ };
96
+ async function* formatRunScriptOutput(
97
+ output,
98
+ { scriptName, stripDisruptiveControls = true, prefix = false },
99
+ ) {
100
+ const workspaceLineBuffers = {};
101
+ const formatLine = (line, workspaceName, scriptName) => {
102
+ const prefixedLine = prefix
103
+ ? `[${workspaceName}:${scriptName}] ${line}`
104
+ : line;
105
+ return `\x1b[0m${prefixedLine}\n`;
106
+ };
107
+ for await (const { metadata, chunk } of output.text()) {
108
+ const workspaceName = metadata.workspace.name;
109
+ const sanitizedChunk = sanitizeChunk(chunk, stripDisruptiveControls);
110
+ const prior = workspaceLineBuffers[workspaceName] ?? "";
111
+ const content = prior + sanitizedChunk;
112
+ const lines = content.split("\n");
113
+ for (const line of lines) {
114
+ if (line)
115
+ yield {
116
+ line: formatLine(line, workspaceName, scriptName),
117
+ metadata,
118
+ };
119
+ }
120
+ workspaceLineBuffers[workspaceName] = content.endsWith("\n")
121
+ ? ""
122
+ : (lines[lines.length - 1] ?? "");
123
+ }
124
+ }
125
+
126
+ export { formatRunScriptOutput };
@@ -1,3 +1,3 @@
1
1
  export declare const runScript: (
2
- context: import("./commandHandlerUtils").ProjectCommandContext,
2
+ context: import("../commandHandlerUtils").ProjectCommandContext,
3
3
  ) => import("commander").Command;
@@ -1,15 +1,16 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import { logger } from "../../internal/logger/index.mjs";
3
+ import { logger } from "../../../internal/logger/index.mjs";
4
4
  import {
5
- commandOutputLogger,
6
5
  handleProjectCommand,
7
6
  splitWorkspacePatterns,
8
- } from "./commandHandlerUtils.mjs"; // CONCATENATED MODULE: external "fs"
7
+ } from "../commandHandlerUtils.mjs";
8
+ import { formatRunScriptOutput } from "./formatRunScriptOutput.mjs"; // CONCATENATED MODULE: external "fs"
9
9
  // CONCATENATED MODULE: external "path"
10
- // CONCATENATED MODULE: external "../../internal/logger/index.mjs"
11
- // CONCATENATED MODULE: external "./commandHandlerUtils.mjs"
12
- // CONCATENATED MODULE: ./src/cli/commands/handleRunScript.ts
10
+ // CONCATENATED MODULE: external "../../../internal/logger/index.mjs"
11
+ // CONCATENATED MODULE: external "../commandHandlerUtils.mjs"
12
+ // CONCATENATED MODULE: external "./formatRunScriptOutput.mjs"
13
+ // CONCATENATED MODULE: ./src/cli/commands/runScript/handleRunScript.ts
13
14
 
14
15
  const runScript = handleProjectCommand(
15
16
  "runScript",
@@ -52,6 +53,9 @@ const runScript = handleProjectCommand(
52
53
  logger.debug(
53
54
  `Command: Run script ${JSON.stringify(script)} for ${workspacePatterns.length ? "workspaces " + workspacePatterns.join(", ") : "all workspaces"} (parallel: ${!!options.parallel}, args: ${JSON.stringify(scriptArgs)})`,
54
55
  );
56
+ const workspaceCount = project.findWorkspacesByPattern(
57
+ ...workspacePatterns,
58
+ ).length;
55
59
  const { output, summary } = project.runScriptAcrossWorkspaces({
56
60
  workspacePatterns: workspacePatterns.length
57
61
  ? workspacePatterns
@@ -66,6 +70,8 @@ const runScript = handleProjectCommand(
66
70
  : true
67
71
  : undefined,
68
72
  args: scriptArgs,
73
+ dependencyOrder: options.depOrder,
74
+ ignoreDependencyFailure: options.ignoreDepFailure,
69
75
  parallel:
70
76
  typeof options.parallel === "boolean" ||
71
77
  typeof options.parallel === "undefined"
@@ -83,33 +89,41 @@ const runScript = handleProjectCommand(
83
89
  : script;
84
90
  const handleOutput = async () => {
85
91
  if (logger.printLevel === "silent") return;
86
- for await (const { outputChunk, scriptMetadata } of output) {
87
- commandOutputLogger.logOutput(
88
- outputChunk.decode(),
89
- "info",
90
- process[outputChunk.streamName],
91
- options.prefix
92
- ? `[${scriptMetadata.workspace.name}:${scriptName}] `
93
- : "",
94
- );
92
+ for await (const { line, metadata } of formatRunScriptOutput(output, {
93
+ prefix: options.prefix,
94
+ scriptName,
95
+ stripDisruptiveControls: workspaceCount > 1 || !!options.parallel,
96
+ })) {
97
+ process[metadata.streamName].write(line);
95
98
  }
96
99
  };
97
100
  handleOutput();
98
101
  const exitResults = await summary;
99
102
  exitResults.scriptResults.forEach(
100
103
  ({ success, metadata: { workspace }, exitCode }) => {
101
- logger.info(
102
- `${success ? "✅" : "❌"} ${workspace.name}: ${scriptName}${exitCode ? ` (exited with code ${exitCode})` : ""}`,
103
- );
104
+ const isSkipped = exitCode === -1;
105
+ if (isSkipped) {
106
+ logger.info(
107
+ `➖ ${workspace.name}: ${scriptName} (skipped due to dependency failure)`,
108
+ );
109
+ } else {
110
+ logger.info(
111
+ `${success ? "✅" : "❌"} ${workspace.name}: ${scriptName}${exitCode ? ` (exited with code ${exitCode})` : ""}`,
112
+ );
113
+ }
104
114
  },
105
115
  );
106
116
  const s = exitResults.scriptResults.length === 1 ? "" : "s";
117
+ const skippedCount = exitResults.scriptResults.filter(
118
+ ({ exitCode }) => exitCode === -1,
119
+ ).length;
120
+ const skippedMessage = skippedCount ? ` (${skippedCount} skipped)` : "";
107
121
  if (exitResults.failureCount) {
108
- const message = `${exitResults.failureCount} of ${exitResults.scriptResults.length} script${s} failed`;
122
+ const message = `${exitResults.failureCount} of ${exitResults.scriptResults.length} script${s} failed${skippedMessage}`;
109
123
  logger.info(message);
110
124
  } else {
111
125
  logger.info(
112
- `${exitResults.scriptResults.length} script${s} ran successfully`,
126
+ `${exitResults.scriptResults.length} script${s} ran successfully${skippedMessage}`,
113
127
  );
114
128
  }
115
129
  if (options.jsonOutfile) {
@@ -0,0 +1,2 @@
1
+ export * from "./handleRunScript";
2
+ export * from "./formatRunScriptOutput";
@@ -0,0 +1,2 @@
1
+ export * from "./handleRunScript.mjs";
2
+ export * from "./formatRunScriptOutput.mjs"; // CONCATENATED MODULE: ./src/cli/commands/runScript/index.ts
@@ -1,6 +1,6 @@
1
1
  import { type AnyFunction } from "../../internal/core";
2
2
  import { type ConfigLocation } from "./configLocation";
3
- export declare const InvalidJSONError: typeof import("../../internal/core").BunWorkspacesError;
3
+ export declare const InvalidJSONError: typeof import("../..").BunWorkspacesError;
4
4
  export declare const getConfigLocation: (
5
5
  name: string,
6
6
  directory: string,
package/src/index.d.ts CHANGED
@@ -11,9 +11,13 @@ export {
11
11
  type WorkspaceScriptMetadata,
12
12
  type RunWorkspaceScriptMetadata,
13
13
  type RunWorkspaceScriptOptions,
14
+ type RunWorkspaceScriptExit,
14
15
  type RunWorkspaceScriptResult,
15
16
  type InlineScriptOptions,
16
17
  type RunScriptAcrossWorkspacesOptions,
18
+ type RunScriptAcrossWorkspacesOutput,
19
+ type RunScriptAcrossWorkspacesSummary,
20
+ type RunScriptAcrossWorkspacesProcessOutput,
17
21
  type RunScriptAcrossWorkspacesResult,
18
22
  type ParallelOption,
19
23
  type ShellOption,
@@ -28,5 +32,5 @@ export {
28
32
  type RunScriptsParallelOptions,
29
33
  } from "./runScript";
30
34
  export { type Workspace } from "./workspaces";
31
- export { type SimpleAsyncIterable } from "./internal/core";
35
+ export { type SimpleAsyncIterable, BunWorkspacesError } from "./internal/core";
32
36
  export { setLogLevel, type LogLevelSetting } from "./internal/logger";
package/src/index.mjs CHANGED
@@ -2,8 +2,15 @@ import {
2
2
  createFileSystemProject,
3
3
  createMemoryProject,
4
4
  } from "./project/index.mjs";
5
+ import { BunWorkspacesError } from "./internal/core/index.mjs";
5
6
  import { setLogLevel } from "./internal/logger/index.mjs"; // CONCATENATED MODULE: external "./project/index.mjs"
7
+ // CONCATENATED MODULE: external "./internal/core/index.mjs"
6
8
  // CONCATENATED MODULE: external "./internal/logger/index.mjs"
7
9
  // CONCATENATED MODULE: ./src/index.ts
8
10
 
9
- export { createFileSystemProject, createMemoryProject, setLogLevel };
11
+ export {
12
+ BunWorkspacesError,
13
+ createFileSystemProject,
14
+ createMemoryProject,
15
+ setLogLevel,
16
+ };
@@ -22,12 +22,6 @@ export type Logger = {
22
22
  level: LogLevel,
23
23
  metadata?: Metadata,
24
24
  ): Log<Message, Metadata>;
25
- logOutput(
26
- chunk: Uint8Array | string,
27
- level: LogLevel,
28
- stream: NodeJS.WriteStream,
29
- prefix: string,
30
- ): Log<string, Record<string, unknown>>;
31
25
  printLevel: LogLevelSetting;
32
26
  } & {
33
27
  [Level in LogLevel]: <
@@ -48,30 +48,6 @@ class _Logger {
48
48
  }
49
49
  return log;
50
50
  }
51
- logOutput(chunk, level, stream, prefix) {
52
- const message =
53
- typeof chunk === "string"
54
- ? chunk.trim()
55
- : new TextDecoder().decode(chunk).trim();
56
- const log = {
57
- message,
58
- level,
59
- metadata: {
60
- stream,
61
- isLogOutput: true,
62
- },
63
- time: new Date(),
64
- };
65
- if (!this.shouldPrint(level)) {
66
- return log;
67
- }
68
- const linePrefix = `${prefix}\x1b[0m`;
69
- const lines = message.split(/\r?\n/);
70
- lines.forEach((line) => {
71
- if (line) stream.write(linePrefix + line + "\n");
72
- });
73
- return log;
74
- }
75
51
  debug(message, metadata) {
76
52
  return this.log(message, "debug", metadata);
77
53
  }
@@ -1,9 +1,13 @@
1
- import type { Simplify } from "../../internal/core";
1
+ import type { SimpleAsyncIterable, Simplify } from "../../internal/core";
2
2
  import {
3
- type RunScriptResult,
4
- type RunScriptsResult,
5
3
  type RunScriptsParallelOptions,
4
+ type RunScriptsSummary,
5
+ type RunScriptsOutput,
6
+ type RunScriptExit,
7
+ type OutputChunk,
8
+ type OutputStreamName,
6
9
  } from "../../runScript";
10
+ import type { MultiProcessOutput } from "../../runScript/output/multiProcessOutput";
7
11
  import { type ScriptShellOption } from "../../runScript/scriptShellOption";
8
12
  import { type Workspace } from "../../workspaces";
9
13
  import type { Project, ProjectConfig } from "../project";
@@ -43,10 +47,21 @@ export type RunWorkspaceScriptOptions = {
43
47
  export type RunWorkspaceScriptMetadata = {
44
48
  workspace: Workspace;
45
49
  };
46
- /** Result of `FileSystemProject.runWorkspaceScript` */
47
- export type RunWorkspaceScriptResult = Simplify<
48
- RunScriptResult<RunWorkspaceScriptMetadata>
50
+ export type RunWorkspaceScriptExit = Simplify<
51
+ RunScriptExit<RunWorkspaceScriptMetadata>
49
52
  >;
53
+ export type RunWorkspaceScriptProcessOutput = MultiProcessOutput<
54
+ RunWorkspaceScriptMetadata & {
55
+ streamName: OutputStreamName;
56
+ }
57
+ > &
58
+ /** @deprecated */
59
+ SimpleAsyncIterable<OutputChunk>;
60
+ /** Result of `FileSystemProject.runWorkspaceScript` */
61
+ export type RunWorkspaceScriptResult = {
62
+ output: RunWorkspaceScriptProcessOutput;
63
+ exit: Promise<RunWorkspaceScriptExit>;
64
+ };
50
65
  export type ParallelOption = boolean | RunScriptsParallelOptions;
51
66
  /** Arguments for `FileSystemProject.runScriptAcrossWorkspaces` */
52
67
  export type RunScriptAcrossWorkspacesOptions = {
@@ -64,11 +79,29 @@ export type RunScriptAcrossWorkspacesOptions = {
64
79
  args?: string;
65
80
  /** Whether to run the scripts in parallel (series by default) */
66
81
  parallel?: ParallelOption;
82
+ /** When `true`, run scripts so that dependent workspaces run only after their dependencies */
83
+ dependencyOrder?: boolean;
84
+ /** When `true`, continue running scripts even if a dependency fails (Only relevant when `dependencyOrder` is `true`) */
85
+ ignoreDependencyFailure?: boolean;
67
86
  };
68
- /** Result of `FileSystemProject.runScriptAcrossWorkspaces` */
69
- export type RunScriptAcrossWorkspacesResult = Simplify<
70
- RunScriptsResult<RunWorkspaceScriptMetadata>
87
+ export type RunScriptAcrossWorkspacesOutput = Simplify<
88
+ RunScriptsOutput<RunWorkspaceScriptMetadata>
71
89
  >;
90
+ export type RunScriptAcrossWorkspacesSummary = Simplify<
91
+ RunScriptsSummary<RunWorkspaceScriptMetadata>
92
+ >;
93
+ export type RunScriptAcrossWorkspacesProcessOutput = MultiProcessOutput<
94
+ RunWorkspaceScriptMetadata & {
95
+ streamName: OutputStreamName;
96
+ }
97
+ > &
98
+ /** @deprecated */
99
+ SimpleAsyncIterable<RunScriptAcrossWorkspacesOutput>;
100
+ /** Result of `FileSystemProject.runScriptAcrossWorkspaces` */
101
+ export type RunScriptAcrossWorkspacesResult = {
102
+ output: RunScriptAcrossWorkspacesProcessOutput;
103
+ summary: Promise<RunScriptAcrossWorkspacesSummary>;
104
+ };
72
105
  declare class _FileSystemProject extends ProjectBase implements Project {
73
106
  #private;
74
107
  readonly rootDirectory: string;