fix(resolver): resolve linked packages by bare specifier (#35228)
Linked packages declared via `"links"` in `deno.json` have not been
resolvable through a bare specifier since #34519, which gated them out
of bare-specifier resolution to fix #29436. Only a `jsr:` specifier or an
import map entry worked. That broke the workflow people relied on for
private packages: a private package is not published to any registry, so
it cannot be referenced as a real `jsr:`/`npm:` dependency, and
`"links"` was the only way to import it by name. The fallout is tracked in #34829
and #35214, and the connection to `deno link` (#34359) is described in
#35227.
The workarounds suggested for the new behavior all fall short. Importing
via `jsr:@org/foo` trips the `no-import-prefix` and
`no-unversioned-import` lints and is a supply-chain footgun, since `deno update` will then look
the private name up on jsr and a colliding public publish could be pulled
in. Adding an import map entry `"@org/foo": "jsr:@org/foo"` does not compose
transitively: when a linked package's own files import a sibling
(`@org/aaa` importing `@org/bbb`), the root import map does not apply
inside the linked package's scope, so every member would have to be duplicated
by hand. Using a real workspace requires the member to be nested under the
workspace root rather than a sibling or absolute path.
This change treats linked packages like workspace members for
bare-specifier resolution. Conceptually a link is just a workspace
member that lives outside the workspace tree, so the `!p.is_link` filter in the
bare-resolution loop is dropped. Workspace members are still listed
before links in `jsr_pkgs`, so they keep precedence when a name collides, and
the `jsr:`-prefixed and import map resolution paths are untouched, so the
override use case `"links"` was designed for keeps working exactly as
before.
This intentionally reverses the bare-resolution behavior that #34519
introduced for #29436. The original concern was that resolving a linked
package by bare name was surprising, but it is not silent: you opt in by
listing the path in `"links"`, and there is no private-registry
alternative for the affected users. The `link_bare_specifier` spec test and the two
resolver unit tests that locked in the rejection are updated to assert
resolution, and a new `link_transitive_sibling` spec test covers the
sibling-import case that an import map entry could not satisfy.
A follow-up can simplify `deno link` (#34359) to stop injecting the
`"@org/foo": "jsr:@org/foo"` import map entry, since bare imports now
work without it.
Closes #35227
Closes #35214