Skip to content
Closed
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ The catalog is generated from the same schema and SDK output as each release. Co

### Build-time source analysis

`@sentry/api/source-analysis` follows references in supplied TypeScript source to discover calls to catalog operations. Install TypeScript only when using this optional build tool; the analyzer is tested with TypeScript 5.9. Its optional peer uses a wildcard so it does not constrain the compiler used by applications that only import the client.
`@sentry/api/source-analysis` follows references in supplied TypeScript source to discover calls to catalog operations. It parses with TypeScript 6's compiler API through `@typescript/typescript6`, since TypeScript 7 no longer ships that API. Install it only when using this optional build tool; the separate package name means it works alongside whichever TypeScript version the project compiles with, including 7. With npm or Bun, its aliased TypeScript 6 dependency is hoisted and its `tsc` bin can replace the project's own in `node_modules/.bin`, so run the project's compiler by path there; pnpm keeps it nested.

```bash
npm install --save-dev @sentry/api typescript@^5.9
npm install --save-dev @sentry/api @typescript/typescript6
```

```ts
Expand Down
6 changes: 4 additions & 2 deletions build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,7 @@ execSync('bun build src/valibot.ts --outdir dist --external valibot', { stdio: "
execSync('bun build src/zod.ts --outdir dist --external zod', { stdio: "inherit" });
execSync("bun build src/browser.ts --outdir dist", { stdio: "inherit" });
execSync("bun build src/operations.ts --outdir dist", { stdio: "inherit" });
execSync("bun build src/source-analysis.ts --outdir dist --external typescript", { stdio: "inherit" });
execSync("tsc --emitDeclarationOnly", { stdio: "inherit" });
execSync("bun build src/source-analysis.ts --outdir dist --external @typescript/typescript6", { stdio: "inherit" });
// @typescript/typescript6 depends on TypeScript 6 under an alias that also
// installs a `tsc` bin, so run this repo's own compiler by path.
execSync("node node_modules/typescript/bin/tsc --emitDeclarationOnly", { stdio: "inherit" });
9 changes: 7 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion lib/source-analysis.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/** Build-time analysis of API usage in consumer-supplied TypeScript source. */

import { dirname, posix } from "node:path";
import ts from "typescript";
// TypeScript 7 no longer ships the JavaScript compiler API, so load the
// TypeScript 6 one under its own name instead of the consumer's `typescript`.
import ts from "@typescript/typescript6";
import type { ApiOperation } from "./operation-types.js";

/** Identity supplied by the generated SDK operation catalog. */
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"build": "node build.mjs",
"test": "bun test",
"test:node": "node --test test/node-cancellation.mjs",
"typecheck": "tsc -p tsconfig.test.json"
"typecheck": "node node_modules/typescript/bin/tsc -p tsconfig.test.json"
},
"exports": {
".": {
Expand Down Expand Up @@ -60,12 +60,12 @@
"url": "https://github.com/getsentry/sentry-api-schema/issues"
},
"peerDependencies": {
"typescript": "*",
"@typescript/typescript6": "^6.0.2",
"valibot": "*",
"zod": "^3.24.0"
},
"peerDependenciesMeta": {
"typescript": {
"@typescript/typescript6": {
"optional": true
},
"valibot": {
Expand All @@ -79,6 +79,7 @@
"@hey-api/openapi-ts": "0.91.1",
"@types/bun": "^1.3.13",
"@types/node": "^22",
"@typescript/typescript6": "^6.0.2",
"typescript": "^5.9.3",
"valibot": "^1.4.2",
"zod": "^3.24.0"
Expand Down
17 changes: 11 additions & 6 deletions test/package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ const readBundle = (name: string) =>
describe("package entry points", () => {
test("keeps validator and source-analysis peers optional", () => {
expect(packageJson.peerDependencies).toEqual({
typescript: "*",
"@typescript/typescript6": "^6.0.2",
valibot: "*",
zod: "^3.24.0",
});
expect(packageJson.peerDependenciesMeta).toEqual({
typescript: { optional: true },
"@typescript/typescript6": { optional: true },
valibot: { optional: true },
zod: { optional: true },
});
});

test("keeps the root bundle independent from optional tools and validators", async () => {
const root = await readBundle("index");
expect(root).not.toMatch(/from ["']typescript["']/);
expect(root).not.toMatch(/from ["'](?:typescript|@typescript\/typescript6)["']/);
expect(root).not.toMatch(/from ["']valibot["']/);
expect(root).not.toMatch(/from ["']zod["']/);
});
Expand All @@ -40,8 +40,8 @@ describe("package entry points", () => {
expect(valibot).not.toMatch(/from ["']zod["']/);
expect(zod).toMatch(/from ["']zod["']/);
expect(zod).not.toMatch(/from ["']valibot["']/);
expect(analysis).toMatch(/from ["']typescript["']/);
expect(analysis).not.toMatch(/from ["'](?:valibot|zod)["']/);
expect(analysis).toMatch(/from ["']@typescript\/typescript6["']/);
expect(analysis).not.toMatch(/from ["'](?:typescript|valibot|zod)["']/);
});

test("packs isolated runtime entries, pagination and build-time analysis", () => {
Expand Down Expand Up @@ -138,7 +138,12 @@ describe("package entry points", () => {
}));
execFileSync("node", [join(root, "node_modules", "typescript", "bin", "tsc"), "-p", directory]);

symlinkSync(join(root, "node_modules", "typescript"), join(directory, "node_modules", "typescript"), "dir");
mkdirSync(join(directory, "node_modules", "@typescript"), { recursive: true });
symlinkSync(
join(root, "node_modules", "@typescript", "typescript6"),
join(directory, "node_modules", "@typescript", "typescript6"),
"dir",
);
writeFileSync(join(directory, "analysis.mjs"), `
import assert from "node:assert/strict";
import { operations } from "@sentry/api/operations";
Expand Down
Loading