Skip to content

Commit 61c2308

Browse files
committed
fix: ban import assertions during publishing
Only import attributes are allowed now.
1 parent c9740ea commit 61c2308

File tree

10 files changed

+145
-2
lines changed

10 files changed

+145
-2
lines changed

api/src/analysis.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::collections::HashSet;
55
use std::sync::Arc;
66

77
use deno_ast::swc::common::comments::CommentKind;
8+
use deno_ast::swc::common::Span;
89
use deno_ast::LineAndColumnDisplay;
910
use deno_ast::MediaType;
1011
use deno_ast::ModuleSpecifier;
@@ -727,6 +728,54 @@ fn check_for_banned_syntax(
727728
continue;
728729
}
729730
},
731+
ast::ModuleDecl::Import(n) => {
732+
if let Some(with) = &n.with {
733+
let range =
734+
Span::new(n.src.span.hi(), with.span.lo(), n.src.span.ctxt)
735+
.range();
736+
let keyword = parsed_source.text_info().range_text(&range);
737+
if keyword.contains("assert") {
738+
let (line, column) = line_col(&with.span.range());
739+
return Err(PublishError::BannedImportAssertion {
740+
specifier: parsed_source.specifier().to_string(),
741+
line,
742+
column,
743+
});
744+
}
745+
}
746+
}
747+
ast::ModuleDecl::ExportNamed(n) => {
748+
if let Some(with) = &n.with {
749+
let src = n.src.as_ref().unwrap();
750+
let range =
751+
Span::new(src.span.hi(), with.span.lo(), src.span.ctxt).range();
752+
let keyword = parsed_source.text_info().range_text(&range);
753+
if keyword.contains("assert") {
754+
let (line, column) = line_col(&with.span.range());
755+
return Err(PublishError::BannedImportAssertion {
756+
specifier: parsed_source.specifier().to_string(),
757+
line,
758+
column,
759+
});
760+
}
761+
}
762+
}
763+
ast::ModuleDecl::ExportAll(n) => {
764+
if let Some(with) = &n.with {
765+
let range =
766+
Span::new(n.src.span.hi(), with.span.lo(), n.src.span.ctxt)
767+
.range();
768+
let keyword = parsed_source.text_info().range_text(&range);
769+
if keyword.contains("assert") {
770+
let (line, column) = line_col(&with.span.range());
771+
return Err(PublishError::BannedImportAssertion {
772+
specifier: parsed_source.specifier().to_string(),
773+
line,
774+
column,
775+
});
776+
}
777+
}
778+
}
730779
_ => continue,
731780
},
732781
ast::ModuleItem::Stmt(n) => match n {
@@ -920,5 +969,29 @@ mod tests {
920969

921970
let x = parse("import express = React.foo;");
922971
assert!(super::check_for_banned_syntax(&x).is_ok());
972+
973+
let x = parse("import './data.json' assert { type: 'json' }");
974+
let err = super::check_for_banned_syntax(&x).unwrap_err();
975+
assert!(
976+
matches!(err, super::PublishError::BannedImportAssertion { .. }),
977+
"{err:?}",
978+
);
979+
980+
let x = parse("export { a } from './data.json' assert { type: 'json' }");
981+
let err = super::check_for_banned_syntax(&x).unwrap_err();
982+
assert!(
983+
matches!(err, super::PublishError::BannedImportAssertion { .. }),
984+
"{err:?}",
985+
);
986+
987+
let x = parse("export * from './data.json' assert { type: 'json' }");
988+
let err = super::check_for_banned_syntax(&x).unwrap_err();
989+
assert!(
990+
matches!(err, super::PublishError::BannedImportAssertion { .. }),
991+
"{err:?}",
992+
);
993+
994+
let x = parse("export * from './data.json' with { type: 'json' }");
995+
assert!(super::check_for_banned_syntax(&x).is_ok(), "{err:?}",);
923996
}
924997
}

api/src/publish.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,41 @@ pub mod tests {
972972
assert_eq!(error.code, "invalidPath");
973973
}
974974

