bun-workspaces 1.8.1 → 1.9.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 (47) hide show
  1. package/README.md +51 -13
  2. package/package.json +1 -1
  3. package/src/2392.mjs +184 -3
  4. package/src/5166.mjs +1 -0
  5. package/src/8529.mjs +10 -0
  6. package/src/affected/affectedBaseRef.mjs +12 -0
  7. package/src/affected/externalDependencyChanges.mjs +47 -0
  8. package/src/affected/fileAffectedWorkspaces.mjs +413 -0
  9. package/src/affected/gitAffectedFiles.mjs +196 -0
  10. package/src/affected/gitAffectedWorkspaces.mjs +108 -0
  11. package/src/affected/index.mjs +7 -0
  12. package/src/ai/mcp/serverState.mjs +1 -1
  13. package/src/cli/commands/commandHandlerUtils.mjs +12 -7
  14. package/src/cli/commands/commands.mjs +4 -1
  15. package/src/cli/commands/handleSimpleCommands.mjs +2 -2
  16. package/src/cli/commands/listAffected.mjs +184 -0
  17. package/src/cli/commands/runScript/handleRunAffected.mjs +99 -0
  18. package/src/cli/commands/runScript/handleRunScript.mjs +19 -202
  19. package/src/cli/commands/runScript/index.mjs +1 -0
  20. package/src/cli/commands/runScript/output/renderGroupedOutput.mjs +22 -7
  21. package/src/cli/commands/runScript/output/tuiTerminal.mjs +45 -0
  22. package/src/cli/commands/runScript/scriptRunFlow.mjs +213 -0
  23. package/src/cli/index.d.ts +749 -134
  24. package/src/config/public.d.ts +66 -2
  25. package/src/config/rootConfig/rootConfig.mjs +4 -0
  26. package/src/config/rootConfig/rootConfigSchema.mjs +3 -0
  27. package/src/config/workspaceConfig/mergeWorkspaceConfig.mjs +33 -19
  28. package/src/config/workspaceConfig/workspaceConfig.mjs +3 -0
  29. package/src/config/workspaceConfig/workspaceConfigSchema.mjs +26 -0
  30. package/src/index.d.ts +307 -5
  31. package/src/index.mjs +1 -0
  32. package/src/internal/bun/bunLock.mjs +33 -0
  33. package/src/internal/generated/aiDocs/docs.mjs +152 -3
  34. package/src/internal/generated/ajv/validateRootConfig.mjs +1 -1
  35. package/src/internal/generated/ajv/validateWorkspaceConfig.mjs +1 -1
  36. package/src/project/implementations/fileSystemProject/affectedWorkspaces.mjs +225 -0
  37. package/src/project/implementations/{fileSystemProject.mjs → fileSystemProject/fileSystemProject.mjs} +169 -12
  38. package/src/project/implementations/fileSystemProject/index.mjs +4 -0
  39. package/src/project/implementations/memoryProject.mjs +1 -0
  40. package/src/project/index.mjs +1 -1
  41. package/src/rslib-runtime.mjs +0 -31
  42. package/src/workspaces/applyWorkspacePatternConfigs.mjs +10 -1
  43. package/src/workspaces/dependencyGraph/resolveDependencies.mjs +68 -18
  44. package/src/workspaces/findWorkspaces.mjs +1 -0
  45. package/src/workspaces/index.mjs +1 -0
  46. package/src/workspaces/workspace.mjs +8 -2
  47. package/src/workspaces/workspacePattern.mjs +13 -3
@@ -59,10 +59,43 @@ const readBunLockfile = (directory) => {
59
59
  const jsonString = fs.readFileSync(bunLockPath, "utf8");
60
60
  return parseBunLock(jsonString, bunLockPath);
61
61
  };
62
+ const VERSION_SEPARATOR = "@";
63
+ const parseBunLockPackageVersions = (jsonString, bunLockPath) => {
64
+ let bunLockJson = null;
65
+ try {
66
+ bunLockJson = parseJSONC(jsonString);
67
+ } catch (error) {
68
+ return new BUN_LOCK_ERRORS.MalformedBunLock(
69
+ `Failed to parse bun lockfile ${bunLockPath ? `at "${bunLockPath}"` : ""}: ${error.message}`,
70
+ );
71
+ }
72
+ if (!isJSONObject(bunLockJson)) {
73
+ return new BUN_LOCK_ERRORS.MalformedBunLock(
74
+ `Bun lockfile ${bunLockPath ? `at "${bunLockPath}"` : ""} is not a valid JSON object`,
75
+ );
76
+ }
77
+ const versions = new Map();
78
+ const packages = bunLockJson.packages;
79
+ if (!isJSONObject(packages)) return versions;
80
+ for (const [name, entry] of Object.entries(packages)) {
81
+ if (!Array.isArray(entry) || typeof entry[0] !== "string") continue;
82
+ const head = entry[0];
83
+ const lastAt = head.lastIndexOf(VERSION_SEPARATOR);
84
+ if (lastAt <= 0) continue;
85
+ const version = head.slice(lastAt + 1);
86
+ if (!version) continue;
87
+ // bun.lock entries for workspace packages carry a `workspace:<path>`
88
+ // pseudo-version. Skip — we only track real registry-resolved versions.
89
+ if (version.startsWith("workspace:")) continue;
90
+ versions.set(name, version);
91
+ }
92
+ return versions;
93
+ };
62
94
 
63
95
  export {
64
96
  BUN_LOCK_ERRORS,
65
97
  SUPPORTED_BUN_LOCK_VERSIONS,
66
98
  parseBunLock,
99
+ parseBunLockPackageVersions,
67
100
  readBunLockfile,
68
101
  };
@@ -7,7 +7,9 @@ Three main domain terms to know:
7
7
 
