Skip to content

Add generateTypeDoc setting for typedoc support #1091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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