975+
#[tokio::test]
976+
async fn import_assertions() {
977+
let t = TestSetup::new().await;
978+
979+
let bytes = create_mock_tarball("import_assertions");
980+
let task = process_tarball_setup2(
981+
&t,
982+
bytes,
983+
&PackageName::try_from("foo").unwrap(),
984+
&Version::try_from("1.2.3").unwrap(),
985+
false,
986+
)
987+
.await;
988+
assert_eq!(task.status, PublishingTaskStatus::Failure, "{task:#?}");
989+
let error = task.error.unwrap();
990+
assert_eq!(error.code, "bannedImportAssertion");
991+
assert_eq!(error.message, "import assertions are not allowed, use import attributes instead (replace 'assert' with 'with') file:///mod.ts:1:29");
992+
}
993+
994+
#[tokio::test]
995+
async fn import_attributes() {
996+
let t = TestSetup::new().await;
997+
998+
let bytes = create_mock_tarball("import_attributes");
999+
let task = process_tarball_setup2(
1000+
&t,
1001+
bytes,
1002+
&PackageName::try_from("foo").unwrap(),
1003+
&Version::try_from("1.2.3").unwrap(),
1004+
false,
1005+
)
1006+
.await;
1007+
assert_eq!(task.status, PublishingTaskStatus::Success, "{task:#?}");
1008+
}
1009+
9751010
#[tokio::test]
9761011
async fn jsr_jsonc() {
9771012
let t = TestSetup::new().await;

api/src/tarball.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ pub enum PublishError {
485485
#[error("invalid external import to '{specifier}', only 'jsr:', 'npm:', 'data:' and 'node:' imports are allowed ({info})")]
486486
InvalidExternalImport { specifier: String, info: String },
487487

488-
#[error("Modifying global types is not allowed {specifier}:{line}:{column}")]
488+
#[error("modifying global types is not allowed {specifier}:{line}:{column}")]
489489
GlobalTypeAugmentation {
490490
specifier: String,
491491
line: usize,
@@ -499,13 +499,20 @@ pub enum PublishError {
499499
column: usize,
500500
},
501501

502-
#[error("Triple slash directives that modify globals (for example, '/// <reference no-default-lib=\"true\" />' or '/// <reference lib=\"dom\" />') are not allowed. Instead instruct the user of your package to specify these directives. {specifier}:{line}:{column}")]
502+
#[error("triple slash directives that modify globals (for example, '/// <reference no-default-lib=\"true\" />' or '/// <reference lib=\"dom\" />') are not allowed. Instead instruct the user of your package to specify these directives. {specifier}:{line}:{column}")]
503503
BannedTripleSlashDirectives {
504504
specifier: String,
505505
line: usize,
506506
column: usize,
507507
},
508508

509+
#[error("import assertions are not allowed, use import attributes instead (replace 'assert' with 'with') {specifier}:{line}:{column}")]
510+
BannedImportAssertion {
511+
specifier: String,
512+
line: usize,
513+
column: usize,
514+
},
515+
509516
#[error(
510517
"file at path '{path}' too large, max size is {max_size}, got {size}"
511518
)]
@@ -614,6 +621,9 @@ impl PublishError {
614621
PublishError::BannedTripleSlashDirectives { .. } => {
615622
Some("bannedTripleSlashDirectives")
616623
}
624+
PublishError::BannedImportAssertion { .. } => {
625+
Some("bannedImportAssertion")
626+
}
617627
PublishError::InvalidExternalImport { .. } => {
618628
Some("invalidExternalImport")
619629
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"abc"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "@scope/foo",
3+
"version": "1.2.3",
4+
"exports": "./mod.ts"
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "./data.json" assert { type: "json" };
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"abc"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "@scope/foo",
3+
"version": "1.2.3",
4+
"exports": "./mod.ts"
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "./data.json" with { type: "json" };

frontend/docs/troubleshooting.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,17 @@ allowed by JSR. JSR only allows triple slash directives that are
105105

106106
You can fix this error by removing the triple slash directive from your source.
107107

108+
### `bannedImportAssertion`
109+
110+
The package being published contains the legacy "import assertions" syntax,
111+
which is not allowed by JSR. JSR only allows the new "import attributes" syntax.
112+
113+
`import "./data.json" assert { type: "json" };` is not allowed.
114+
`import "./data.json" with { type: "json" };` is allowed.
115+
116+
You can fix this error by updating the import assertion to an import attribute,
117+
by replacing `assert` with `with`.
118+
108119
### `fileTooLarge`
109120

110121
The package being published contains a file that is too large. JSR only allows

0 commit comments

Comments
 (0)