From 3f9ba2fffca901a35a988ea6e25072a19454c6fa Mon Sep 17 00:00:00 2001 From: tjprescott Date: Mon, 6 Mar 2023 09:14:27 -0800 Subject: [PATCH] Updates. --- .gitignore | 8 +++-- .../emitters/typespec-apiview/cspell.yaml | 1 + .../emitters/typespec-apiview/package.json | 3 +- .../emitters/typespec-apiview/src/apiview.ts | 6 ++-- .../emitters/typespec-apiview/src/emitter.ts | 18 +++++----- .../emitters/typespec-apiview/src/lib.ts | 4 +-- .../typespec-apiview/src/namespace-model.ts | 35 ++++--------------- .../typespec-apiview/src/testing/index.ts | 4 +-- .../emitters/typespec-apiview/src/version.ts | 2 +- .../test/apiview-options.test.ts | 6 ++-- .../typespec-apiview/test/apiview.test.ts | 10 +++--- .../typespec-apiview/test/test-host.ts | 7 ++-- 12 files changed, 43 insertions(+), 61 deletions(-) diff --git a/.gitignore b/.gitignore index 57d04b2e371..5dce6d6e3a7 100644 --- a/.gitignore +++ b/.gitignore @@ -500,6 +500,8 @@ tools/oav-traffic-converter/build/ src/swift/*.xcworkspace/xcuserdata/ src/swift/**/*.xcodeproj/xcuserdata/ -# Cadl APIView -cadl-output/ -tools/apiview/emitters/cadl-apiview/temp/ \ No newline at end of file +# TypeSpec APIView +tools/apiview/emitters/cadl-apiview/cadl-output/ +tools/apiview/emitters/cadl-apiview/temp/ +tools/apiview/emitters/typespec-apiview/tsp-output/ +tools/apiview/emitters/typespec-apiview/temp/ \ No newline at end of file diff --git a/tools/apiview/emitters/typespec-apiview/cspell.yaml b/tools/apiview/emitters/typespec-apiview/cspell.yaml index de4ed1284d3..7081335ee16 100644 --- a/tools/apiview/emitters/typespec-apiview/cspell.yaml +++ b/tools/apiview/emitters/typespec-apiview/cspell.yaml @@ -58,6 +58,7 @@ words: - vswhere - westus - xplat + - deindent ignorePaths: - "**/node_modules/**" - "**/dist/**" diff --git a/tools/apiview/emitters/typespec-apiview/package.json b/tools/apiview/emitters/typespec-apiview/package.json index 718807fec41..47611b496c5 100644 --- a/tools/apiview/emitters/typespec-apiview/package.json +++ b/tools/apiview/emitters/typespec-apiview/package.json @@ -33,7 +33,7 @@ ] } }, - "typespecMain": "dist/src/index.js", + "tspMain": "dist/src/index.js", "engines": { "node": ">=16.0.0" }, @@ -57,6 +57,7 @@ "@azure-tools/typespec-azure-core": "0.27.0", "@azure-tools/typespec-autorest": "0.27.0", "@typespec/compiler": "0.41.0", + "@typespec/http": "0.41.0", "@typespec/rest": "0.41.0", "@typespec/versioning": "0.41.0" }, diff --git a/tools/apiview/emitters/typespec-apiview/src/apiview.ts b/tools/apiview/emitters/typespec-apiview/src/apiview.ts index 6ed14f6a79d..d6552bd0605 100644 --- a/tools/apiview/emitters/typespec-apiview/src/apiview.ts +++ b/tools/apiview/emitters/typespec-apiview/src/apiview.ts @@ -414,7 +414,7 @@ export class ApiView { case SyntaxKind.BlockComment: throw new Error(`Case "BlockComment" not implemented`); case SyntaxKind.TypeSpecScript: - throw new Error(`Case "CadlScript" not implemented`); + throw new Error(`Case "TypeSpecScript" not implemented`); case SyntaxKind.DecoratorExpression: obj = node as DecoratorExpressionNode; this.punctuation("@", false, false); @@ -997,7 +997,7 @@ export class ApiView { } } - private renderPunctuation(punc: string) { + private renderPunctuation(punctuation: string) { const last = this.tokens.pop()!; if (last?.Kind === ApiViewTokenKind.Whitespace) { // hacky workaround to ensure comma is after trailing bracket for expanded anonymous models @@ -1005,7 +1005,7 @@ export class ApiView { } else { this.tokens.push(last); } - this.punctuation(punc, false, true); + this.punctuation(punctuation, false, true); } resolveMissingTypeReferences() { diff --git a/tools/apiview/emitters/typespec-apiview/src/emitter.ts b/tools/apiview/emitters/typespec-apiview/src/emitter.ts index 370c3b0177e..b4e844c5353 100644 --- a/tools/apiview/emitters/typespec-apiview/src/emitter.ts +++ b/tools/apiview/emitters/typespec-apiview/src/emitter.ts @@ -45,7 +45,7 @@ export function resolveOptions(context: EmitContext): Res function resolveNamespaceString(namespace: Namespace): string | undefined { // FIXME: Fix this wonky workaround when getNamespaceString is fixed. const value = getNamespaceFullName(namespace); - return value == "" ? undefined : value; + return value === "" ? undefined : value; } // TODO: Up-level this logic? @@ -53,12 +53,12 @@ function resolveAllowedVersions(program: Program, service: Service): string[] { const allowed: string[] = []; const serviceVersion = service.version; const versions = getVersion(program, service.type)?.getVersions(); - if (serviceVersion != undefined && versions != undefined) { + if (serviceVersion !== undefined && versions !== undefined) { throw new Error("Cannot have serviceVersion with multi-API."); } - if (serviceVersion != undefined) { + if (serviceVersion !== undefined) { allowed.push(serviceVersion); - } else if (versions != undefined) { + } else if (versions !== undefined) { for (const item of versions) { allowed.push(item.name); } @@ -71,7 +71,7 @@ function resolveAllowedVersions(program: Program, service: Service): string[] { function resolveVersionValue(program: Program, namespace: Namespace, version: string): string { try { const versions = getVersion(program, namespace)!.getVersions(); - return versions.filter((item) => item.name == version).map((item) => item.value)[0]; + return versions.filter((item) => item.name === version).map((item) => item.value)[0]; } catch { return version; } @@ -82,8 +82,8 @@ function resolveProgramForVersion(program: Program, namespace: Namespace, versio return program; } const version = resolveVersionValue(program, namespace, versionKey); - const projections = buildVersionProjections(program, namespace).filter((item) => item.version == version); - if (projections.length == 0) { + const projections = buildVersionProjections(program, namespace).filter((item) => item.version === version); + if (projections.length === 0) { // non-multi-version scenario. Return original program. return program; } else { @@ -154,7 +154,7 @@ function createApiViewEmitter(program: Program, options: ResolvedApiViewEmitterO return; } // applies the default "apiview.json" filename if not provided and there's only a single service - if (services.length == 1) { + if (services.length === 1) { options.outputFile = options.outputFile ?? "apiview.json" } validateMultiServiceOptions(program, services, options); @@ -166,7 +166,7 @@ function createApiViewEmitter(program: Program, options: ResolvedApiViewEmitterO const serviceTitle = service.title ? service.title : namespaceString; const allowedVersions = resolveAllowedVersions(program, service); if (versionString) { - if (allowedVersions.filter((version) => version == versionString).length == 0) { + if (allowedVersions.filter((version) => version === versionString).length === 0) { reportDiagnostic(program, { code: "version-not-found", target: NoTarget, diff --git a/tools/apiview/emitters/typespec-apiview/src/lib.ts b/tools/apiview/emitters/typespec-apiview/src/lib.ts index ef8dfd3cd05..8c6b55f7951 100644 --- a/tools/apiview/emitters/typespec-apiview/src/lib.ts +++ b/tools/apiview/emitters/typespec-apiview/src/lib.ts @@ -1,4 +1,4 @@ -import { createCadlLibrary, JSONSchemaType, paramMessage } from "@typespec/compiler"; +import { createTypeSpecLibrary, JSONSchemaType, paramMessage } from "@typespec/compiler"; export interface ApiViewEmitterOptions { "output-file"?: string; @@ -20,7 +20,7 @@ const ApiViewEmitterOptionsSchema: JSONSchemaType = { }; -export const $lib = createCadlLibrary({ +export const $lib = createTypeSpecLibrary({ name: "@azure-tools/typespec-apiview", diagnostics: { "no-services-found": { diff --git a/tools/apiview/emitters/typespec-apiview/src/namespace-model.ts b/tools/apiview/emitters/typespec-apiview/src/namespace-model.ts index a7a141704f6..991916980d7 100644 --- a/tools/apiview/emitters/typespec-apiview/src/namespace-model.ts +++ b/tools/apiview/emitters/typespec-apiview/src/namespace-model.ts @@ -73,10 +73,10 @@ export class NamespaceModel { // Gather models and resources for (const [modelName, model] of ns.models) { - if (model.node != undefined) { + if (model.node !== undefined) { let isResource = false; for (const dec of model.decorators) { - if (dec.decorator.name == "$resource") { + if (dec.decorator.name === "$resource") { isResource = true; break; } @@ -156,7 +156,7 @@ function inNamespace(node: Node, program: Program, namespace: Namespace): boolea export function generateId(obj: BaseNode | NamespaceModel | undefined): string | undefined { let node; - if (obj == undefined) { + if (obj === undefined) { return undefined; } if (obj instanceof NamespaceModel) { @@ -181,14 +181,7 @@ export function generateId(obj: BaseNode | NamespaceModel | undefined): string | break; case SyntaxKind.EnumMember: node = obj as EnumMemberNode; - switch (node.id.kind) { - case SyntaxKind.Identifier: - name = node.id.sv; - break; - case SyntaxKind.StringLiteral: - name = node.id.value; - break; - } + name = node.id.sv; parentId = generateId(node.parent); break; case SyntaxKind.EnumSpreadMember: @@ -214,14 +207,7 @@ export function generateId(obj: BaseNode | NamespaceModel | undefined): string | break; case SyntaxKind.ModelProperty: node = obj as ModelPropertyNode; - switch (node.id.kind) { - case SyntaxKind.Identifier: - name = node.id.sv; - break; - case SyntaxKind.StringLiteral: - name = node.id.value; - break; - } + name = node.id.sv; parentId = generateId(node.parent); break; case SyntaxKind.ModelSpreadProperty: @@ -253,20 +239,13 @@ export function generateId(obj: BaseNode | NamespaceModel | undefined): string | break; case SyntaxKind.UnionVariant: node = obj as UnionVariantNode; - switch (node.id.kind) { - case SyntaxKind.Identifier: - name = node.id.sv; - break; - case SyntaxKind.StringLiteral: - name = node.id.value; - break; - } + name = node.id.sv; parentId = generateId(node.parent); break; default: return undefined; } - if (parentId != undefined) { + if (parentId !== undefined) { return `${parentId}.${name}`; } else { return name; diff --git a/tools/apiview/emitters/typespec-apiview/src/testing/index.ts b/tools/apiview/emitters/typespec-apiview/src/testing/index.ts index 0c79177717a..ccd07422c3c 100644 --- a/tools/apiview/emitters/typespec-apiview/src/testing/index.ts +++ b/tools/apiview/emitters/typespec-apiview/src/testing/index.ts @@ -1,8 +1,8 @@ import { resolvePath } from "@typespec/compiler"; -import { CadlTestLibrary } from "@typespec/compiler/testing"; +import { TypeSpecTestLibrary } from "@typespec/compiler/testing"; import { fileURLToPath } from "url"; -export const ApiViewTestLibrary: CadlTestLibrary = { +export const ApiViewTestLibrary: TypeSpecTestLibrary = { name: "@azure-tools/typespec-apiview", packageRoot: resolvePath(fileURLToPath(import.meta.url), "../../../../"), files: [ diff --git a/tools/apiview/emitters/typespec-apiview/src/version.ts b/tools/apiview/emitters/typespec-apiview/src/version.ts index 633c84a9da6..cf3eb161dca 100644 --- a/tools/apiview/emitters/typespec-apiview/src/version.ts +++ b/tools/apiview/emitters/typespec-apiview/src/version.ts @@ -1 +1 @@ -export const LIB_VERSION = "0.3.5"; +export const LIB_VERSION = "0.4.0"; diff --git a/tools/apiview/emitters/typespec-apiview/test/apiview-options.test.ts b/tools/apiview/emitters/typespec-apiview/test/apiview-options.test.ts index c8c7bef8da5..f59d01ec921 100644 --- a/tools/apiview/emitters/typespec-apiview/test/apiview-options.test.ts +++ b/tools/apiview/emitters/typespec-apiview/test/apiview-options.test.ts @@ -1,7 +1,5 @@ -import { Diagnostic, logDiagnostics, resolvePath } from "@typespec/compiler"; -import { expectDiagnosticEmpty, expectDiagnostics } from "@typespec/compiler/testing"; -import { strictEqual } from "assert"; -import { apiViewFor, apiViewText, compare, createApiViewTestRunner, diagnosticsFor } from "./test-host.js"; +import { expectDiagnostics } from "@typespec/compiler/testing"; +import { apiViewFor, apiViewText, compare, diagnosticsFor } from "./test-host.js"; describe("apiview-options: tests", () => { diff --git a/tools/apiview/emitters/typespec-apiview/test/apiview.test.ts b/tools/apiview/emitters/typespec-apiview/test/apiview.test.ts index 770af72c10b..beef6ab285d 100644 --- a/tools/apiview/emitters/typespec-apiview/test/apiview.test.ts +++ b/tools/apiview/emitters/typespec-apiview/test/apiview.test.ts @@ -1,4 +1,4 @@ -import assert, { fail, strictEqual } from "assert"; +import assert, { fail } from "assert"; import { ApiViewDocument, ApiViewTokenKind } from "../src/apiview.js"; import { apiViewFor, apiViewText, compare } from "./test-host.js"; @@ -11,17 +11,17 @@ describe("apiview: tests", () => { defIdsPerLine[index] = new Array(); for (const token of apiview.Tokens) { // ensure that there are no repeated definition IDs. - if (token.DefinitionId != undefined) { + if (token.DefinitionId !== undefined) { if (definitionIds.has(token.DefinitionId)) { fail(`Duplicate defintion ID ${token.DefinitionId}.`); } definitionIds.add(token.DefinitionId); } // Collect the definition IDs that exist on each line - if (token.DefinitionId != undefined) { + if (token.DefinitionId !== undefined) { defIdsPerLine[index].push(token.DefinitionId); } - if (token.Kind == ApiViewTokenKind.Newline) { + if (token.Kind === ApiViewTokenKind.Newline) { index++; defIdsPerLine[index] = new Array(); } @@ -29,7 +29,7 @@ describe("apiview: tests", () => { // ensure that each line has either 0 or 1 definition ID. for (let x = 0; x < defIdsPerLine.length; x++) { const row = defIdsPerLine[x]; - assert(row.length == 0 || row.length == 1, `Too many definition IDs (${row.length}) on line ${x}`); + assert(row.length === 0 || row.length === 1, `Too many definition IDs (${row.length}) on line ${x}`); } } diff --git a/tools/apiview/emitters/typespec-apiview/test/test-host.ts b/tools/apiview/emitters/typespec-apiview/test/test-host.ts index d19f7536231..946814be3d9 100644 --- a/tools/apiview/emitters/typespec-apiview/test/test-host.ts +++ b/tools/apiview/emitters/typespec-apiview/test/test-host.ts @@ -1,5 +1,6 @@ import { createTestHost, createTestWrapper } from "@typespec/compiler/testing"; import { RestTestLibrary } from "@typespec/rest/testing"; +import { HttpTestLibrary } from "@typespec/http/testing"; import { VersioningTestLibrary } from "@typespec/versioning/testing"; import { AzureCoreTestLibrary } from "@azure-tools/typespec-azure-core/testing"; import { ApiViewTestLibrary } from "../src/testing/index.js"; @@ -11,7 +12,7 @@ import { strictEqual } from "assert"; export async function createApiViewTestHost() { return createTestHost({ - libraries: [ApiViewTestLibrary, RestTestLibrary, VersioningTestLibrary, AzureCoreTestLibrary], + libraries: [ApiViewTestLibrary, RestTestLibrary, HttpTestLibrary, VersioningTestLibrary, AzureCoreTestLibrary], }); } @@ -67,7 +68,7 @@ export function apiViewText(apiview: ApiViewDocument): string[] { vals.push("\n"); break; default: - if (token.Value != undefined) { + if (token.Value !== undefined) { vals.push(token.Value); } break; @@ -90,7 +91,7 @@ function trimLines(lines: string[]): string[] { const trimmed: string[] = []; const indent = getIndex(lines); for (const line of lines) { - if (line.trim() == '') { + if (line.trim() === '') { // skip blank lines continue; } else {