Skip to content

chore: Migrate to the new documenter API #82

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
28 changes: 4 additions & 24 deletions scripts/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,21 @@
// SPDX-License-Identifier: Apache-2.0
import path from "node:path";

import { documentComponents, documentTestUtils } from "@cloudscape-design/documenter";
import { documentTestUtils, writeComponentsDocumentation } from "@cloudscape-design/documenter";

import { listPublicDirs, writeSourceFile } from "./utils.js";
import { writeSourceFile } from "./utils.js";

const publicDirs = listPublicDirs("src");
const targetDir = "lib/components/internal/api-docs";

componentDocs();
testUtilDocs();

function validatePublicFiles(definitionFiles) {
for (const publicDir of publicDirs) {
if (!definitionFiles.includes(publicDir)) {
throw new Error(`Directory src/${publicDir} does not have a corresponding API definition`);
}
}
}

function componentDocs() {
const definitions = documentComponents({
writeComponentsDocumentation({
outDir: path.join(targetDir, "components"),
tsconfigPath: path.resolve("tsconfig.json"),
publicFilesGlob: "src/*/index.tsx",
});
const outDir = path.join(targetDir, "components");
for (const definition of definitions) {
writeSourceFile(
path.join(outDir, definition.dashCaseName + ".js"),
`module.exports = ${JSON.stringify(definition, null, 2)};`,
);
}
const indexContent = `module.exports = {
${definitions.map((definition) => `${JSON.stringify(definition.dashCaseName)}:require('./${definition.dashCaseName}')`).join(",\n")}
}`;
writeSourceFile(path.join(outDir, "index.js"), indexContent);
validatePublicFiles(definitions.map((def) => def.dashCaseName));
}

function testUtilDocs() {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/__snapshots__/documenter.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`definition for 'code-view' matches the snapshot 1`] = `
exports[`definition for code-view matches the snapshot > code-view 1`] = `
{
"dashCaseName": "code-view",
"events": [],
Expand Down
14 changes: 10 additions & 4 deletions src/__tests__/documenter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
// SPDX-License-Identifier: Apache-2.0
import { expect, test } from "vitest";

// @ts-expect-error no types here
import apiDocs from "../../lib/components/internal/api-docs/components";
import componentDefinitions from "../../lib/components/internal/api-docs/components";
Copy link
Member Author

@taheramr taheramr May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decided to follow how we define the documenter tests everywhere by using the getAllComponents util

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

import { getAllComponents } from "./utils";

test.each(Object.entries(apiDocs))("definition for $0 matches the snapshot", (name, definition) => {
expect(definition).toMatchSnapshot();
test.each<string>(getAllComponents())(`definition for %s matches the snapshot`, (componentName: string) => {
const definition = componentDefinitions[componentName];
// overriding with a fake value so that when there are icon changes in components this test doesn't block it
const iconNameDefinition = definition.properties.find(({ name }: { name: string }) => name === "iconName");
if (iconNameDefinition && iconNameDefinition.inlineType?.type === "union") {
iconNameDefinition.inlineType.values = ["comes from @cloudscape-design/components"];
}
Comment on lines +10 to +14
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed in this package

We can add it later, if we really start using icons in snapshots

expect(definition).toMatchSnapshot(componentName);
});
27 changes: 27 additions & 0 deletions src/__tests__/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* eslint-env node */
/* eslint-disable header/header */
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
Comment on lines +1 to +4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you put comments in this order, they pass the linter without disabling

Suggested change
/* eslint-env node */
/* eslint-disable header/header */
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/* eslint-env node */

import * as fs from "node:fs";
import * as path from "node:path";

const componentsDir = path.resolve(__dirname, "../../lib/components");

export function getAllComponents(): string[] {
return fs
.readdirSync(componentsDir)
.filter(
(name) =>
name !== "internal" &&
name !== "test-utils" &&
!name.includes(".") &&
!name.includes("LICENSE") &&
!name.includes("NOTICE"),
);
}

export async function requireComponent(componentName: string) {
// eslint-disable-next-line no-unsanitized/method
const { default: Component } = await import(path.join(componentsDir, componentName));
return Component;
}
Loading