UNPKG

@azure-tools/typespec-apiview

Version:

Library for emitting APIView token files from TypeSpec

98 lines 4.03 kB
import { emitFile, getNamespaceFullName, listServices, NoTarget, resolvePath, } from "@typespec/compiler"; import path from "path"; import { ApiView } from "./apiview.js"; import { reportDiagnostic } from "./lib.js"; export async function $onEmit(context) { const options = resolveOptions(context); const emitter = createApiViewEmitter(context.program, options); await emitter.emitApiView(); } export function resolveOptions(context) { var _a; const resolvedOptions = { ...context.options }; return { emitterOutputDir: context.emitterOutputDir, outputFile: resolvedOptions["output-file"], service: resolvedOptions["service"], includeGlobalNamespace: (_a = resolvedOptions["include-global-namespace"]) !== null && _a !== void 0 ? _a : false, }; } function resolveNamespaceString(namespace) { // FIXME: Fix this wonky workaround when getNamespaceString is fixed. const value = getNamespaceFullName(namespace); return value === "" ? undefined : value; } /** * Ensures that single-value options are not used in multi-service specs unless the * `--service` option is specified. Single-service specs need not pass this option. */ function validateMultiServiceOptions(program, services, options) { for (const [name, val] of [["output-file", options.outputFile]]) { if (val && !options.service && services.length > 1) { reportDiagnostic(program, { code: "invalid-option", target: NoTarget, format: { name: name } }); } } } /** * If the `--service` option is provided, ensures the service exists and returns the filtered list. */ function applyServiceFilter(program, services, options) { if (!options.service) { return services; } const filtered = services.filter((x) => x.title === options.service); if (!filtered.length) { reportDiagnostic(program, { code: "invalid-service", target: NoTarget, format: { value: options.service } }); } return filtered; } function createApiViewEmitter(program, options) { return { emitApiView }; async function emitApiView() { var _a, _b, _c; let services = listServices(program); if (!services.length) { reportDiagnostic(program, { code: "no-services-found", target: NoTarget }); return; } // applies the default "apiview.json" filename if not provided and there's only a single service if (services.length === 1) { options.outputFile = (_a = options.outputFile) !== null && _a !== void 0 ? _a : "apiview.json"; } validateMultiServiceOptions(program, services, options); services = applyServiceFilter(program, services, options); for (const service of services) { const namespaceString = (_b = resolveNamespaceString(service.type)) !== null && _b !== void 0 ? _b : "Unknown"; const serviceTitle = service.title ? service.title : namespaceString; const apiview = new ApiView(serviceTitle, namespaceString, options.includeGlobalNamespace); apiview.compile(program); apiview.resolveMissingTypeReferences(); if (!program.compilerOptions.noEmit && !program.hasError()) { const outputFolder = path.dirname(options.emitterOutputDir); await program.host.mkdirp(outputFolder); const outputFile = (_c = options.outputFile) !== null && _c !== void 0 ? _c : `${namespaceString}-apiview.json`; const outputPath = resolvePath(outputFolder, outputFile); await emitFile(program, { path: outputPath, content: JSON.stringify(apiview.asCodeFile()) + "\n" }); } } } } //# sourceMappingURL=emitter.js.map