@vzn/vx 0.0.156 → 0.0.159

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx",
3
- "version": "0.0.156",
3
+ "version": "0.0.159",
4
4
  "description": "A fast, correct task runner and build cache for JavaScript monorepos.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -17,10 +17,10 @@
17
17
  "node": ">=18"
18
18
  },
19
19
  "optionalDependencies": {
20
- "@vzn/vx-linux-x64": "0.0.156",
21
- "@vzn/vx-linux-arm64": "0.0.156",
22
- "@vzn/vx-darwin-x64": "0.0.156",
23
- "@vzn/vx-darwin-arm64": "0.0.156"
20
+ "@vzn/vx-linux-x64": "0.0.159",
21
+ "@vzn/vx-linux-arm64": "0.0.159",
22
+ "@vzn/vx-darwin-x64": "0.0.159",
23
+ "@vzn/vx-darwin-arm64": "0.0.159"
24
24
  },
25
25
  "dependencies": {
26
26
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -113,7 +113,14 @@ export function validateWorkspace(config: WorkspaceConfig, configPath: string):
113
113
  const fileClaimants = new Map<string, string>()
114
114
  for (const [i, p] of config.plugins.entries()) {
115
115
  if (p === null || typeof p !== 'object') {
116
- throw new UserError(`${configPath}: \`plugins[${i}]\` must be an object`)
116
+ // Nx's nx.json lists plugins by module name (`'@nx/vite/plugin'`);
117
+ // a vx plugin is the value its package's function returns.
118
+ throw new UserError(
119
+ `${configPath}: \`plugins[${i}]\` must be an object` +
120
+ (typeof p === 'string'
121
+ ? ` — a plugin is what its package's function returns (\`nx()\` from \`@vzn/vx-migrate\`), not a module name`
122
+ : ''),
123
+ )
117
124
  }
118
125
  // The loose schema's shape (unknown-typed hooks) plus the one retired
119
126
  // key this loader still refuses by name.
@@ -524,6 +531,7 @@ export function validateProjectConfig(config: ProjectConfig, configPath: string)
524
531
  `let cleanOutputs delete files outside it)`,
525
532
  )
526
533
  }
534
+ assertNoForeignToken(g, `${where}.cache.outputs.files`)
527
535
  if (namesDirItself(g)) {
528
536
  throw new UserError(
529
537
  `${where}.cache.outputs.files: "${g}" names the project directory itself and selects nothing — ` +
@@ -561,6 +569,7 @@ export function validateProjectConfig(config: ProjectConfig, configPath: string)
561
569
  `use cache.inputs.workspaceFiles for workspace-root-relative inputs)`,
562
570
  )
563
571
  }
572
+ assertNoForeignToken(g, `${where}.cache.inputs.files`)
564
573
  if (namesDirItself(g)) {
565
574
  throw new UserError(
566
575
  `${where}.cache.inputs.files: "${g}" names the project directory itself and selects nothing — use "**" for everything under it`,
@@ -716,6 +725,12 @@ const FOREIGN_FIELDS: ReadonlyMap<ReadonlySet<string>, Readonly<Record<string, s
716
725
  cmd: '`exec.command`',
717
726
  script: '`exec.command`',
718
727
  persistent: '`exec.persistent: {}`',
728
+ // Nx's target keys (project.json) and Turbo's `outputLogs`.
729
+ continuous: '`exec.persistent: {}`',
730
+ executor:
731
+ '`exec.command`: vx runs one shell command (`nx()` from `@vzn/vx-migrate` runs an Nx executor as one)',
732
+ options: '`exec.command` (a run-commands `options.command`) and `exec.env`',
733
+ outputLogs: 'the `--output-logs` flag of `vx run`',
719
734
  },
720
735
  ],
721
736
  [EXEC_FIELDS, { cmd: '`command`', script: '`command`' }],
@@ -737,6 +752,9 @@ const FOREIGN_FIELDS: ReadonlyMap<ReadonlySet<string>, Readonly<Record<string, s
737
752
  'a cache plugin in `plugins` (`turboCache()` or `nxCache()` from `@vzn/vx-migrate`)',
738
753
  parallel: '`concurrency`',
739
754
  cacheDirectory: '`cacheDir`',
755
+ defaultBase: 'the base in `--affected=<base>` (default `origin/HEAD`)',
756
+ tasksRunnerOptions: 'a cache plugin in `plugins` (`nxCache()` from `@vzn/vx-migrate`)',
757
+ globalPassThroughEnv: '`exec.env.passThrough` on the tasks it passes to',
740
758
  },
741
759
  ],
742
760
  ])
@@ -807,6 +825,36 @@ function ownFileCovered(glob: string, configPath: string): string | null {
807
825
  return ['package.json', path.basename(configPath)].find((f) => g.match(f)) ?? null
808
826
  }
809
827
 
828
+ /**
829
+ * Turbo's and Nx's glob tokens, pasted from turbo.json or project.json
830
+ * (D-50). vx expands none of them, so each is a literal that matches no
831
+ * file: an input list of `$TURBO_DEFAULT$` keyed the task on nothing and
832
+ * replayed a stale output after its source changed.
833
+ */
834
+ const FOREIGN_TOKENS: readonly (readonly [string, string])[] = [
835
+ [
836
+ '$TURBO_DEFAULT$',
837
+ 'Turbo\'s default input set, which vx does not have — list the files, such as "**" for everything in the project',
838
+ ],
839
+ [
840
+ '$TURBO_ROOT$',
841
+ "Turbo's workspace root — name the path without it in `workspaceFiles`, which is workspace-root-relative",
842
+ ],
843
+ ['{projectRoot}', "Nx's project root — drop it: `files` globs are project-relative already"],
844
+ [
845
+ '{workspaceRoot}',
846
+ "Nx's workspace root — name the path without it in `workspaceFiles`, which is workspace-root-relative",
847
+ ],
848
+ ]
849
+
850
+ function assertNoForeignToken(glob: string, where: string): void {
851
+ for (const [token, meaning] of FOREIGN_TOKENS) {
852
+ if (glob.includes(token)) {
853
+ throw new UserError(`${where}: "${glob}" holds ${token}, ${meaning}`)
854
+ }
855
+ }
856
+ }
857
+
810
858
  /**
811
859
  * `.`, `./`, `././` (with or without a `!`) name the directory itself, which
812
860
  * no matcher expands: the entry selected nothing and said so nowhere.
@@ -1016,6 +1064,7 @@ function validateWorkspaceGlobs(v: unknown, where: string, negation: boolean): v
1016
1064
  `entries are workspace-root-relative and must stay within the workspace root`,
1017
1065
  )
1018
1066
  }
1067
+ assertNoForeignToken(g, where)
1019
1068
  if (namesDirItself(g)) {
1020
1069
  throw new UserError(
1021
1070
  `${where}: "${g}" names the workspace root itself and selects nothing — use "**" for everything under it`,