8
8
  - Project: generally represents a monorepo and is defined by the root \`package.json\` file
9
9
  - Workspace: a nested package within a project. The root package.json can count as a workspace as well, but by default, only nested packages are considered workspaces.
10
- - Script: an entry in the \`scripts\` field of a workspace's \`package.json\` file. bw can also run one-off commands known as "inline scripts," which can use the Bun shell or system shell (\`sh -c\` or \`cmd /d /s /c\` for windows).`;
10
+ - Script: an entry in the \`scripts\` field of a workspace's \`package.json\` file. bw can also run one-off commands known as "inline scripts," which can use the Bun shell or system shell (\`sh -c\` or \`cmd /d /s /c\` for windows).
11
+
12
+ bw also supports **affected workspace** detection: given a set of changed files (from a git diff or an explicit list), it determines which workspaces are meaningfully changed. This drives \`bw list-affected\`/\`bw run-affected\` for orchestrating builds, tests, etc. across only the workspaces that need them.`;
11
13
  const DOC_CONCEPTS = `## Concepts
12
14
 
13
15
  ### Workspace patterns
@@ -59,7 +61,28 @@ const scriptName = process.env.BW_SCRIPT_NAME;
59
61
  bw run "bun <projectPath>/my-script.ts" --inline \\
60
62
  --inline-name="my-script-name" \\
61
63
  --args="<workspaceName> <workspacePath>"
62
- \`\`\``;
64
+ \`\`\`
65
+
66
+ ### Affected workspaces
67
+
68
+ A workspace is "affected" when something in its set of **inputs** has changed. Inputs default to:
69
+
70
+ - Files in the workspace's directory (only git-trackable files; the default file pattern is \`"."\`)
71
+ - Workspace dependencies — if a workspace dep is affected for any reason, dependents cascade as affected
72
+ - All non-workspace dependencies declared in its \`package.json\` (across all four maps: \`dependencies\`, \`devDependencies\`, \`peerDependencies\`, \`optionalDependencies\`). Version changes are detected by diffing resolved versions in \`bun.lock\`. For \`peerDependencies\`/\`optionalDependencies\`, lockfile presence is the gate — an unresolved optional (e.g., a platform-skipped native binding) emits no change.
73
+
74
+ Inputs are configurable per workspace (\`defaultInputs\`) and per script (\`scripts[name].inputs\`):
75
+
76
+ - \`files\`: file/dir/glob patterns relative to the workspace. Leading \`/\` makes a pattern relative to the project root. Prefix \`!\` to exclude. Only git-trackable files match.
77
+ - \`workspacePatterns\`: workspace patterns whose matched workspaces are treated as inputs (like dependencies, but without needing a real \`package.json\` dep).
78
+ - \`externalDependencies\`: an allowlist of package names. Omitted = all external deps participate; \`[]\` = none participate; non-empty = only listed names participate (intersected with the workspace's actual external deps).
79
+
80
+ There are two diff sources:
81
+
82
+ - **git** (default): diff \`HEAD\` against the configured base ref (default \`main\`, configurable via \`affectedBaseRef\` in the root config or \`BW_AFFECTED_BASE_REF_DEFAULT\` env var). Uncommitted changes (staged, unstaged, untracked) are included by default. Gitignored files never participate.
83
+ - **fileList**: pass changed files explicitly (paths, dirs, or globs) — bypasses git entirely.
84
+
85
+ Use \`--explain\` for a per-workspace summary of changed inputs and dep cascade reasons, and \`--explain --detailed\` for full per-file/edge breakdowns including the affected-dep chain.`;
63
86
  const DOC_CLI = `### CLI examples:
64
87
 
65
88
  \`\`\`bash
@@ -124,6 +147,54 @@ bw run my-script --output-style=prefixed
124
147
  # Use the plain output style (no workspace prefixes)
125
148
  bw run my-script --output-style=plain
126
149
 
150
+ # List affected workspaces (default: git diff HEAD vs the configured base ref, "main" by default)
151
+ bw list-affected
152
+ bw ls-affected # alias
153
+
154
+ # Compare specific git refs
155
+ bw ls-affected --base=my-branch-a --head=my-branch-b
156
+ bw ls-affected -B my-branch-a -H my-branch-b # short forms
157
+
158
+ # Resolve inputs for a specific script (uses scripts[name].inputs when configured)
159
+ bw ls-affected --script=build
160
+
161
+ # Ignore some uncommitted changes (uncommitted included by default)
162
+ bw ls-affected --ignore-uncommitted # all of: staged, unstaged, untracked
163
+ bw ls-affected --ignore-untracked
164
+ bw ls-affected --ignore-unstaged
165
+ bw ls-affected --ignore-staged
166
+
167
+ # Skip workspace dep cascade (only direct file/external-dep changes flag a workspace)
168
+ bw ls-affected --ignore-workspace-deps
169
+
170
+ # Skip lockfile-based external dep version tracking
171
+ bw ls-affected --ignore-external-deps
172
+
173
+ # Bypass git entirely with an explicit list of changed files
174
+ # (paths, dirs, globs; '!' to exclude; whitespace-separated)
175
+ bw ls-affected --files="packages/example/**/*.ts packages/example/my-file.json"
176
+ bw ls-affected -F "packages/a/**/*.ts !packages/a/**/*.test.ts"
177
+
178
+ # Per-workspace summary of why each workspace is affected
179
+ bw ls-affected --explain
180
+ bw ls-affected -e
181
+
182
+ # Full per-file changes and dep cascade chain for each affected workspace
183
+ bw ls-affected --explain --detailed
184
+ bw ls-affected -e -D
185
+
186
+ # JSON output (with --explain produces the full result object)
187
+ bw ls-affected --json --pretty
188
+ bw ls-affected --explain --json --pretty
189
+
190
+ # Run a script across affected workspaces (accepts the same affected options
191
+ # as ls-affected, plus the same script-execution options as run-script:
192
+ # --parallel, --dep-order, --args, --output-style, --inline, etc.)
193
+ bw run-affected build
194
+ bw run-affected build --base=my-branch --ignore-uncommitted --dep-order
195
+ bw run-affected build --files="packages/a/src/**/*.ts" --parallel=2
196
+ bw run-affected "bun build" --inline --inline-name=build # inline command form
197
+
127
198
  ### Global Options ###
128
199
  # Root directory of project:
129
200
  bw --cwd=/path/to/project ls
@@ -188,6 +259,44 @@ project.runScriptAcrossWorkspaces({
188
259
  // event: "start", "skip", "exit"
189
260
  },
190
261
  });
262
+
263
+ // Determine affected workspaces — git mode (default)
264
+ project.determineAffectedWorkspaces({
265
+ diffSource: "git",
266
+ // optional: resolve inputs for a specific script (uses scripts[name].inputs)
267
+ script: "build",
268
+ // optional: skip workspace dep cascade
269
+ ignoreWorkspaceDependencies: false,
270
+ // optional: skip lockfile-based external dep version tracking
271
+ ignoreExternalDependencies: false,
272
+ diffOptions: {
273
+ baseRef: "main", // default from config / "main"
274
+ headRef: "HEAD", // default
275
+ ignoreUncommitted: false, // staged + unstaged + untracked
276
+ ignoreUntracked: false,
277
+ ignoreUnstaged: false,
278
+ ignoreStaged: false,
279
+ },
280
+ });
281
+
282
+ // Determine affected workspaces — fileList mode (bypass git)
283
+ project.determineAffectedWorkspaces({
284
+ diffSource: "fileList",
285
+ // paths, directories, or globs (relative to project root); '!' to exclude
286
+ changedFiles: ["packages/a/**/*.ts", "!packages/a/**/*.test.ts"],
287
+ });
288
+
289
+ // Run a script across affected workspaces. Accepts the same affected options
290
+ // as determineAffectedWorkspaces, plus the script-execution options from
291
+ // runScriptAcrossWorkspaces (parallel, dependencyOrder, args, onScriptEvent, etc.).
292
+ project.runAffectedWorkspaceScript({
293
+ script: "build",
294
+ diffSource: "git",
295
+ diffOptions: { baseRef: "main", ignoreUncommitted: true },
296
+ parallel: { max: 2 },
297
+ dependencyOrder: true,
298
+ ignoreDependencyFailure: true,
299
+ });
191
300
  \`\`\`
192
301
 
193
302
  ## The Workspace object
@@ -207,10 +316,26 @@ project.runScriptAcrossWorkspaces({
207
316
  "scripts": ["my-script"],
208
317
  // Aliases defined in workspace configuration (bw.workspace.jsonc/bw.workspace.json)
209
318
  "aliases": ["my-alias"],
319
+ // Tags defined in workspace configuration
320
+ "tags": ["my-tag"],
210
321
  // Names of other workspaces that this workspace depends on
211
322
  "dependencies": ["my-dependency"],
212
323
  // Names of other workspaces that depend on this workspace
213
324
  "dependents": ["my-dependent"],
325
+ // Non-workspace package deps declared in package.json (across all four maps).
326
+ // \`source\` is one of "dependencies" | "devDependencies" | "peerDependencies" | "optionalDependencies".
327
+ // \`version\` is the package.json range, with \`catalog:\`/\`catalog:<name>\` resolved when possible.
328
+ // \`catalog\` is present when declared via a catalog ref.
329
+ "externalDependencies": [
330
+ { "name": "lodash", "version": "^4.17.0", "source": "dependencies" },
331
+ { "name": "typescript", "version": "^5.0.0", "source": "devDependencies" },
332
+ {
333
+ "name": "react",
334
+ "version": "^18.0.0",
335
+ "source": "dependencies",
336
+ "catalog": { "name": "" },
337
+ },
338
+ ],
214
339
  }
215
340
  \`\`\``;
