Skip to content

Commit

Permalink
TSPD exports support (#4700)
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheeguerin authored Oct 11, 2024
1 parent c381624 commit eeee93e
Show file tree
Hide file tree
Showing 17 changed files with 105 additions and 11 deletions.
20 changes: 20 additions & 0 deletions .chronus/changes/tspd-exports-support-2024-9-11-17-14-36.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: fix
packages:
- "@typespec/compiler"
- "@typespec/events"
- "@typespec/http"
- "@typespec/json-schema"
- "@typespec/library-linter"
- "@typespec/openapi"
- "@typespec/openapi3"
- "@typespec/protobuf"
- "@typespec/rest"
- "@typespec/sse"
- "@typespec/streams"
- "@typespec/versioning"
- "@typespec/xml"
---

TSPD exports support
1 change: 1 addition & 0 deletions packages/compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"tspMain": "lib/std/main.tsp",
"exports": {
".": {
"typespec": "./lib/std/main.tsp",
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
Expand Down
5 changes: 4 additions & 1 deletion packages/events/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
"main": "dist/src/index.js",
"tspMain": "lib/main.tsp",
"exports": {
".": "./dist/src/index.js",
".": {
"typespec": "./lib/main.tsp",
"default": "./dist/src/index.js"
},
"./testing": "./dist/src/testing/index.js",
"./experimental": {
"types": "./dist/src/experimental/index.d.ts",
Expand Down
1 change: 1 addition & 0 deletions packages/http/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"tspMain": "lib/http.tsp",
"exports": {
".": {
"typespec": "./lib/http.tsp",
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
Expand Down
1 change: 1 addition & 0 deletions packages/json-schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"main": "dist/src/index.js",
"exports": {
".": {
"typespec": "./lib/main.tsp",
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
Expand Down
1 change: 1 addition & 0 deletions packages/library-linter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"main": "dist/src/index.js",
"exports": {
".": {
"typespec": "./dist/src/index.js",
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
Expand Down
1 change: 1 addition & 0 deletions packages/openapi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"tspMain": "lib/main.tsp",
"exports": {
".": {
"typespec": "./lib/main.tsp",
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
Expand Down
1 change: 1 addition & 0 deletions packages/openapi3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"tspMain": "lib/main.tsp",
"exports": {
".": {
"typespec": "./lib/main.tsp",
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
Expand Down
6 changes: 5 additions & 1 deletion packages/protobuf/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
],
"main": "dist/src/index.js",
"exports": {
".": "./dist/src/index.js",
".": {
"typespec": "./lib/proto.tsp",
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
"./testing": "./dist/src/testing/index.js"
},
"type": "module",
Expand Down
1 change: 1 addition & 0 deletions packages/rest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"tspMain": "lib/rest.tsp",
"exports": {
".": {
"typespec": "./lib/rest.tsp",
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
Expand Down
5 changes: 4 additions & 1 deletion packages/spec-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
"main": "dist/index.js",
"tspMain": "lib/lib.tsp",
"exports": {
".": "./dist/src/index.js"
".": {
"typespec": "./lib/lib.tsp",
"default": "./dist/src/index.js"
}
},
"engines": {
"node": ">=16.0.0"
Expand Down
5 changes: 4 additions & 1 deletion packages/sse/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
"main": "dist/src/index.js",
"tspMain": "lib/main.tsp",
"exports": {
".": "./dist/src/index.js",
".": {
"typespec": "./lib/main.tsp",
"default": "./dist/src/index.js"
},
"./testing": "./dist/src/testing/index.js"
},
"engines": {
Expand Down
1 change: 1 addition & 0 deletions packages/streams/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"tspMain": "lib/main.tsp",
"exports": {
".": {
"typespec": "./lib/main.tsp",
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
Expand Down
52 changes: 47 additions & 5 deletions packages/tspd/src/gen-extern-signatures/gen-extern-signatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,74 @@ import {
CompilerHost,
Decorator,
Diagnostic,
type PackageJson,
Program,
type SourceLocation,
compile,
createDiagnosticCollector,
createSourceFile,
getLocationContext,
getTypeName,
joinPaths,
navigateProgram,
resolvePath,
type PackageJson,
} from "@typespec/compiler";
import prettier from "prettier";
import { createDiagnostic } from "../ref-doc/lib.js";
import { generateSignatureTests, generateSignatures } from "./decorators-signatures.js";
import { DecoratorSignature } from "./types.js";

function createSourceLocation(path: string): SourceLocation {
return { file: createSourceFile("", path), pos: 0, end: 0 };
}
export async function generateExternSignatures(
host: CompilerHost,
libraryPath: string,
): Promise<readonly Diagnostic[]> {
const diagnostics = createDiagnosticCollector();
const pkgJson = await readPackageJson(host, libraryPath);
if (!pkgJson.tspMain) {
throw new Error("Must have a tspMain with decorator declaration.");
if (!pkgJson.exports) {
return [
createDiagnostic({
code: "exports-missing",
target: createSourceLocation(resolvePath(libraryPath, "package.json")),
}),
];
}

const exportsMap: Record<string, string> = {};
for (const [key, value] of Object.entries(pkgJson.exports)) {
if (typeof value === "object" && "typespec" in value && typeof value.typespec === "string") {
exportsMap[key] = resolvePath(libraryPath, value.typespec);
}
}

const exports = Object.values(exportsMap);
if (exports.length > 0) {
diagnostics.pipe(await generateExternSignatureForExports(host, libraryPath, pkgJson, exports));
} else {
diagnostics.add(
createDiagnostic({
code: "exports-missing",
messageId: "missingCondition",
target: createSourceLocation(resolvePath(libraryPath, "package.json")),
}),
);
}

const main = resolvePath(libraryPath, pkgJson.tspMain);
return diagnostics.diagnostics;
}

export async function generateExternSignatureForExports(
host: CompilerHost,
libraryPath: string,
pkgJson: PackageJson,
exports: string[],
): Promise<[undefined, readonly Diagnostic[]]> {
const [main, ...additionalImports] = exports;
const diagnostics = createDiagnosticCollector();
const program = await compile(host, main, {
additionalImports,
parseOptions: { comments: true, docs: true },
});
const prettierConfig = await prettier.resolveConfig(libraryPath);
Expand All @@ -42,7 +84,7 @@ export async function generateExternSignatures(
for (const [name, content] of Object.entries(files)) {
await host.writeFile(resolvePath(outDir, name), content);
}
return diagnostics.diagnostics;
return [undefined, diagnostics.diagnostics];
}

async function readPackageJson(host: CompilerHost, libraryPath: string): Promise<PackageJson> {
Expand Down
9 changes: 8 additions & 1 deletion packages/tspd/src/ref-doc/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ import { createTypeSpecLibrary, paramMessage } from "@typespec/compiler";
export const libDef = {
name: "@typespec/tspd",
diagnostics: {
"exports-missing": {
severity: "error",
messages: {
default: `exports field is missing in package.json`,
missingCondition: `exports field is missing one export with the typespec condition`,
},
},
"documentation-missing": {
severity: "warning",
messages: {
Expand All @@ -22,6 +29,6 @@ export const libDef = {
} as const;

export const $lib = createTypeSpecLibrary(libDef);
export const { reportDiagnostic, createStateSymbol } = $lib;
export const { reportDiagnostic, createStateSymbol, createDiagnostic } = $lib;

export type RefDocLibrary = typeof $lib;
1 change: 1 addition & 0 deletions packages/versioning/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"tspMain": "lib/main.tsp",
"exports": {
".": {
"typespec": "./lib/main.tsp",
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js"
},
Expand Down
5 changes: 4 additions & 1 deletion packages/xml/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
"main": "dist/src/index.js",
"tspMain": "lib/main.tsp",
"exports": {
".": "./dist/src/index.js",
".": {
"typespec": "./lib/main.tsp",
"default": "./dist/src/index.js"
},
"./testing": "./dist/src/testing/index.js"
},
"engines": {
Expand Down

0 comments on commit eeee93e

Please sign in to comment.