Skip to content

Commit 23c764a

Browse files
committed
fix: check dependencies when adding imports
1 parent 6e4f8d4 commit 23c764a

File tree

2 files changed

+80
-5
lines changed

2 files changed

+80
-5
lines changed

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptWriter.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616
package software.amazon.smithy.typescript.codegen;
1717

1818
import java.nio.file.Path;
19+
import java.util.List;
20+
import java.util.Set;
1921
import java.util.function.BiFunction;
2022
import java.util.function.UnaryOperator;
2123
import software.amazon.smithy.codegen.core.CodegenException;
2224
import software.amazon.smithy.codegen.core.Symbol;
25+
import software.amazon.smithy.codegen.core.SymbolDependency;
2326
import software.amazon.smithy.codegen.core.SymbolReference;
2427
import software.amazon.smithy.codegen.core.SymbolWriter;
2528
import software.amazon.smithy.model.Model;
@@ -29,6 +32,7 @@
2932
import software.amazon.smithy.model.traits.DeprecatedTrait;
3033
import software.amazon.smithy.model.traits.DocumentationTrait;
3134
import software.amazon.smithy.model.traits.InternalTrait;
35+
import software.amazon.smithy.utils.SetUtils;
3236
import software.amazon.smithy.utils.SmithyUnstableApi;
3337
import software.amazon.smithy.utils.StringUtils;
3438

@@ -49,6 +53,32 @@
4953
@SmithyUnstableApi
5054
public final class TypeScriptWriter extends SymbolWriter<TypeScriptWriter, ImportDeclarations> {
5155
public static final String CODEGEN_INDICATOR = "// smithy-typescript generated code\n";
56+
public static final Set<String> EXEMPT_DEPENDENCIES = SetUtils.of(
57+
"buffer",
58+
"child_process",
59+
"crypto",
60+
"dns",
61+
"dns/promises",
62+
"events",
63+
"fs",
64+
"fs/promises",
65+
"http",
66+
"http2",
67+
"https",
68+
"os",
69+
"path",
70+
"path/posix",
71+
"path/win32",
72+
"process",
73+
"stream",
74+
"stream/consumers",
75+
"stream/promises",
76+
"stream/web",
77+
"tls",
78+
"url",
79+
"util",
80+
"zlib"
81+
);
5282

5383
private final String moduleName;
5484
private final boolean withAttribution;
@@ -114,6 +144,40 @@ public TypeScriptWriter addIgnoredDefaultImport(String name, String from, String
114144
*/
115145
@Deprecated
116146
public TypeScriptWriter addImport(String name, String as, String from) {
147+
final boolean isPackageImport =
148+
from.startsWith("@")
149+
|| (!from.startsWith("/") && !from.startsWith("."));
150+
151+
if (isPackageImport) {
152+
String[] packageNameSegments = from.split("/");
153+
String packageName =
154+
from.startsWith("@")
155+
? packageNameSegments[0] + "/" + packageNameSegments[1]
156+
: packageNameSegments[0];
157+
List<SymbolDependency> dependencies = getDependencies();
158+
if (!EXEMPT_DEPENDENCIES.contains(packageName)
159+
&& dependencies.stream().noneMatch(dep -> dep.getPackageName().equals(packageName))) {
160+
throw new CodegenException(
161+
"""
162+
The import %s does not correspond to a registered dependency.
163+
TypeScriptWriter::addDependency() is required before ::addImport(), or call ::addImportUnchecked().
164+
""".formatted(from)
165+
);
166+
}
167+
}
168+
169+
getImportContainer().addImport(name, as, from);
170+
return this;
171+
}
172+
173+
/**
174+
* Imports a type using an alias from a module only if necessary.
175+
* @return Returns the writer.
176+
*
177+
* @deprecated Use {@link TypeScriptWriter#addImport(String, String, TypeScriptDependency)} addImport}
178+
*/
179+
@Deprecated
180+
public TypeScriptWriter addImportUnchecked(String name, String as, String from) {
117181
getImportContainer().addImport(name, as, from);
118182
return this;
119183
}
@@ -126,6 +190,15 @@ public TypeScriptWriter addImport(String name, String as, String from) {
126190
* @param from PackageContainer to import the type from.
127191
* @return Returns the writer.
128192
*/
193+
public TypeScriptWriter addImport(String name, String as, Dependency from) {
194+
addDependency(from);
195+
return this.addImport(name, as, from.getPackageName());
196+
}
197+
198+
/**
199+
* @deprecated use {@link #addImport(String name, String as, Dependency from)}.
200+
*/
201+
@Deprecated
129202
public TypeScriptWriter addImport(String name, String as, PackageContainer from) {
130203
return this.addImport(name, as, from.getPackageName());
131204
}

smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/TypeScriptWriterTest.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,17 @@ public void writesDocStrings() {
2121
public void doesNotAddNewlineBetweenManagedAndExplicitImports() {
2222
TypeScriptWriter writer = new TypeScriptWriter("foo");
2323
writer.write("import { Foo } from \"baz\";");
24-
writer.addImport("Baz", "Baz", "hello");
24+
writer.addImport("Baz", "Baz", "./hello");
2525
writer.addImport("Bar", "__Bar", TypeScriptDependency.SMITHY_TYPES);
2626
writer.addRelativeImport("Qux", "__Qux", Paths.get("./qux"));
2727
String result = writer.toString();
2828

29-
assertThat(result, equalTo(CODEGEN_INDICATOR + "import { Qux as __Qux } from \"./qux\";\n"
30-
+ "import { Bar as __Bar } from \"@smithy/types\";\n"
31-
+ "import { Baz } from \"hello\";\n"
32-
+ "import { Foo } from \"baz\";\n"));
29+
assertThat(result, equalTo("""
30+
%simport { Baz } from "./hello";
31+
import { Qux as __Qux } from "./qux";
32+
import { Bar as __Bar } from "@smithy/types";
33+
import { Foo } from "baz";
34+
""".formatted(CODEGEN_INDICATOR)));
3335
}
3436

3537
@Test

0 commit comments

Comments
 (0)