216
341
  const DOC_CONFIG = `## Root config
@@ -225,6 +350,7 @@ Config defaults here take precedence over environment variables. Explicit CLI ar
225
350
  "parallelMax": 5, // same options as seen in CLI examples above
226
351
  "shell": "system", // "bun" or "system" (default "bun")
227
352
  "includeRootWorkspace": true, // treat root package.json as a normal workspace
353
+ "affectedBaseRef": "main", // default git base ref for affected resolution (env: BW_AFFECTED_BASE_REF_DEFAULT)
228
354
  },
229
355
  "workspacePatternConfigs": [
230
356
  // see Workspace Pattern Configs section below
@@ -258,11 +384,24 @@ Tags are strings to group workspaces together; they do not need to be unique.
258
384
  {
259
385
  "alias": "my-alias", // can be array
260
386
  "tags": ["my-tag"],
387
+ // Default inputs used to determine if the workspace is affected, applied to
388
+ // all scripts that don't configure their own inputs. See "Inputs" below.
389
+ "defaultInputs": {
390
+ "files": ["src/**/*.ts", "!src/**/*.test.ts"],
391
+ "workspacePatterns": ["tag:shared-lib"],
392
+ "externalDependencies": ["lodash", "react"],
393
+ },
261
394
  "scripts": {
262
395
  "lint": {
263
396
  // set optional sorting order for scripts
264
397
  "order": 1,
265
398
  },
399
+ "build": {
400
+ // per-script inputs override defaultInputs for this script's affected resolution
401
+ "inputs": {
402
+ "files": ["src/**/*.ts", "/shared-types/**/*.ts"], // leading "/" = relative to the project root
403
+ },
404
+ },
266
405
  },
267
406
  "rules": {
268
407
  "workspaceDependencies": {
@@ -276,6 +415,16 @@ Tags are strings to group workspaces together; they do not need to be unique.
276
415
  }
277
416
  \`\`\`
278
417
 
418
+ ### Inputs
419
+
420
+ The \`defaultInputs\` field (and the per-script \`scripts[name].inputs\` field) controls what counts as an input for [affected workspace](#affected-workspaces) resolution. Both have the same shape (\`WorkspaceInputsConfig\`):
421
+
422
+ - \`files\` — file paths, directories, or globs relative to the workspace's directory. Leading \`/\` makes a pattern relative to the project root. Prefix with \`!\` to exclude. Only git-trackable files are matched. Default when not provided is \`["."]\` (everything in the workspace dir).
423
+ - \`workspacePatterns\` — workspace patterns whose matched workspaces are treated as inputs (like dependencies, but without needing a real \`package.json\` dep edge).
424
+ - \`externalDependencies\` — allowlist of package names that participate in lockfile-change detection. Omitted = all external deps participate; \`[]\` = none participate; non-empty list = only listed names participate (intersected with the workspace's actual external deps from \`package.json\`).
425
+
426
+ Per-script \`inputs\` fully replaces \`defaultInputs\` for that script — the two are not merged. If a script has its own \`inputs\` field, \`defaultInputs\` is ignored for that script.
427
+
279
428
  ### Workspace Dependency Rules
280
429
 
281
430
  Using the \`rules.workspaceDependencies\` field, you can define rules for which workspaces are allowed to be dependencies, using \`allowPatterns\`, \`denyPatterns\`, or both.
@@ -346,7 +495,7 @@ The factory \`(workspace: RawWorkspace, prevConfig: ResolvedWorkspaceConfig) =>
346
495
  - \`workspace.dependencies\` — names of workspace dependencies
347
496
  - \`workspace.dependents\` — names of workspaces that depend on this one
348
497
 
349
- \`prevConfig\` is the fully resolved workspace config at that point, including the local config and any configs applied by earlier pattern entries. It has \`aliases: string[]\`, \`tags: string[]\`, \`scripts: Record<string, ScriptConfig>\`, \`rules: WorkspaceRules\`.
498
+ \`prevConfig\` is the fully resolved workspace config at that point, including the local config and any configs applied by earlier pattern entries. It has \`aliases: string[]\`, \`tags: string[]\`, \`scripts: Record<string, ScriptConfig>\`, \`rules: WorkspaceRules\`, \`defaultInputs?: WorkspaceInputsConfig\`.
350
499
 
351
500
  ## TypeScript/JSON Config Files
352
501
 
@@ -1 +1 @@
1
- "use strict";module.exports = validate11;module.exports.default = validate11;const schema12 = {"type":"object","additionalProperties":false,"properties":{"defaults":{"type":"object","additionalProperties":false,"properties":{"parallelMax":{"type":["number","string"]},"shell":{"type":"string"},"includeRootWorkspace":{"type":"boolean"}}},"workspacePatternConfigs":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["patterns","config"],"properties":{"patterns":{"type":"array","items":{"type":"string"}},"config":{}}}}}};function validate11(data, {instancePath="", parentData, parentDataProperty, rootData=data}={}){let vErrors = null;let errors = 0;if(errors === 0){if(data && typeof data == "object" && !Array.isArray(data)){const _errs1 = errors;for(const key0 in data){if(!((key0 === "defaults") || (key0 === "workspacePatternConfigs"))){validate11.errors = [{instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties"}];return false;break;}}if(_errs1 === errors){if(data.defaults !== undefined){let data0 = data.defaults;const _errs2 = errors;if(errors === _errs2){if(data0 && typeof data0 == "object" && !Array.isArray(data0)){const _errs4 = errors;for(const key1 in data0){if(!(((key1 === "parallelMax") || (key1 === "shell")) || (key1 === "includeRootWorkspace"))){validate11.errors = [{instancePath:instancePath+"/defaults",schemaPath:"#/properties/defaults/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key1},message:"must NOT have additional properties"}];return false;break;}}if(_errs4 === errors){if(data0.parallelMax !== undefined){let data1 = data0.parallelMax;const _errs5 = errors;if((!((typeof data1 == "number") && (isFinite(data1)))) && (typeof data1 !== "string")){validate11.errors = [{instancePath:instancePath+"/defaults/parallelMax",schemaPath:"#/properties/defaults/properties/parallelMax/type",keyword:"type",params:{type: schema12.properties.defaults.properties.parallelMax.type},message:"must be number,string"}];return false;}var valid1 = _errs5 === errors;}else {var valid1 = true;}if(valid1){if(data0.shell !== undefined){const _errs7 = errors;if(typeof data0.shell !== "string"){validate11.errors = [{instancePath:instancePath+"/defaults/shell",schemaPath:"#/properties/defaults/properties/shell/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid1 = _errs7 === errors;}else {var valid1 = true;}if(valid1){if(data0.includeRootWorkspace !== undefined){const _errs9 = errors;if(typeof data0.includeRootWorkspace !== "boolean"){validate11.errors = [{instancePath:instancePath+"/defaults/includeRootWorkspace",schemaPath:"#/properties/defaults/properties/includeRootWorkspace/type",keyword:"type",params:{type: "boolean"},message:"must be boolean"}];return false;}var valid1 = _errs9 === errors;}else {var valid1 = true;}}}}}else {validate11.errors = [{instancePath:instancePath+"/defaults",schemaPath:"#/properties/defaults/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid0 = _errs2 === errors;}else {var valid0 = true;}if(valid0){if(data.workspacePatternConfigs !== undefined){let data4 = data.workspacePatternConfigs;const _errs11 = errors;if(errors === _errs11){if(Array.isArray(data4)){var valid2 = true;const len0 = data4.length;for(let i0=0; i0<len0; i0++){let data5 = data4[i0];const _errs13 = errors;if(errors === _errs13){if(data5 && typeof data5 == "object" && !Array.isArray(data5)){let missing0;if(((data5.patterns === undefined) && (missing0 = "patterns")) || ((data5.config === undefined) && (missing0 = "config"))){validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs/" + i0,schemaPath:"#/properties/workspacePatternConfigs/items/required",keyword:"required",params:{missingProperty: missing0},message:"must have required property '"+missing0+"'"}];return false;}else {const _errs15 = errors;for(const key2 in data5){if(!((key2 === "patterns") || (key2 === "config"))){validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs/" + i0,schemaPath:"#/properties/workspacePatternConfigs/items/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key2},message:"must NOT have additional properties"}];return false;break;}}if(_errs15 === errors){if(data5.patterns !== undefined){let data6 = data5.patterns;const _errs16 = errors;if(errors === _errs16){if(Array.isArray(data6)){var valid4 = true;const len1 = data6.length;for(let i1=0; i1<len1; i1++){const _errs18 = errors;if(typeof data6[i1] !== "string"){validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs/" + i0+"/patterns/" + i1,schemaPath:"#/properties/workspacePatternConfigs/items/properties/patterns/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid4 = _errs18 === errors;if(!valid4){break;}}}else {validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs/" + i0+"/patterns",schemaPath:"#/properties/workspacePatternConfigs/items/properties/patterns/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}}}}}else {validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs/" + i0,schemaPath:"#/properties/workspacePatternConfigs/items/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid2 = _errs13 === errors;if(!valid2){break;}}}else {validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs",schemaPath:"#/properties/workspacePatternConfigs/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid0 = _errs11 === errors;}else {var valid0 = true;}}}}else {validate11.errors = [{instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}validate11.errors = vErrors;return errors === 0;}
1
+ "use strict";export const validate = validate11;export default validate11;const schema12 = {"type":"object","additionalProperties":false,"properties":{"defaults":{"type":"object","additionalProperties":false,"properties":{"parallelMax":{"type":["number","string"]},"shell":{"type":"string"},"includeRootWorkspace":{"type":"boolean"},"affectedBaseRef":{"type":"string"}}},"workspacePatternConfigs":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["patterns","config"],"properties":{"patterns":{"type":"array","items":{"type":"string"}},"config":{}}}}}};function validate11(data, {instancePath="", parentData, parentDataProperty, rootData=data}={}){let vErrors = null;let errors = 0;if(errors === 0){if(data && typeof data == "object" && !Array.isArray(data)){const _errs1 = errors;for(const key0 in data){if(!((key0 === "defaults") || (key0 === "workspacePatternConfigs"))){validate11.errors = [{instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties"}];return false;break;}}if(_errs1 === errors){if(data.defaults !== undefined){let data0 = data.defaults;const _errs2 = errors;if(errors === _errs2){if(data0 && typeof data0 == "object" && !Array.isArray(data0)){const _errs4 = errors;for(const key1 in data0){if(!((((key1 === "parallelMax") || (key1 === "shell")) || (key1 === "includeRootWorkspace")) || (key1 === "affectedBaseRef"))){validate11.errors = [{instancePath:instancePath+"/defaults",schemaPath:"#/properties/defaults/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key1},message:"must NOT have additional properties"}];return false;break;}}if(_errs4 === errors){if(data0.parallelMax !== undefined){let data1 = data0.parallelMax;const _errs5 = errors;if((!((typeof data1 == "number") && (isFinite(data1)))) && (typeof data1 !== "string")){validate11.errors = [{instancePath:instancePath+"/defaults/parallelMax",schemaPath:"#/properties/defaults/properties/parallelMax/type",keyword:"type",params:{type: schema12.properties.defaults.properties.parallelMax.type},message:"must be number,string"}];return false;}var valid1 = _errs5 === errors;}else {var valid1 = true;}if(valid1){if(data0.shell !== undefined){const _errs7 = errors;if(typeof data0.shell !== "string"){validate11.errors = [{instancePath:instancePath+"/defaults/shell",schemaPath:"#/properties/defaults/properties/shell/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid1 = _errs7 === errors;}else {var valid1 = true;}if(valid1){if(data0.includeRootWorkspace !== undefined){const _errs9 = errors;if(typeof data0.includeRootWorkspace !== "boolean"){validate11.errors = [{instancePath:instancePath+"/defaults/includeRootWorkspace",schemaPath:"#/properties/defaults/properties/includeRootWorkspace/type",keyword:"type",params:{type: "boolean"},message:"must be boolean"}];return false;}var valid1 = _errs9 === errors;}else {var valid1 = true;}if(valid1){if(data0.affectedBaseRef !== undefined){const _errs11 = errors;if(typeof data0.affectedBaseRef !== "string"){validate11.errors = [{instancePath:instancePath+"/defaults/affectedBaseRef",schemaPath:"#/properties/defaults/properties/affectedBaseRef/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid1 = _errs11 === errors;}else {var valid1 = true;}}}}}}else {validate11.errors = [{instancePath:instancePath+"/defaults",schemaPath:"#/properties/defaults/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid0 = _errs2 === errors;}else {var valid0 = true;}if(valid0){if(data.workspacePatternConfigs !== undefined){let data5 = data.workspacePatternConfigs;const _errs13 = errors;if(errors === _errs13){if(Array.isArray(data5)){var valid2 = true;const len0 = data5.length;for(let i0=0; i0<len0; i0++){let data6 = data5[i0];const _errs15 = errors;if(errors === _errs15){if(data6 && typeof data6 == "object" && !Array.isArray(data6)){let missing0;if(((data6.patterns === undefined) && (missing0 = "patterns")) || ((data6.config === undefined) && (missing0 = "config"))){validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs/" + i0,schemaPath:"#/properties/workspacePatternConfigs/items/required",keyword:"required",params:{missingProperty: missing0},message:"must have required property '"+missing0+"'"}];return false;}else {const _errs17 = errors;for(const key2 in data6){if(!((key2 === "patterns") || (key2 === "config"))){validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs/" + i0,schemaPath:"#/properties/workspacePatternConfigs/items/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key2},message:"must NOT have additional properties"}];return false;break;}}if(_errs17 === errors){if(data6.patterns !== undefined){let data7 = data6.patterns;const _errs18 = errors;if(errors === _errs18){if(Array.isArray(data7)){var valid4 = true;const len1 = data7.length;for(let i1=0; i1<len1; i1++){const _errs20 = errors;if(typeof data7[i1] !== "string"){validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs/" + i0+"/patterns/" + i1,schemaPath:"#/properties/workspacePatternConfigs/items/properties/patterns/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid4 = _errs20 === errors;if(!valid4){break;}}}else {validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs/" + i0+"/patterns",schemaPath:"#/properties/workspacePatternConfigs/items/properties/patterns/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}}}}}else {validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs/" + i0,schemaPath:"#/properties/workspacePatternConfigs/items/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid2 = _errs15 === errors;if(!valid2){break;}}}else {validate11.errors = [{instancePath:instancePath+"/workspacePatternConfigs",schemaPath:"#/properties/workspacePatternConfigs/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid0 = _errs13 === errors;}else {var valid0 = true;}}}}else {validate11.errors = [{instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}validate11.errors = vErrors;return errors === 0;}
@@ -1 +1 @@
1
- "use strict";module.exports = validate10;module.exports.default = validate10;const schema11 = {"type":"object","additionalProperties":false,"properties":{"alias":{"type":["string","array"],"items":{"type":"string"},"uniqueItems":true},"tags":{"type":"array","items":{"type":"string"},"uniqueItems":true},"scripts":{"type":"object","additionalProperties":{"type":"object","properties":{"order":{"type":"number"}},"additionalProperties":false}},"rules":{"type":"object","additionalProperties":false,"properties":{"workspaceDependencies":{"type":"object","properties":{"allowPatterns":{"type":"array","items":{"type":"string"}},"denyPatterns":{"type":"array","items":{"type":"string"}}},"additionalProperties":false}}}}};function validate10(data, {instancePath="", parentData, parentDataProperty, rootData=data}={}){let vErrors = null;let errors = 0;if(errors === 0){if(data && typeof data == "object" && !Array.isArray(data)){const _errs1 = errors;for(const key0 in data){if(!((((key0 === "alias") || (key0 === "tags")) || (key0 === "scripts")) || (key0 === "rules"))){validate10.errors = [{instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties"}];return false;break;}}if(_errs1 === errors){if(data.alias !== undefined){let data0 = data.alias;const _errs2 = errors;if((typeof data0 !== "string") && (!(Array.isArray(data0)))){validate10.errors = [{instancePath:instancePath+"/alias",schemaPath:"#/properties/alias/type",keyword:"type",params:{type: schema11.properties.alias.type},message:"must be string,array"}];return false;}if(errors === _errs2){if(Array.isArray(data0)){var valid1 = true;const len0 = data0.length;for(let i0=0; i0<len0; i0++){const _errs4 = errors;if(typeof data0[i0] !== "string"){validate10.errors = [{instancePath:instancePath+"/alias/" + i0,schemaPath:"#/properties/alias/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid1 = _errs4 === errors;if(!valid1){break;}}if(valid1){let i1 = data0.length;let j0;if(i1 > 1){const indices0 = {};for(;i1--;){let item0 = data0[i1];if(typeof item0 !== "string"){continue;}if(typeof indices0[item0] == "number"){j0 = indices0[item0];validate10.errors = [{instancePath:instancePath+"/alias",schemaPath:"#/properties/alias/uniqueItems",keyword:"uniqueItems",params:{i: i1, j: j0},message:"must NOT have duplicate items (items ## "+j0+" and "+i1+" are identical)"}];return false;break;}indices0[item0] = i1;}}}}}var valid0 = _errs2 === errors;}else {var valid0 = true;}if(valid0){if(data.tags !== undefined){let data2 = data.tags;const _errs6 = errors;if(errors === _errs6){if(Array.isArray(data2)){var valid3 = true;const len1 = data2.length;for(let i2=0; i2<len1; i2++){const _errs8 = errors;if(typeof data2[i2] !== "string"){validate10.errors = [{instancePath:instancePath+"/tags/" + i2,schemaPath:"#/properties/tags/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid3 = _errs8 === errors;if(!valid3){break;}}if(valid3){let i3 = data2.length;let j1;if(i3 > 1){const indices1 = {};for(;i3--;){let item1 = data2[i3];if(typeof item1 !== "string"){continue;}if(typeof indices1[item1] == "number"){j1 = indices1[item1];validate10.errors = [{instancePath:instancePath+"/tags",schemaPath:"#/properties/tags/uniqueItems",keyword:"uniqueItems",params:{i: i3, j: j1},message:"must NOT have duplicate items (items ## "+j1+" and "+i3+" are identical)"}];return false;break;}indices1[item1] = i3;}}}}else {validate10.errors = [{instancePath:instancePath+"/tags",schemaPath:"#/properties/tags/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid0 = _errs6 === errors;}else {var valid0 = true;}if(valid0){if(data.scripts !== undefined){let data4 = data.scripts;const _errs10 = errors;if(errors === _errs10){if(data4 && typeof data4 == "object" && !Array.isArray(data4)){for(const key1 in data4){let data5 = data4[key1];const _errs13 = errors;if(errors === _errs13){if(data5 && typeof data5 == "object" && !Array.isArray(data5)){const _errs15 = errors;for(const key2 in data5){if(!(key2 === "order")){validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1"),schemaPath:"#/properties/scripts/additionalProperties/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key2},message:"must NOT have additional properties"}];return false;break;}}if(_errs15 === errors){if(data5.order !== undefined){let data6 = data5.order;if(!((typeof data6 == "number") && (isFinite(data6)))){validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1")+"/order",schemaPath:"#/properties/scripts/additionalProperties/properties/order/type",keyword:"type",params:{type: "number"},message:"must be number"}];return false;}}}}else {validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1"),schemaPath:"#/properties/scripts/additionalProperties/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid5 = _errs13 === errors;if(!valid5){break;}}}else {validate10.errors = [{instancePath:instancePath+"/scripts",schemaPath:"#/properties/scripts/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid0 = _errs10 === errors;}else {var valid0 = true;}if(valid0){if(data.rules !== undefined){let data7 = data.rules;const _errs18 = errors;if(errors === _errs18){if(data7 && typeof data7 == "object" && !Array.isArray(data7)){const _errs20 = errors;for(const key3 in data7){if(!(key3 === "workspaceDependencies")){validate10.errors = [{instancePath:instancePath+"/rules",schemaPath:"#/properties/rules/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key3},message:"must NOT have additional properties"}];return false;break;}}if(_errs20 === errors){if(data7.workspaceDependencies !== undefined){let data8 = data7.workspaceDependencies;const _errs21 = errors;if(errors === _errs21){if(data8 && typeof data8 == "object" && !Array.isArray(data8)){const _errs23 = errors;for(const key4 in data8){if(!((key4 === "allowPatterns") || (key4 === "denyPatterns"))){validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies",schemaPath:"#/properties/rules/properties/workspaceDependencies/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key4},message:"must NOT have additional properties"}];return false;break;}}if(_errs23 === errors){if(data8.allowPatterns !== undefined){let data9 = data8.allowPatterns;const _errs24 = errors;if(errors === _errs24){if(Array.isArray(data9)){var valid9 = true;const len2 = data9.length;for(let i4=0; i4<len2; i4++){const _errs26 = errors;if(typeof data9[i4] !== "string"){validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies/allowPatterns/" + i4,schemaPath:"#/properties/rules/properties/workspaceDependencies/properties/allowPatterns/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid9 = _errs26 === errors;if(!valid9){break;}}}else {validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies/allowPatterns",schemaPath:"#/properties/rules/properties/workspaceDependencies/properties/allowPatterns/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid8 = _errs24 === errors;}else {var valid8 = true;}if(valid8){if(data8.denyPatterns !== undefined){let data11 = data8.denyPatterns;const _errs28 = errors;if(errors === _errs28){if(Array.isArray(data11)){var valid10 = true;const len3 = data11.length;for(let i5=0; i5<len3; i5++){const _errs30 = errors;if(typeof data11[i5] !== "string"){validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies/denyPatterns/" + i5,schemaPath:"#/properties/rules/properties/workspaceDependencies/properties/denyPatterns/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid10 = _errs30 === errors;if(!valid10){break;}}}else {validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies/denyPatterns",schemaPath:"#/properties/rules/properties/workspaceDependencies/properties/denyPatterns/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid8 = _errs28 === errors;}else {var valid8 = true;}}}}else {validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies",schemaPath:"#/properties/rules/properties/workspaceDependencies/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}}}}else {validate10.errors = [{instancePath:instancePath+"/rules",schemaPath:"#/properties/rules/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid0 = _errs18 === errors;}else {var valid0 = true;}}}}}}else {validate10.errors = [{instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}validate10.errors = vErrors;return errors === 0;}
1
+ "use strict";export const validate = validate10;export default validate10;const schema11 = {"type":"object","additionalProperties":false,"properties":{"alias":{"type":["string","array"],"items":{"type":"string"},"uniqueItems":true},"tags":{"type":"array","items":{"type":"string"},"uniqueItems":true},"scripts":{"type":"object","additionalProperties":{"type":"object","properties":{"order":{"type":"number"},"inputs":{"type":"object","additionalProperties":false,"properties":{"files":{"type":"array","items":{"type":"string"}},"workspacePatterns":{"type":"array","items":{"type":"string"}},"externalDependencies":{"type":"array","items":{"type":"string"}}}}},"additionalProperties":false}},"rules":{"type":"object","additionalProperties":false,"properties":{"workspaceDependencies":{"type":"object","properties":{"allowPatterns":{"type":"array","items":{"type":"string"}},"denyPatterns":{"type":"array","items":{"type":"string"}}},"additionalProperties":false}}},"defaultInputs":{"type":"object","additionalProperties":false,"properties":{"files":{"type":"array","items":{"type":"string"}},"workspacePatterns":{"type":"array","items":{"type":"string"}},"externalDependencies":{"type":"array","items":{"type":"string"}}}}}};function validate10(data, {instancePath="", parentData, parentDataProperty, rootData=data}={}){let vErrors = null;let errors = 0;if(errors === 0){if(data && typeof data == "object" && !Array.isArray(data)){const _errs1 = errors;for(const key0 in data){if(!(((((key0 === "alias") || (key0 === "tags")) || (key0 === "scripts")) || (key0 === "rules")) || (key0 === "defaultInputs"))){validate10.errors = [{instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties"}];return false;break;}}if(_errs1 === errors){if(data.alias !== undefined){let data0 = data.alias;const _errs2 = errors;if((typeof data0 !== "string") && (!(Array.isArray(data0)))){validate10.errors = [{instancePath:instancePath+"/alias",schemaPath:"#/properties/alias/type",keyword:"type",params:{type: schema11.properties.alias.type},message:"must be string,array"}];return false;}if(errors === _errs2){if(Array.isArray(data0)){var valid1 = true;const len0 = data0.length;for(let i0=0; i0<len0; i0++){const _errs4 = errors;if(typeof data0[i0] !== "string"){validate10.errors = [{instancePath:instancePath+"/alias/" + i0,schemaPath:"#/properties/alias/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid1 = _errs4 === errors;if(!valid1){break;}}if(valid1){let i1 = data0.length;let j0;if(i1 > 1){const indices0 = {};for(;i1--;){let item0 = data0[i1];if(typeof item0 !== "string"){continue;}if(typeof indices0[item0] == "number"){j0 = indices0[item0];validate10.errors = [{instancePath:instancePath+"/alias",schemaPath:"#/properties/alias/uniqueItems",keyword:"uniqueItems",params:{i: i1, j: j0},message:"must NOT have duplicate items (items ## "+j0+" and "+i1+" are identical)"}];return false;break;}indices0[item0] = i1;}}}}}var valid0 = _errs2 === errors;}else {var valid0 = true;}if(valid0){if(data.tags !== undefined){let data2 = data.tags;const _errs6 = errors;if(errors === _errs6){if(Array.isArray(data2)){var valid3 = true;const len1 = data2.length;for(let i2=0; i2<len1; i2++){const _errs8 = errors;if(typeof data2[i2] !== "string"){validate10.errors = [{instancePath:instancePath+"/tags/" + i2,schemaPath:"#/properties/tags/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid3 = _errs8 === errors;if(!valid3){break;}}if(valid3){let i3 = data2.length;let j1;if(i3 > 1){const indices1 = {};for(;i3--;){let item1 = data2[i3];if(typeof item1 !== "string"){continue;}if(typeof indices1[item1] == "number"){j1 = indices1[item1];validate10.errors = [{instancePath:instancePath+"/tags",schemaPath:"#/properties/tags/uniqueItems",keyword:"uniqueItems",params:{i: i3, j: j1},message:"must NOT have duplicate items (items ## "+j1+" and "+i3+" are identical)"}];return false;break;}indices1[item1] = i3;}}}}else {validate10.errors = [{instancePath:instancePath+"/tags",schemaPath:"#/properties/tags/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid0 = _errs6 === errors;}else {var valid0 = true;}if(valid0){if(data.scripts !== undefined){let data4 = data.scripts;const _errs10 = errors;if(errors === _errs10){if(data4 && typeof data4 == "object" && !Array.isArray(data4)){for(const key1 in data4){let data5 = data4[key1];const _errs13 = errors;if(errors === _errs13){if(data5 && typeof data5 == "object" && !Array.isArray(data5)){const _errs15 = errors;for(const key2 in data5){if(!((key2 === "order") || (key2 === "inputs"))){validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1"),schemaPath:"#/properties/scripts/additionalProperties/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key2},message:"must NOT have additional properties"}];return false;break;}}if(_errs15 === errors){if(data5.order !== undefined){let data6 = data5.order;const _errs16 = errors;if(!((typeof data6 == "number") && (isFinite(data6)))){validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1")+"/order",schemaPath:"#/properties/scripts/additionalProperties/properties/order/type",keyword:"type",params:{type: "number"},message:"must be number"}];return false;}var valid6 = _errs16 === errors;}else {var valid6 = true;}if(valid6){if(data5.inputs !== undefined){let data7 = data5.inputs;const _errs18 = errors;if(errors === _errs18){if(data7 && typeof data7 == "object" && !Array.isArray(data7)){const _errs20 = errors;for(const key3 in data7){if(!(((key3 === "files") || (key3 === "workspacePatterns")) || (key3 === "externalDependencies"))){validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1")+"/inputs",schemaPath:"#/properties/scripts/additionalProperties/properties/inputs/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key3},message:"must NOT have additional properties"}];return false;break;}}if(_errs20 === errors){if(data7.files !== undefined){let data8 = data7.files;const _errs21 = errors;if(errors === _errs21){if(Array.isArray(data8)){var valid8 = true;const len2 = data8.length;for(let i4=0; i4<len2; i4++){const _errs23 = errors;if(typeof data8[i4] !== "string"){validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1")+"/inputs/files/" + i4,schemaPath:"#/properties/scripts/additionalProperties/properties/inputs/properties/files/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid8 = _errs23 === errors;if(!valid8){break;}}}else {validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1")+"/inputs/files",schemaPath:"#/properties/scripts/additionalProperties/properties/inputs/properties/files/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid7 = _errs21 === errors;}else {var valid7 = true;}if(valid7){if(data7.workspacePatterns !== undefined){let data10 = data7.workspacePatterns;const _errs25 = errors;if(errors === _errs25){if(Array.isArray(data10)){var valid9 = true;const len3 = data10.length;for(let i5=0; i5<len3; i5++){const _errs27 = errors;if(typeof data10[i5] !== "string"){validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1")+"/inputs/workspacePatterns/" + i5,schemaPath:"#/properties/scripts/additionalProperties/properties/inputs/properties/workspacePatterns/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid9 = _errs27 === errors;if(!valid9){break;}}}else {validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1")+"/inputs/workspacePatterns",schemaPath:"#/properties/scripts/additionalProperties/properties/inputs/properties/workspacePatterns/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid7 = _errs25 === errors;}else {var valid7 = true;}if(valid7){if(data7.externalDependencies !== undefined){let data12 = data7.externalDependencies;const _errs29 = errors;if(errors === _errs29){if(Array.isArray(data12)){var valid10 = true;const len4 = data12.length;for(let i6=0; i6<len4; i6++){const _errs31 = errors;if(typeof data12[i6] !== "string"){validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1")+"/inputs/externalDependencies/" + i6,schemaPath:"#/properties/scripts/additionalProperties/properties/inputs/properties/externalDependencies/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid10 = _errs31 === errors;if(!valid10){break;}}}else {validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1")+"/inputs/externalDependencies",schemaPath:"#/properties/scripts/additionalProperties/properties/inputs/properties/externalDependencies/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid7 = _errs29 === errors;}else {var valid7 = true;}}}}}else {validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1")+"/inputs",schemaPath:"#/properties/scripts/additionalProperties/properties/inputs/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid6 = _errs18 === errors;}else {var valid6 = true;}}}}else {validate10.errors = [{instancePath:instancePath+"/scripts/" + key1.replace(/~/g, "~0").replace(/\//g, "~1"),schemaPath:"#/properties/scripts/additionalProperties/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid5 = _errs13 === errors;if(!valid5){break;}}}else {validate10.errors = [{instancePath:instancePath+"/scripts",schemaPath:"#/properties/scripts/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid0 = _errs10 === errors;}else {var valid0 = true;}if(valid0){if(data.rules !== undefined){let data14 = data.rules;const _errs33 = errors;if(errors === _errs33){if(data14 && typeof data14 == "object" && !Array.isArray(data14)){const _errs35 = errors;for(const key4 in data14){if(!(key4 === "workspaceDependencies")){validate10.errors = [{instancePath:instancePath+"/rules",schemaPath:"#/properties/rules/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key4},message:"must NOT have additional properties"}];return false;break;}}if(_errs35 === errors){if(data14.workspaceDependencies !== undefined){let data15 = data14.workspaceDependencies;const _errs36 = errors;if(errors === _errs36){if(data15 && typeof data15 == "object" && !Array.isArray(data15)){const _errs38 = errors;for(const key5 in data15){if(!((key5 === "allowPatterns") || (key5 === "denyPatterns"))){validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies",schemaPath:"#/properties/rules/properties/workspaceDependencies/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key5},message:"must NOT have additional properties"}];return false;break;}}if(_errs38 === errors){if(data15.allowPatterns !== undefined){let data16 = data15.allowPatterns;const _errs39 = errors;if(errors === _errs39){if(Array.isArray(data16)){var valid13 = true;const len5 = data16.length;for(let i7=0; i7<len5; i7++){const _errs41 = errors;if(typeof data16[i7] !== "string"){validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies/allowPatterns/" + i7,schemaPath:"#/properties/rules/properties/workspaceDependencies/properties/allowPatterns/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid13 = _errs41 === errors;if(!valid13){break;}}}else {validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies/allowPatterns",schemaPath:"#/properties/rules/properties/workspaceDependencies/properties/allowPatterns/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid12 = _errs39 === errors;}else {var valid12 = true;}if(valid12){if(data15.denyPatterns !== undefined){let data18 = data15.denyPatterns;const _errs43 = errors;if(errors === _errs43){if(Array.isArray(data18)){var valid14 = true;const len6 = data18.length;for(let i8=0; i8<len6; i8++){const _errs45 = errors;if(typeof data18[i8] !== "string"){validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies/denyPatterns/" + i8,schemaPath:"#/properties/rules/properties/workspaceDependencies/properties/denyPatterns/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid14 = _errs45 === errors;if(!valid14){break;}}}else {validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies/denyPatterns",schemaPath:"#/properties/rules/properties/workspaceDependencies/properties/denyPatterns/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid12 = _errs43 === errors;}else {var valid12 = true;}}}}else {validate10.errors = [{instancePath:instancePath+"/rules/workspaceDependencies",schemaPath:"#/properties/rules/properties/workspaceDependencies/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}}}}else {validate10.errors = [{instancePath:instancePath+"/rules",schemaPath:"#/properties/rules/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid0 = _errs33 === errors;}else {var valid0 = true;}if(valid0){if(data.defaultInputs !== undefined){let data20 = data.defaultInputs;const _errs47 = errors;if(errors === _errs47){if(data20 && typeof data20 == "object" && !Array.isArray(data20)){const _errs49 = errors;for(const key6 in data20){if(!(((key6 === "files") || (key6 === "workspacePatterns")) || (key6 === "externalDependencies"))){validate10.errors = [{instancePath:instancePath+"/defaultInputs",schemaPath:"#/properties/defaultInputs/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key6},message:"must NOT have additional properties"}];return false;break;}}if(_errs49 === errors){if(data20.files !== undefined){let data21 = data20.files;const _errs50 = errors;if(errors === _errs50){if(Array.isArray(data21)){var valid16 = true;const len7 = data21.length;for(let i9=0; i9<len7; i9++){const _errs52 = errors;if(typeof data21[i9] !== "string"){validate10.errors = [{instancePath:instancePath+"/defaultInputs/files/" + i9,schemaPath:"#/properties/defaultInputs/properties/files/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid16 = _errs52 === errors;if(!valid16){break;}}}else {validate10.errors = [{instancePath:instancePath+"/defaultInputs/files",schemaPath:"#/properties/defaultInputs/properties/files/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid15 = _errs50 === errors;}else {var valid15 = true;}if(valid15){if(data20.workspacePatterns !== undefined){let data23 = data20.workspacePatterns;const _errs54 = errors;if(errors === _errs54){if(Array.isArray(data23)){var valid17 = true;const len8 = data23.length;for(let i10=0; i10<len8; i10++){const _errs56 = errors;if(typeof data23[i10] !== "string"){validate10.errors = [{instancePath:instancePath+"/defaultInputs/workspacePatterns/" + i10,schemaPath:"#/properties/defaultInputs/properties/workspacePatterns/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid17 = _errs56 === errors;if(!valid17){break;}}}else {validate10.errors = [{instancePath:instancePath+"/defaultInputs/workspacePatterns",schemaPath:"#/properties/defaultInputs/properties/workspacePatterns/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid15 = _errs54 === errors;}else {var valid15 = true;}if(valid15){if(data20.externalDependencies !== undefined){let data25 = data20.externalDependencies;const _errs58 = errors;if(errors === _errs58){if(Array.isArray(data25)){var valid18 = true;const len9 = data25.length;for(let i11=0; i11<len9; i11++){const _errs60 = errors;if(typeof data25[i11] !== "string"){validate10.errors = [{instancePath:instancePath+"/defaultInputs/externalDependencies/" + i11,schemaPath:"#/properties/defaultInputs/properties/externalDependencies/items/type",keyword:"type",params:{type: "string"},message:"must be string"}];return false;}var valid18 = _errs60 === errors;if(!valid18){break;}}}else {validate10.errors = [{instancePath:instancePath+"/defaultInputs/externalDependencies",schemaPath:"#/properties/defaultInputs/properties/externalDependencies/type",keyword:"type",params:{type: "array"},message:"must be array"}];return false;}}var valid15 = _errs58 === errors;}else {var valid15 = true;}}}}}else {validate10.errors = [{instancePath:instancePath+"/defaultInputs",schemaPath:"#/properties/defaultInputs/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}var valid0 = _errs47 === errors;}else {var valid0 = true;}}}}}}}else {validate10.errors = [{instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object"}];return false;}}validate10.errors = vErrors;return errors === 0;}
@@ -0,0 +1,225 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import bun from "bun";
4
+ import { getFileAffectedWorkspaces } from "../../../affected/fileAffectedWorkspaces.mjs";
5
+ import { getGitAffectedWorkspaces } from "../../../affected/gitAffectedWorkspaces.mjs";
6
+
7
+ const isOptionsForDiffSource = (options, diffSource) =>
8
+ options.diffSource === diffSource;
9
+ const DEFAULT_INPUT_FILE_PATTERN = ".";
10
+ const DEFAULT_HEAD_REF = "HEAD";
11
+ const BUN_LOCK_PROJECT_RELATIVE_PATH = "bun.lock";
12
+ const FILE_PATTERN_NEGATION_PREFIX = "!";
13
+ const GLOB_CHARACTER_REGEX = /[*?[{]/;
14
+ const SKIPPED_DIR_NAMES = new Set(["node_modules", ".git"]);
15
+ const buildWorkspaceInputs = ({ project, script }) => {
16
+ const effectiveInputsByName = new Map();
17
+ const inputs = project.workspaces.map((workspace) => {
18
+ const workspaceConfig = project.config.workspaces[workspace.name];
19
+ const scriptInputs = script
20
+ ? workspaceConfig?.scripts[script]?.inputs
21
+ : undefined;
22
+ const sourceInputs = scriptInputs ?? workspaceConfig?.defaultInputs ?? {};
23
+ const effectiveFiles = sourceInputs.files ?? [DEFAULT_INPUT_FILE_PATTERN];
24
+ const effectiveWorkspacePatterns = sourceInputs.workspacePatterns ?? [];
25
+ const effectiveExternalDependencies = sourceInputs.externalDependencies;
26
+ effectiveInputsByName.set(workspace.name, {
27
+ files: effectiveFiles,
28
+ workspacePatterns: effectiveWorkspacePatterns,
29
+ ...(effectiveExternalDependencies !== undefined && {
30
+ externalDependencies: effectiveExternalDependencies,
31
+ }),
32
+ });
33
+ return {
34
+ workspace,
35
+ inputFilePatterns: effectiveFiles,
36
+ inputWorkspacePatterns: effectiveWorkspacePatterns,
37
+ ...(effectiveExternalDependencies !== undefined && {
38
+ inputExternalDependencyNames: effectiveExternalDependencies,
39
+ }),
40
+ };
41
+ });
42
+ return {
43
+ inputs,
44
+ effectiveInputsByName,
45
+ };
46
+ };
47
+ const buildLockfileChangeSyntheticEntries = (workspaces) => {
48
+ const result = new Map();
49
+ for (const workspace of workspaces) {
50
+ if (!workspace.externalDependencies.length) continue;
51
+ result.set(
52
+ workspace.name,
53
+ workspace.externalDependencies.map(({ name, source }) => ({
54
+ name,
55
+ source,
56
+ baseVersion: null,
57
+ headVersion: null,
58
+ })),
59
+ );
60
+ }
61
+ return result;
62
+ };
63
+ const normalizeChangedFilesPattern = (pattern) => {
64
+ let normalized = pattern.replaceAll("\\", "/");
65
+ while (normalized.startsWith("./")) normalized = normalized.slice(2);
66
+ normalized = normalized.replace(/^\/+/, "").replace(/\/+$/, "");
67
+ if (normalized === ".") return "";
68
+ return normalized;
69
+ };
70
+ const expandPatternToFiles = ({ rootDirectory, pattern }) => {
71
+ if (!pattern) return [];
72
+ const normalized = normalizeChangedFilesPattern(pattern);
73
+ if (normalized && GLOB_CHARACTER_REGEX.test(normalized)) {
74
+ return Array.from(
75
+ new bun.Glob(normalized).scanSync({
76
+ cwd: rootDirectory,
77
+ onlyFiles: true,
78
+ }),
79
+ ).map((match) => match.replaceAll("\\", "/"));
80
+ }
81
+ // Empty `normalized` means the input resolved to the project root (e.g. ".")
82
+ const isProjectRoot = normalized === "";
83
+ const absolute = isProjectRoot
84
+ ? rootDirectory
85
+ : path.join(rootDirectory, ...normalized.split("/"));
86
+ let stat;
87
+ try {
88
+ stat = fs.statSync(absolute);
89
+ } catch {
90
+ // Pass through paths that don't exist on disk (e.g. deleted files)
91
+ return isProjectRoot ? [] : [normalized];
92
+ }
93
+ if (stat.isFile()) return [normalized];
94
+ if (!stat.isDirectory()) return [];
95
+ const result = [];
96
+ const walk = (dir, baseRel) => {
97
+ for (const entry of fs.readdirSync(dir, {
98
+ withFileTypes: true,
99
+ })) {
100
+ if (entry.isDirectory() && SKIPPED_DIR_NAMES.has(entry.name)) continue;
101
+ const rel = baseRel ? `${baseRel}/${entry.name}` : entry.name;
102
+ if (entry.isDirectory()) {
103
+ walk(path.join(dir, entry.name), rel);
104
+ } else if (entry.isFile()) {
105
+ result.push(rel);
106
+ }
107
+ }
108
+ };
109
+ walk(absolute, normalized);
110
+ return result;
111
+ };
112
+ const expandChangedFilesPatterns = ({ rootDirectory, patterns }) => {
113
+ const includes = new Set();
114
+ const excludes = new Set();
115
+ for (const pattern of patterns) {
116
+ const isExclude = pattern.startsWith(FILE_PATTERN_NEGATION_PREFIX);
117
+ const stripped = isExclude
118
+ ? pattern.slice(FILE_PATTERN_NEGATION_PREFIX.length)
119
+ : pattern;
120
+ const target = isExclude ? excludes : includes;
121
+ for (const expanded of expandPatternToFiles({
122
+ rootDirectory,
123
+ pattern: stripped,
124
+ })) {
125
+ target.add(expanded);
126
+ }
127
+ }
128
+ for (const excluded of excludes) {
129
+ includes.delete(excluded);
130
+ }
131
+ return [...includes];
132
+ };
133
+ const toAffectedWorkspaceResult = (internal, effectiveInputsByName) => ({
134
+ workspace: internal.workspace,
135
+ inputs: effectiveInputsByName.get(internal.workspace.name) ?? {},
136
+ isAffected: internal.isAffected,
137
+ affectedReasons: {
138
+ changedFiles: internal.affectedReasons.changedFiles.map((file) => ({
139
+ projectFilePath: file.filePath,
140
+ inputMatch: file.inputPattern,
141
+ ...(file.fileMetadata?.git && {
142
+ gitReasons: file.fileMetadata.git.reasons,
143
+ }),
144
+ })),
145
+ dependencies: internal.affectedReasons.dependencies,
146
+ externalDependencies: internal.affectedReasons.externalDependencies,
147
+ },
148
+ });
149
+ const determineAffectedWorkspaces = async (project, options) => {
150
+ const ignoreWorkspaceDependencies =
151
+ options.ignoreWorkspaceDependencies ?? false;
152
+ const ignoreExternalDependencies =
153
+ options.ignoreExternalDependencies ?? false;
154
+ const { inputs: workspaceInputs, effectiveInputsByName } =
155
+ buildWorkspaceInputs({
156
+ project,
157
+ script: options.script,
158
+ });
159
+ if (isOptionsForDiffSource(options, "git")) {
160
+ const baseRef =
161
+ options.diffOptions?.baseRef ??
162
+ project.config.root.defaults.affectedBaseRef;
163
+ const headRef = options.diffOptions?.headRef ?? DEFAULT_HEAD_REF;
164
+ const { affectedWorkspaces, baseSha, headSha } =
165
+ await getGitAffectedWorkspaces({
166
+ rootDirectory: project.rootDirectory,
167
+ workspacesOptions: {
168
+ workspaceInputs,
169
+ workspaces: project.workspaces,
170
+ ignoreWorkspaceDependencies,
171
+ ignoreExternalDependencies,
172
+ },
173
+ gitOptions: {
174
+ baseRef,
175
+ headRef,
176
+ ignoreUntracked: options.diffOptions?.ignoreUntracked,
177
+ ignoreStaged: options.diffOptions?.ignoreStaged,
178
+ ignoreUnstaged: options.diffOptions?.ignoreUnstaged,
179
+ ignoreUncommitted: options.diffOptions?.ignoreUncommitted,
180
+ },
181
+ });
182
+ return {
183
+ metadata: {
184
+ diffSource: "git",
185
+ git: {
186
+ baseRef,
187
+ headRef,
188
+ baseSha,
189
+ headSha,
190
+ },
191
+ },
192
+ workspaceResults: affectedWorkspaces.map((result) =>
193
+ toAffectedWorkspaceResult(result, effectiveInputsByName),
194
+ ),
195
+ };
196
+ }
197
+ const expandedChangedFilePaths = expandChangedFilesPatterns({
198
+ rootDirectory: project.rootDirectory,
199
+ patterns: options.changedFiles,
200
+ });
201
+ const lockfileInChangedFiles = expandedChangedFilePaths.includes(
202
+ BUN_LOCK_PROJECT_RELATIVE_PATH,
203
+ );
204
+ const externalDepChangesByWorkspace =
205
+ !ignoreExternalDependencies && lockfileInChangedFiles
206
+ ? buildLockfileChangeSyntheticEntries(project.workspaces)
207
+ : new Map();
208
+ const { affectedWorkspaces } = await getFileAffectedWorkspaces({
209
+ rootDirectory: project.rootDirectory,
210
+ workspaceInputs,
211
+ changedFilePaths: expandedChangedFilePaths,
212
+ externalDepChangesByWorkspace,
213
+ ignoreWorkspaceDependencies,
214
+ });
215
+ return {
216
+ metadata: {
217
+ diffSource: "fileList",
218
+ },
219
+ workspaceResults: affectedWorkspaces.map((result) =>
220
+ toAffectedWorkspaceResult(result, effectiveInputsByName),
221
+ ),
222
+ };
223
+ };
224
+
225
+ export { determineAffectedWorkspaces, isOptionsForDiffSource };