Skip to content

Commit

Permalink
Add generateTypeDoc setting for typedoc support (smithy-lang#1091)
Browse files Browse the repository at this point in the history
Breaking change: typedoc support was previously generated by default,
but this change makes typedoc support opt-in through the
`generateTypeDoc` boolean setting.
  • Loading branch information
Steven Yuan authored Dec 5, 2023
1 parent 43d4bfb commit bc4911f
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ final class DirectedTypeScriptCodegen
* A mapping of static resource files to copy over to a new filename.
*/
private static final Map<String, String> STATIC_FILE_COPIES = MapUtils.of(
"typedoc.json", "typedoc.json",
"tsconfig.json", "tsconfig.json",
"tsconfig.cjs.json", "tsconfig.cjs.json",
"tsconfig.es.json", "tsconfig.es.json",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
final class PackageJsonGenerator {

public static final String PACKAGE_JSON_FILENAME = "package.json";
public static final String TYPEDOC_FILE_NAME = "typedoc.json";
public static final String VITEST_CONFIG_FILENAME = "vite.config.js";

private PackageJsonGenerator() {}
Expand Down Expand Up @@ -67,6 +68,24 @@ static void writePackageJson(
PackageJsonGenerator.class.getResourceAsStream(VITEST_CONFIG_FILENAME)));
}

if (settings.generateTypeDoc()) {
// Add typedoc to the "devDependencies" if not present
if (devDeps.getMember(TypeScriptDependency.TYPEDOC.packageName).isEmpty()) {
devDeps = devDeps.withMember(
TypeScriptDependency.TYPEDOC.packageName,
TypeScriptDependency.TYPEDOC.version);
node = node.withMember("devDependencies", devDeps);
}

// Add build:docs script
ObjectNode scripts = node.getObjectMember("scripts").orElse(Node.objectNode());
scripts = scripts.withMember("build:docs", "typedoc");
node = node.withMember("scripts", scripts);

// Write typedoc.json
manifest.writeFile(TYPEDOC_FILE_NAME, PackageJsonGenerator.class, TYPEDOC_FILE_NAME);
}

// These are currently only generated for clients, but they may be needed for ssdk as well.
if (settings.generateClient()) {
// Add the Node vs Browser hook.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ public enum TypeScriptDependency implements Dependency {
// Conditionally added when specs have been generated.
VITEST("devDependencies", "vitest", "^0.33.0", false),

// Conditionally added when `generateTypeDoc` is true.
TYPEDOC("devDependencies", "typedoc", "0.23.23", false),

// Server dependency for SSDKs
SERVER_COMMON("dependencies", "@aws-smithy/server-common", false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public final class TypeScriptSettings {
private static final String PACKAGE_MANAGER = "packageManager";
private static final String CREATE_DEFAULT_README = "createDefaultReadme";
private static final String EXPERIMENTAL_IDENTITY_AND_AUTH = "experimentalIdentityAndAuth";
private static final String GENERATE_TYPEDOC = "generateTypeDoc";

private String packageName;
private String packageDescription = "";
Expand All @@ -75,6 +76,7 @@ public final class TypeScriptSettings {
private PackageManager packageManager = PackageManager.YARN;
private boolean createDefaultReadme = false;
private boolean experimentalIdentityAndAuth = false;
private boolean generateTypeDoc = false;

@Deprecated
public static TypeScriptSettings from(Model model, ObjectNode config) {
Expand Down Expand Up @@ -110,6 +112,8 @@ public static TypeScriptSettings from(Model model, ObjectNode config, ArtifactTy
config.getBooleanMember(CREATE_DEFAULT_README).map(BooleanNode::getValue).orElse(false));
settings.setExperimentalIdentityAndAuth(
config.getBooleanMemberOrDefault(EXPERIMENTAL_IDENTITY_AND_AUTH, false));
settings.setGenerateTypeDoc(
config.getBooleanMember(GENERATE_TYPEDOC).map(BooleanNode::getValue).orElse(false));
settings.setPackageManager(
config.getStringMember(PACKAGE_MANAGER)
.map(s -> PackageManager.fromString(s.getValue()))
Expand Down Expand Up @@ -380,6 +384,24 @@ public void setExperimentalIdentityAndAuth(boolean experimentalIdentityAndAuth)
this.experimentalIdentityAndAuth = experimentalIdentityAndAuth;
}

/**
* Returns whether to generate typedoc support.
*
* @return whether to generate typedoc support. Default: false
*/
public boolean generateTypeDoc() {
return generateTypeDoc;
}

/**
* Sets whether to generate typedoc support.
*
* @param generateTypeDoc whether to generate typedoc support
*/
public void setGenerateTypeDoc(boolean generateTypeDoc) {
this.generateTypeDoc = generateTypeDoc;
}

/**
* Gets the corresponding {@link ServiceShape} from a model.
*
Expand Down Expand Up @@ -468,11 +490,11 @@ public enum ArtifactType {
CLIENT(SymbolVisitor::new,
Arrays.asList(PACKAGE, PACKAGE_DESCRIPTION, PACKAGE_JSON, PACKAGE_VERSION, PACKAGE_MANAGER,
SERVICE, PROTOCOL, PRIVATE, REQUIRED_MEMBER_MODE,
CREATE_DEFAULT_README, EXPERIMENTAL_IDENTITY_AND_AUTH)),
CREATE_DEFAULT_README, EXPERIMENTAL_IDENTITY_AND_AUTH, GENERATE_TYPEDOC)),
SSDK((m, s) -> new ServerSymbolVisitor(m, new SymbolVisitor(m, s)),
Arrays.asList(PACKAGE, PACKAGE_DESCRIPTION, PACKAGE_JSON, PACKAGE_VERSION, PACKAGE_MANAGER,
SERVICE, PROTOCOL, PRIVATE, REQUIRED_MEMBER_MODE,
DISABLE_DEFAULT_VALIDATION, CREATE_DEFAULT_README));
DISABLE_DEFAULT_VALIDATION, CREATE_DEFAULT_README, GENERATE_TYPEDOC));

private final BiFunction<Model, TypeScriptSettings, SymbolProvider> symbolProviderFactory;
private final List<String> configProperties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"scripts": {
"build": "concurrently '${packageManager}:build:cjs' '${packageManager}:build:es' '${packageManager}:build:types'",
"build:cjs": "tsc -p tsconfig.cjs.json",
"build:docs": "typedoc",
"build:es": "tsc -p tsconfig.es.json",
"build:types": "tsc -p tsconfig.types.json",
"build:types:downlevel": "downlevel-dts dist-types dist-types/ts3.4",
Expand All @@ -24,7 +23,6 @@
"concurrently": "7.0.0",
"downlevel-dts": "0.10.1",
"rimraf": "^3.0.0",
"typedoc": "0.23.23",
"typescript": "~4.9.5"
},
"engines": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertTrue;

class PackageJsonGeneratorTest {
Expand Down Expand Up @@ -126,6 +127,71 @@ void expectTestScriptAndTestConfigToBeAdded() {
assertThat(configString, containsString("include: ['**/*.spec.ts']"));
}

@Test
void expectTypeDocToNotBeAdded() {
Model model = Model.assembler()
.addImport(getClass().getResource("simple-service.smithy"))
.assemble()
.unwrap();

MockManifest manifest = new MockManifest();

ObjectNode settings = Node.objectNodeBuilder()
.withMember("service", Node.from("smithy.example#Example"))
.withMember("package", Node.from("example"))
.withMember("packageVersion", Node.from("1.0.0"))
.withMember("packageDescription", Node.from("example description"))
.build();

final TypeScriptSettings typeScriptSettings = TypeScriptSettings.from(model, settings,
TypeScriptSettings.ArtifactType.CLIENT);

Map<String, Map<String, SymbolDependency>> deps = new HashMap<>();

PackageJsonGenerator.writePackageJson(typeScriptSettings, manifest, deps);

assertTrue(manifest.getFileString(PackageJsonGenerator.PACKAGE_JSON_FILENAME).isPresent());
assertTrue(manifest.getFileString(PackageJsonGenerator.TYPEDOC_FILE_NAME).isEmpty());

String packageJson = manifest.getFileString(PackageJsonGenerator.PACKAGE_JSON_FILENAME).get();

assertThat(packageJson, not(containsString("\"build:docs\": \"typedoc\"")));
assertThat(packageJson, not(containsString("\"typedoc\": \"0.23.23\"")));
}

@Test
void expectTypeDocToBeAddedWithGenerateTypeDoc() {
Model model = Model.assembler()
.addImport(getClass().getResource("simple-service.smithy"))
.assemble()
.unwrap();

MockManifest manifest = new MockManifest();

ObjectNode settings = Node.objectNodeBuilder()
.withMember("service", Node.from("smithy.example#Example"))
.withMember("package", Node.from("example"))
.withMember("packageVersion", Node.from("1.0.0"))
.withMember("packageDescription", Node.from("example description"))
.withMember("generateTypeDoc", true)
.build();

final TypeScriptSettings typeScriptSettings = TypeScriptSettings.from(model, settings,
TypeScriptSettings.ArtifactType.CLIENT);

Map<String, Map<String, SymbolDependency>> deps = new HashMap<>();

PackageJsonGenerator.writePackageJson(typeScriptSettings, manifest, deps);

assertTrue(manifest.getFileString(PackageJsonGenerator.PACKAGE_JSON_FILENAME).isPresent());
assertTrue(manifest.getFileString(PackageJsonGenerator.TYPEDOC_FILE_NAME).isPresent());

String packageJson = manifest.getFileString(PackageJsonGenerator.PACKAGE_JSON_FILENAME).get();

assertThat(packageJson, containsString("\"build:docs\": \"typedoc\""));
assertThat(packageJson, containsString("\"typedoc\": \"0.23.23\""));
}

private static Stream<Arguments> providePackageDescriptionTestCases() {
return Stream.of(
Arguments.of(TypeScriptSettings.ArtifactType.SSDK, "example server"),
Expand Down

0 comments on commit bc4911f

Please sign in to comment.