Skip to content

Commit

Permalink
fix: jsr specifier does not support tags
Browse files Browse the repository at this point in the history
When a jsr specifier is used, an error is returned if the version
segment contains a tag.

Fixes: denoland/deno#22420
  • Loading branch information
irbull committed Feb 17, 2024
1 parent 2341e9a commit 20d778c
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 1 deletion.
48 changes: 47 additions & 1 deletion src/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ use deno_semver::npm::NpmPackageReqReference;
use deno_semver::package::PackageNv;
use deno_semver::package::PackageNvReference;
use deno_semver::package::PackageReq;
use deno_semver::package::PackageReqReferenceParseError;
use deno_semver::RangeSetOrTag;
use deno_semver::Version;
use futures::future::LocalBoxFuture;
use futures::future::Shared;
Expand All @@ -62,6 +64,7 @@ use std::collections::HashSet;
use std::collections::VecDeque;
use std::fmt;
use std::sync::Arc;
use thiserror::Error;
use url::Url;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
Expand Down Expand Up @@ -2770,6 +2773,14 @@ struct Builder<'a, 'graph> {
diagnostics: Vec<BuildDiagnostic>,
}

#[derive(Error, Debug, Clone)]
pub enum JsrPackageFormatError {
#[error(transparent)]
JsrPackageParseError(PackageReqReferenceParseError),
#[error("Version tag not supported in jsr specifiers.")]
JsrPackageVersionTagNotSupportedError,
}

impl<'a, 'graph> Builder<'a, 'graph> {
#[allow(clippy::too_many_arguments)]
pub async fn build(
Expand Down Expand Up @@ -3508,7 +3519,7 @@ impl<'a, 'graph> Builder<'a, 'graph> {
maybe_range: Option<Range>,
is_dynamic: bool,
) {
match JsrPackageReqReference::from_specifier(&specifier) {
match validate_jsr_specifier(&specifier) {
Ok(package_ref) => {
if let Some(range) = &maybe_range {
if let Some(nv) =
Expand Down Expand Up @@ -4120,6 +4131,19 @@ impl<'a, 'graph> Builder<'a, 'graph> {
}
}

fn validate_jsr_specifier(
specifier: &Url,
) -> Result<JsrPackageReqReference, JsrPackageFormatError> {
let package_ref = JsrPackageReqReference::from_specifier(&specifier)
.map_err(|err| JsrPackageFormatError::JsrPackageParseError(err))?;
match package_ref.req().version_req.inner() {
RangeSetOrTag::Tag(_) => {
Err(JsrPackageFormatError::JsrPackageVersionTagNotSupportedError)
}
RangeSetOrTag::RangeSet(_) => Ok(package_ref),
}
}

fn normalize_export_name(sub_path: Option<&str>) -> Cow<str> {
let Some(sub_path) = sub_path else {
return Cow::Borrowed(".");
Expand Down Expand Up @@ -4483,6 +4507,28 @@ mod tests {
}));
}

#[test]
fn test_jsr_import_format() {
assert!(
validate_jsr_specifier(&Url::parse("jsr:@scope/mod@tag").unwrap())
.is_err(),
"jsr import specifier with tag should be an error"
);

assert!(
validate_jsr_specifier(&Url::parse("jsr:@scope/mod@").unwrap()).is_err()
);

assert!(validate_jsr_specifier(
&Url::parse("jsr:@scope/mod@1.2.3").unwrap()
)
.is_ok());

assert!(
validate_jsr_specifier(&Url::parse("jsr:@scope/mod").unwrap()).is_ok()
);
}

#[test]
fn test_module_dependency_includes() {
let specifier = ModuleSpecifier::parse("file:///a.ts").unwrap();
Expand Down
47 changes: 47 additions & 0 deletions tests/specs/graph/JsrSpecifiers_VersionTagNotSupported.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# https://jsr.io/@scope/a/meta.json
{
"versions": {
"1.0.0": {}
}
}

# mod.ts
import 'jsr:@scope/a@tag';

# output
{
"roots": [
"file:///mod.ts"
],
"modules": [
{
"kind": "esm",
"dependencies": [
{
"specifier": "jsr:@scope/a@tag",
"code": {
"specifier": "jsr:@scope/a@tag",
"span": {
"start": {
"line": 0,
"character": 7
},
"end": {
"line": 0,
"character": 25
}
}
}
}
],
"size": 27,
"mediaType": "TypeScript",
"specifier": "file:///mod.ts"
},
{
"specifier": "jsr:@scope/a@tag",
"error": "Version tag not supported in jsr specifiers."
}
],
"redirects": {}
}

0 comments on commit 20d778c

Please sign in to comment.