From c48f61620c1e243f2437cfe601d24e83f6ba37da Mon Sep 17 00:00:00 2001 From: Elliot DeNolf Date: Thu, 16 Oct 2025 16:31:09 -0400 Subject: [PATCH 1/4] tools: create ts-plugin-inherit-doc to be able to inherit jsdoc from parent type --- .vscode/settings.json | 1 + package.json | 1 + pnpm-lock.yaml | 47 ++++++++++++++----------------------------- tsconfig.json | 5 +++++ 4 files changed, 22 insertions(+), 32 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 76de0a81ded..a6e68687d9b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,6 +15,7 @@ { "rule": "object-shorthand", "severity": "off", "fixable": true } ], "typescript.tsdk": "node_modules/typescript/lib", + "typescript.tsserver.pluginPaths": ["${workspaceFolder}/tools/ts-plugin-inherit-doc"], // Load .git-blame-ignore-revs file "gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".git-blame-ignore-revs"], "jestrunner.jestCommand": "pnpm exec cross-env NODE_OPTIONS=\"--no-deprecation\" node 'node_modules/jest/bin/jest.js'", diff --git a/package.json b/package.json index be2ce9d023a..8c5b03fd2f5 100644 --- a/package.json +++ b/package.json @@ -140,6 +140,7 @@ "@payloadcms/eslint-config": "workspace:*", "@payloadcms/eslint-plugin": "workspace:*", "@payloadcms/live-preview-react": "workspace:*", + "@payloadcms/ts-plugin-inherit-doc": "workspace:*", "@playwright/test": "1.54.1", "@sentry/nextjs": "^8.33.1", "@sentry/node": "^8.33.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95a4f18c84d..4c7c83103a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,6 +39,9 @@ importers: '@payloadcms/live-preview-react': specifier: workspace:* version: link:packages/live-preview-react + '@payloadcms/ts-plugin-inherit-doc': + specifier: workspace:* + version: link:tools/ts-plugin-inherit-doc '@playwright/test': specifier: 1.54.1 version: 1.54.1 @@ -1819,7 +1822,7 @@ importers: version: 16.9.0 next: specifier: 15.4.4 - version: 15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + version: 15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) payload: specifier: workspace:* version: link:../../packages/payload @@ -1961,7 +1964,7 @@ importers: version: 8.6.0(react@19.1.1) geist: specifier: ^1.3.0 - version: 1.4.2(next@15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)) + version: 1.4.2(next@15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)) graphql: specifier: ^16.8.1 version: 16.9.0 @@ -1973,7 +1976,7 @@ importers: version: 0.477.0(react@19.1.1) next: specifier: ^15.5.4 - version: 15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + version: 15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) next-themes: specifier: 0.4.6 version: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -2623,6 +2626,12 @@ importers: specifier: workspace:* version: link:../../packages/translations + tools/ts-plugin-inherit-doc: + dependencies: + typescript: + specifier: 5.7.3 + version: 5.7.3 + packages: '@alloc/quick-lru@5.2.0': @@ -25112,9 +25121,9 @@ snapshots: dependencies: next: 15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) - geist@1.4.2(next@15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)): + geist@1.4.2(next@15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)): dependencies: - next: 15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + next: 15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) gel@2.0.1: dependencies: @@ -27099,32 +27108,6 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4): - dependencies: - '@next/env': 15.4.4 - '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001720 - postcss: 8.4.31 - react: 19.1.1 - react-dom: 19.1.1(react@19.1.1) - styled-jsx: 5.1.6(@babel/core@7.27.4)(babel-plugin-macros@3.1.0)(react@19.1.1) - optionalDependencies: - '@next/swc-darwin-arm64': 15.4.4 - '@next/swc-darwin-x64': 15.4.4 - '@next/swc-linux-arm64-gnu': 15.4.4 - '@next/swc-linux-arm64-musl': 15.4.4 - '@next/swc-linux-x64-gnu': 15.4.4 - '@next/swc-linux-x64-musl': 15.4.4 - '@next/swc-win32-arm64-msvc': 15.4.4 - '@next/swc-win32-x64-msvc': 15.4.4 - '@opentelemetry/api': 1.9.0 - '@playwright/test': 1.54.1 - sass: 1.77.4 - sharp: 0.34.3 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4): dependencies: '@next/env': 15.4.4 @@ -27152,7 +27135,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4): + next@15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4): dependencies: '@next/env': 15.5.4 '@swc/helpers': 0.5.15 diff --git a/tsconfig.json b/tsconfig.json index 58c299a78ee..e303c9fff82 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,6 +4,11 @@ "composite": false, "noEmit": true, "baseUrl": ".", + "plugins": [ + { + "name": "@payloadcms/ts-plugin-inherit-doc" + } + ] }, "references": [ { From 1e9f9afde7bfd192bf632067bffe927beda41012 Mon Sep 17 00:00:00 2001 From: Elliot DeNolf Date: Thu, 16 Oct 2025 16:35:33 -0400 Subject: [PATCH 2/4] chore: missing actual plugin --- tools/ts-plugin-inherit-doc/README.md | 48 ++++++ tools/ts-plugin-inherit-doc/package.json | 19 +++ tools/ts-plugin-inherit-doc/src/index.ts | 173 ++++++++++++++++++++++ tools/ts-plugin-inherit-doc/tsconfig.json | 18 +++ 4 files changed, 258 insertions(+) create mode 100644 tools/ts-plugin-inherit-doc/README.md create mode 100644 tools/ts-plugin-inherit-doc/package.json create mode 100644 tools/ts-plugin-inherit-doc/src/index.ts create mode 100644 tools/ts-plugin-inherit-doc/tsconfig.json diff --git a/tools/ts-plugin-inherit-doc/README.md b/tools/ts-plugin-inherit-doc/README.md new file mode 100644 index 00000000000..d0b1b7a1775 --- /dev/null +++ b/tools/ts-plugin-inherit-doc/README.md @@ -0,0 +1,48 @@ +# TypeScript JSDoc Inheritance Plugin + +A TypeScript Language Service Plugin that enables documentation inheritance via `@inheritDoc` tag. + +## Usage + +1. Build the plugin: + +```bash +cd tools/ts-plugin-inherit-doc +pnpm install +pnpm build +``` + +2. Add to your `tsconfig.json`: + +```json +{ + "compilerOptions": { + "plugins": [{ "name": "@payloadcms/ts-plugin-inherit-doc" }] + } +} +``` + +3. Use in your code: + +```javascript +/** + * Represents a user in the system + * @typedef {Object} User + * @property {string} id - Unique identifier + * @property {string} name - User's full name + */ + +/** + * @typedef {Object} UserResponse + * @property {User} user - @inheritDoc User + * @property {string} token - Auth token + */ +``` + +When you hover over `user` property, you'll see the inherited documentation from `User`. + +## Notes + +- The plugin rebuilds the documentation cache on each hover (optimization needed for production) +- Only works with `@typedef` JSDoc declarations +- VSCode requires TypeScript workspace version to use plugins diff --git a/tools/ts-plugin-inherit-doc/package.json b/tools/ts-plugin-inherit-doc/package.json new file mode 100644 index 00000000000..d2a68624c15 --- /dev/null +++ b/tools/ts-plugin-inherit-doc/package.json @@ -0,0 +1,19 @@ +{ + "name": "@payloadcms/ts-plugin-inherit-doc", + "version": "1.0.0", + "description": "TypeScript Language Service Plugin for JSDoc documentation inheritance", + "keywords": [ + "typescript", + "plugin", + "jsdoc" + ], + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc", + "watch": "tsc --watch" + }, + "dependencies": { + "typescript": "^5.7.2" + } +} diff --git a/tools/ts-plugin-inherit-doc/src/index.ts b/tools/ts-plugin-inherit-doc/src/index.ts new file mode 100644 index 00000000000..25f00c44ed0 --- /dev/null +++ b/tools/ts-plugin-inherit-doc/src/index.ts @@ -0,0 +1,173 @@ +import type * as ts from 'typescript/lib/tsserverlibrary' + +interface DocCache { + [typeName: string]: { + documentation: string + properties: Map + } +} + +function init(modules: { typescript: typeof import('typescript/lib/tsserverlibrary') }) { + const ts = modules.typescript + let docCache: DocCache = {} + + function create(info: ts.server.PluginCreateInfo) { + const proxy: ts.LanguageService = Object.create(null) + const oldLS = info.languageService + const program = oldLS.getProgram() + + // Build documentation cache + function buildDocCache() { + if (!program) { + return + } + + docCache = {} + const checker = program.getTypeChecker() + const sourceFiles = program.getSourceFiles().filter((sf) => !sf.isDeclarationFile) + + for (const sourceFile of sourceFiles) { + ts.forEachChild(sourceFile, visitNode) + } + + function visitNode(node: ts.Node) { + let typeName: string | undefined + let jsDoc: readonly ts.JSDoc[] | undefined + + // Handle type alias declarations + if (ts.isTypeAliasDeclaration(node)) { + typeName = node.name.text + jsDoc = (node as any).jsDoc + } + // Handle interface declarations + else if (ts.isInterfaceDeclaration(node)) { + typeName = node.name.text + jsDoc = (node as any).jsDoc + } + // Handle @typedef JSDoc declarations + else if (ts.isVariableStatement(node) || ts.isExpressionStatement(node)) { + const jsDocTags = ts.getJSDocTags(node) + const typedefTag = jsDocTags.find((tag) => tag.tagName.text === 'typedef') + if (typedefTag && ts.isJSDocTypedefTag(typedefTag)) { + typeName = typedefTag.name?.getText() + jsDoc = [node as any] + .filter((n: any) => n.jsDoc) + .flatMap((n: any) => n.jsDoc) as ts.JSDoc[] + } + } + + if (typeName && jsDoc && jsDoc.length > 0) { + const fullComment = ts.getTextOfJSDocComment(jsDoc[0].comment) + const properties = new Map() + + // Extract property documentation from JSDoc tags + for (const doc of jsDoc) { + if (doc.tags) { + for (const tag of doc.tags) { + if (ts.isJSDocPropertyTag(tag)) { + const propName = tag.name.getText() + const propDoc = ts.getTextOfJSDocComment(tag.comment) || '' + properties.set(propName, propDoc) + } + } + } + } + + docCache[typeName] = { + documentation: fullComment || '', + properties, + } + } + + ts.forEachChild(node, visitNode) + } + } + + // Parse @inheritDoc tag from JSDoc comment + function parseInheritDoc(comment: string): null | string { + const match = comment.match(/@inheritDoc\s+(\w+)/) + return match ? match[1] : null + } + + // Merge documentation from referenced type + function mergeDocumentation( + original: string | ts.SymbolDisplayPart[] | undefined, + inheritFrom: string, + ): ts.SymbolDisplayPart[] { + if (!docCache[inheritFrom]) { + const result: ts.SymbolDisplayPart[] = + typeof original === 'string' ? [{ text: original, kind: 'text' }] : original || [] + result.push({ + text: `\n\n[DEBUG: Type "${inheritFrom}" not found. Available: ${Object.keys(docCache).join(', ')}]`, + kind: 'text', + }) + return result + } + + const inherited = docCache[inheritFrom] + const result: ts.SymbolDisplayPart[] = [] + + // Add inherited documentation + if (inherited.documentation) { + result.push({ text: inherited.documentation, kind: 'text' }) + } + + // Add inherited properties + if (inherited.properties.size > 0) { + result.push({ text: '\n\nProperties:\n', kind: 'text' }) + inherited.properties.forEach((doc, name) => { + result.push({ text: `• ${name}: ${doc}\n`, kind: 'text' }) + }) + } + + return result + } + + // Intercept hover requests + proxy.getQuickInfoAtPosition = (fileName: string, position: number) => { + const quickInfo = oldLS.getQuickInfoAtPosition(fileName, position) + if (!quickInfo) { + return quickInfo + } + + // Rebuild cache on each request (in production, you'd want smarter invalidation) + buildDocCache() + + // Check if documentation contains @inheritDoc + const docParts = quickInfo.documentation || [] + const docText = docParts.map((part) => part.text).join('') + const inheritFrom = parseInheritDoc(docText) + + // Add debug marker to ALL hovers to verify plugin is running + const debugMarker: ts.SymbolDisplayPart[] = [{ text: '\n\n[Plugin Active ✓]', kind: 'text' }] + + if (inheritFrom) { + return { + ...quickInfo, + documentation: [ + ...mergeDocumentation(quickInfo.documentation, inheritFrom), + ...debugMarker, + ], + } + } + + return { + ...quickInfo, + documentation: [...docParts, ...debugMarker], + } + } + + // Proxy all other methods + return new Proxy(oldLS, { + get: (target, prop) => { + return prop in proxy + ? proxy[prop as keyof ts.LanguageService] + : target[prop as keyof ts.LanguageService] + }, + }) + } + + return { create } +} + +export = init diff --git a/tools/ts-plugin-inherit-doc/tsconfig.json b/tools/ts-plugin-inherit-doc/tsconfig.json new file mode 100644 index 00000000000..eb56c8eb160 --- /dev/null +++ b/tools/ts-plugin-inherit-doc/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": ["ES2020"], + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} From 4ed3f68e5c3e3e214be4699ec6f386cb6fec08e9 Mon Sep 17 00:00:00 2001 From: Elliot DeNolf Date: Thu, 16 Oct 2025 16:49:30 -0400 Subject: [PATCH 3/4] test: add unit tests --- pnpm-lock.yaml | 299 ++++++++++++++++-- tools/ts-plugin-inherit-doc/jest.config.js | 7 + tools/ts-plugin-inherit-doc/package.json | 7 + tools/ts-plugin-inherit-doc/src/index.test.ts | 156 +++++++++ tools/ts-plugin-inherit-doc/src/index.ts | 126 +++++++- 5 files changed, 557 insertions(+), 38 deletions(-) create mode 100644 tools/ts-plugin-inherit-doc/jest.config.js create mode 100644 tools/ts-plugin-inherit-doc/src/index.test.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c7c83103a1..88fab4f20ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,7 +47,7 @@ importers: version: 1.54.1 '@sentry/nextjs': specifier: ^8.33.1 - version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(react@19.1.1)(webpack@5.96.1(@swc/core@1.11.29)) + version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(react@19.1.1)(webpack@5.96.1(@swc/core@1.11.29)) '@sentry/node': specifier: ^8.33.1 version: 8.37.1 @@ -137,7 +137,7 @@ importers: version: 10.1.4(@aws-sdk/credential-providers@3.687.0(@aws-sdk/client-sso-oidc@3.687.0(@aws-sdk/client-sts@3.687.0)))(socks@2.8.3) next: specifier: 15.4.4 - version: 15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + version: 15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) open: specifier: ^10.1.0 version: 10.1.0 @@ -1170,7 +1170,7 @@ importers: dependencies: next: specifier: ^15.2.3 - version: 15.2.3(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + version: 15.2.3(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) devDependencies: '@payloadcms/eslint-config': specifier: workspace:* @@ -1235,7 +1235,7 @@ importers: dependencies: '@sentry/nextjs': specifier: ^8.33.1 - version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(react@19.1.1)(webpack@5.96.1(@swc/core@1.11.29)) + version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(react@19.1.1)(webpack@5.96.1(@swc/core@1.11.29)) '@sentry/types': specifier: ^8.33.1 version: 8.37.1 @@ -1623,7 +1623,7 @@ importers: version: link:../plugin-cloud-storage uploadthing: specifier: 7.3.0 - version: 7.3.0(express@5.0.1)(next@15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(tailwindcss@4.1.13) + version: 7.3.0(express@5.0.1)(next@15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(tailwindcss@4.1.13) devDependencies: payload: specifier: workspace:* @@ -1822,7 +1822,7 @@ importers: version: 16.9.0 next: specifier: 15.4.4 - version: 15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + version: 15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) payload: specifier: workspace:* version: link:../../packages/payload @@ -2166,7 +2166,7 @@ importers: version: 16.4.7 geist: specifier: ^1.3.0 - version: 1.4.2(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)) + version: 1.4.2(next@15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)) graphql: specifier: ^16.8.1 version: 16.9.0 @@ -2175,10 +2175,10 @@ importers: version: 0.378.0(react@19.1.1) next: specifier: 15.4.4 - version: 15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + version: 15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) next-sitemap: specifier: ^4.2.3 - version: 4.2.3(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)) + version: 4.2.3(next@15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)) payload: specifier: workspace:* version: link:../../packages/payload @@ -2410,7 +2410,7 @@ importers: version: link:../packages/ui '@sentry/nextjs': specifier: ^8.33.1 - version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(react@19.1.1)(webpack@5.96.1(@swc/core@1.11.29)) + version: 8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(react@19.1.1)(webpack@5.96.1(@swc/core@1.11.29)) '@sentry/react': specifier: ^7.77.0 version: 7.119.2(react@19.1.1) @@ -2482,7 +2482,7 @@ importers: version: 8.15.1(@aws-sdk/credential-providers@3.687.0(@aws-sdk/client-sso-oidc@3.687.0(@aws-sdk/client-sts@3.687.0)))(socks@2.8.3) next: specifier: 15.4.4 - version: 15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + version: 15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) nodemailer: specifier: 7.0.9 version: 7.0.9 @@ -2631,6 +2631,19 @@ importers: typescript: specifier: 5.7.3 version: 5.7.3 + devDependencies: + '@types/jest': + specifier: ^29.5.12 + version: 29.5.12 + '@types/node': + specifier: ^22.15.30 + version: 22.15.30 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@22.15.30)(babel-plugin-macros@3.1.0) + ts-jest: + specifier: ^29.2.0 + version: 29.4.5(@babel/core@7.27.4)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.4))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.15.30)(babel-plugin-macros@3.1.0))(typescript@5.7.3) packages: @@ -8865,6 +8878,10 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} @@ -10657,6 +10674,11 @@ packages: resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} engines: {node: '>=10'} + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} @@ -11600,6 +11622,9 @@ packages: lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -11670,6 +11695,9 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -13372,6 +13400,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + send@1.2.0: resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} engines: {node: '>= 18'} @@ -14092,6 +14125,33 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-jest@29.4.5: + resolution: {integrity: sha512-HO3GyiWn2qvTQA4kTgjDcXiMwYQt68a1Y8+JuLRVpdIzm+UOLSHgl/XqR4c6nzJkq5rOkjc02O2I7P7l/Yof0Q==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 || ^30.0.0 + '@jest/types': ^29.0.0 || ^30.0.0 + babel-jest: ^29.0.0 || ^30.0.0 + esbuild: '*' + jest: ^29.0.0 || ^30.0.0 + jest-util: ^29.0.0 || ^30.0.0 + typescript: 5.7.3 + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + jest-util: + optional: true + ts-pattern@5.6.2: resolution: {integrity: sha512-d4IxJUXROL5NCa3amvMg6VQW2HVtZYmUTPfvVtO7zJWGYLJ+mry9v2OmYm+z67aniQoQ8/yFNadiEwtNS9qQiw==} @@ -14203,6 +14263,10 @@ packages: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + type-is@2.0.1: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} @@ -14257,6 +14321,11 @@ packages: ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + uint8array-extras@1.4.0: resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} engines: {node: '>=18'} @@ -14684,6 +14753,9 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + workerd@1.20251004.0: resolution: {integrity: sha512-1YajTH54RdrQrO5FY1HuH1t87H3bWjbM4MtOTF6XdPQL8LxVWACC46aGjmhyVJKMQNLECs64d+AYFGxVrFTOAA==} engines: {node: '>=16'} @@ -16877,21 +16949,45 @@ snapshots: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 @@ -16902,6 +16998,12 @@ snapshots: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 @@ -16912,11 +17014,23 @@ snapshots: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 @@ -16932,41 +17046,89 @@ snapshots: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.4)': + dependencies: + '@babel/core': 7.27.4 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 @@ -20481,7 +20643,7 @@ snapshots: '@sentry/utils': 7.119.2 localforage: 1.10.0 - '@sentry/nextjs@8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(react@19.1.1)(webpack@5.96.1(@swc/core@1.11.29))': + '@sentry/nextjs@8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(react@19.1.1)(webpack@5.96.1(@swc/core@1.11.29))': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation-http': 0.53.0(@opentelemetry/api@1.9.0) @@ -20497,7 +20659,7 @@ snapshots: '@sentry/vercel-edge': 8.37.1 '@sentry/webpack-plugin': 2.22.6(webpack@5.96.1(@swc/core@1.11.29)) chalk: 3.0.0 - next: 15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + next: 15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) resolve: 1.22.8 rollup: 3.29.5 stacktrace-parser: 0.1.10 @@ -20510,7 +20672,7 @@ snapshots: - supports-color - webpack - '@sentry/nextjs@8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(react@19.1.1)(webpack@5.96.1(@swc/core@1.11.29))': + '@sentry/nextjs@8.37.1(@opentelemetry/core@1.27.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.27.0(@opentelemetry/api@1.9.0))(next@15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(react@19.1.1)(webpack@5.96.1(@swc/core@1.11.29))': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation-http': 0.53.0(@opentelemetry/api@1.9.0) @@ -20526,7 +20688,7 @@ snapshots: '@sentry/vercel-edge': 8.37.1 '@sentry/webpack-plugin': 2.22.6(webpack@5.96.1(@swc/core@1.11.29)) chalk: 3.0.0 - next: 15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + next: 15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) resolve: 1.22.8 rollup: 3.29.5 stacktrace-parser: 0.1.10 @@ -21977,7 +22139,7 @@ snapshots: '@types/better-sqlite3@7.6.13': dependencies: - '@types/node': 22.5.4 + '@types/node': 22.15.30 '@types/busboy@1.5.4': dependencies: @@ -23018,6 +23180,20 @@ snapshots: transitivePeerDependencies: - supports-color + babel-jest@29.7.0(@babel/core@7.27.4): + dependencies: + '@babel/core': 7.27.4 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.27.4) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + optional: true + babel-plugin-istanbul@6.1.1: dependencies: '@babel/helper-plugin-utils': 7.27.1 @@ -23092,12 +23268,39 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.3) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.3) + babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.4): + dependencies: + '@babel/core': 7.27.4 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.4) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.4) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.4) + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.27.4) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.4) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.4) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.4) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.4) + optional: true + babel-preset-jest@29.6.3(@babel/core@7.27.3): dependencies: '@babel/core': 7.27.3 babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.3) + babel-preset-jest@29.6.3(@babel/core@7.27.4): + dependencies: + '@babel/core': 7.27.4 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) + optional: true + balanced-match@1.0.2: {} bare-events@2.5.0: @@ -23209,6 +23412,10 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.3(browserslist@4.25.0) + bs-logger@0.2.6: + dependencies: + fast-json-stable-stringify: 2.1.0 + bser@2.1.1: dependencies: node-int64: 0.4.0 @@ -25117,9 +25324,9 @@ snapshots: - encoding - supports-color - geist@1.4.2(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)): + geist@1.4.2(next@15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)): dependencies: - next: 15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + next: 15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) geist@1.4.2(next@15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.50.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)): dependencies: @@ -25369,6 +25576,15 @@ snapshots: dependencies: duplexer: 0.1.2 + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + has-bigints@1.0.2: {} has-flag@3.0.0: {} @@ -26489,6 +26705,8 @@ snapshots: lodash.isplainobject@4.0.6: {} + lodash.memoize@4.1.2: {} + lodash.merge@4.6.2: {} lodash@4.17.21: {} @@ -26554,6 +26772,8 @@ snapshots: dependencies: semver: 7.7.2 + make-error@1.3.6: {} + makeerror@1.0.12: dependencies: tmpl: 1.0.5 @@ -27038,13 +27258,13 @@ snapshots: transitivePeerDependencies: - supports-color - next-sitemap@4.2.3(next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)): + next-sitemap@4.2.3(next@15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4)): dependencies: '@corex/deepmerge': 4.0.43 '@next/env': 13.5.11 fast-glob: 3.3.2 minimist: 1.2.8 - next: 15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + next: 15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) next-themes@0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: @@ -27080,7 +27300,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.2.3(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4): + next@15.2.3(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4): dependencies: '@next/env': 15.2.3 '@swc/counter': 0.1.3 @@ -27108,7 +27328,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.4.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4): + next@15.4.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@19.1.0-rc.3)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4): dependencies: '@next/env': 15.4.4 '@swc/helpers': 0.5.15 @@ -27161,7 +27381,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4): + next@15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4): dependencies: '@next/env': 15.5.4 '@swc/helpers': 0.5.15 @@ -28468,6 +28688,8 @@ snapshots: semver@7.7.2: {} + semver@7.7.3: {} + send@1.2.0: dependencies: debug: 4.4.1 @@ -29378,6 +29600,26 @@ snapshots: ts-interface-checker@0.1.13: {} + ts-jest@29.4.5(@babel/core@7.27.4)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.4))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.15.30)(babel-plugin-macros@3.1.0))(typescript@5.7.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.8 + jest: 29.7.0(@types/node@22.15.30)(babel-plugin-macros@3.1.0) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.3 + type-fest: 4.41.0 + typescript: 5.7.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.27.4 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.27.4) + jest-util: 29.7.0 + ts-pattern@5.6.2: {} ts-tqdm@0.8.6: {} @@ -29467,6 +29709,8 @@ snapshots: type-fest@0.7.1: {} + type-fest@4.41.0: {} + type-is@2.0.1: dependencies: content-type: 1.0.5 @@ -29554,6 +29798,9 @@ snapshots: ufo@1.6.1: {} + uglify-js@3.19.3: + optional: true + uint8array-extras@1.4.0: {} unbox-primitive@1.0.2: @@ -29686,7 +29933,7 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - uploadthing@7.3.0(express@5.0.1)(next@15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(tailwindcss@4.1.13): + uploadthing@7.3.0(express@5.0.1)(next@15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4))(tailwindcss@4.1.13): dependencies: '@effect/platform': 0.69.8(effect@3.10.3) '@uploadthing/mime-types': 0.3.2 @@ -29694,7 +29941,7 @@ snapshots: effect: 3.10.3 optionalDependencies: express: 5.0.1 - next: 15.5.4(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) + next: 15.5.4(@babel/core@7.27.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.54.1)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(sass@1.77.4) tailwindcss: 4.1.13 uri-js@4.4.1: @@ -30159,6 +30406,8 @@ snapshots: word-wrap@1.2.5: {} + wordwrap@1.0.0: {} + workerd@1.20251004.0: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20251004.0 diff --git a/tools/ts-plugin-inherit-doc/jest.config.js b/tools/ts-plugin-inherit-doc/jest.config.js new file mode 100644 index 00000000000..83c7a48212b --- /dev/null +++ b/tools/ts-plugin-inherit-doc/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + roots: ['/src'], + testMatch: ['**/*.test.ts'], + collectCoverageFrom: ['src/**/*.ts', '!src/**/*.test.ts'], +} diff --git a/tools/ts-plugin-inherit-doc/package.json b/tools/ts-plugin-inherit-doc/package.json index d2a68624c15..dd10c2372d8 100644 --- a/tools/ts-plugin-inherit-doc/package.json +++ b/tools/ts-plugin-inherit-doc/package.json @@ -11,9 +11,16 @@ "types": "dist/index.d.ts", "scripts": { "build": "tsc", + "test": "jest", "watch": "tsc --watch" }, "dependencies": { "typescript": "^5.7.2" + }, + "devDependencies": { + "@types/jest": "^29.5.12", + "@types/node": "^22.15.30", + "jest": "^29.7.0", + "ts-jest": "^29.2.0" } } diff --git a/tools/ts-plugin-inherit-doc/src/index.test.ts b/tools/ts-plugin-inherit-doc/src/index.test.ts new file mode 100644 index 00000000000..d4ba99a1ea8 --- /dev/null +++ b/tools/ts-plugin-inherit-doc/src/index.test.ts @@ -0,0 +1,156 @@ +import * as fs from 'fs' +import * as os from 'os' +import * as path from 'path' +import * as ts from 'typescript/lib/tsserverlibrary' + +// eslint-disable-next-line @typescript-eslint/no-require-imports +const pluginFactory = require('./index') + +describe('ts-plugin-inherit-doc', () => { + let tempDir: string + let testFilePath: string + + beforeEach(() => { + // Create temporary directory for test files + tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ts-plugin-test-')) + testFilePath = path.join(tempDir, 'test.ts') + }) + + afterEach(() => { + // Clean up + fs.rmSync(tempDir, { recursive: true, force: true }) + }) + + function createLanguageService(fileContent: string): ts.LanguageService { + fs.writeFileSync(testFilePath, fileContent) + + const servicesHost: ts.LanguageServiceHost = { + getScriptFileNames: () => [testFilePath], + getScriptVersion: () => '1', + getScriptSnapshot: (fileName) => { + if (fileName === testFilePath) { + const text = fs.readFileSync(fileName, 'utf8') + return ts.ScriptSnapshot.fromString(text) + } + return undefined + }, + getCurrentDirectory: () => tempDir, + getCompilationSettings: () => ({ + target: ts.ScriptTarget.ES2020, + module: ts.ModuleKind.CommonJS, + }), + getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options), + fileExists: ts.sys.fileExists, + readFile: ts.sys.readFile, + readDirectory: ts.sys.readDirectory, + directoryExists: ts.sys.directoryExists, + getDirectories: ts.sys.getDirectories, + } + + const languageService = ts.createLanguageService(servicesHost) + + // Initialize plugin + const plugin = pluginFactory({ typescript: ts }) + const pluginInfo: ts.server.PluginCreateInfo = { + languageService, + languageServiceHost: servicesHost, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + project: {} as any, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + serverHost: {} as any, + config: {}, + } + + return plugin.create(pluginInfo) + } + + test('plugin adds debug marker to all hovers', () => { + const content = ` +type MyType = { + prop: string +} +` + const ls = createLanguageService(content) + const position = content.indexOf('prop') + const quickInfo = ls.getQuickInfoAtPosition(testFilePath, position) + + expect(quickInfo).toBeDefined() + expect(quickInfo!.documentation).toBeDefined() + }) + + test('inherits documentation from referenced type', () => { + const content = ` +/** + * Base type with documentation + */ +type BaseType = { + /** + * A property + */ + prop: string +} + +type DerivedType = { + /** + * @inheritDoc BaseType + */ + field: BaseType +} +` + const ls = createLanguageService(content) + const position = content.indexOf('field:') + const quickInfo = ls.getQuickInfoAtPosition(testFilePath, position) + + expect(quickInfo).toBeDefined() + const docText = quickInfo!.documentation!.map((p) => p.text).join('') + expect(docText).toContain('Base type with documentation') + expect(docText).toContain('prop: A property') + }) + + test('shows debug message when type not found', () => { + const content = ` +type MyType = { + /** + * @inheritDoc NonExistentType + */ + field: string +} +` + const ls = createLanguageService(content) + const position = content.indexOf('field:') + const quickInfo = ls.getQuickInfoAtPosition(testFilePath, position) + + expect(quickInfo).toBeDefined() + const docText = quickInfo!.documentation!.map((p) => p.text).join('') + expect(docText).toContain('NonExistentType') + expect(docText).toContain('not found') + }) + + test('works with interface declarations', () => { + const content = ` +/** + * Interface documentation + */ +interface MyInterface { + /** + * Method docs + */ + method(): void +} + +type MyType = { + /** + * @inheritDoc MyInterface + */ + field: MyInterface +} +` + const ls = createLanguageService(content) + const position = content.lastIndexOf('field:') + const quickInfo = ls.getQuickInfoAtPosition(testFilePath, position) + + expect(quickInfo).toBeDefined() + const docText = quickInfo!.documentation!.map((p) => p.text).join('') + expect(docText).toContain('Interface documentation') + }) +}) diff --git a/tools/ts-plugin-inherit-doc/src/index.ts b/tools/ts-plugin-inherit-doc/src/index.ts index 25f00c44ed0..968a742301a 100644 --- a/tools/ts-plugin-inherit-doc/src/index.ts +++ b/tools/ts-plugin-inherit-doc/src/index.ts @@ -73,6 +73,31 @@ function init(modules: { typescript: typeof import('typescript/lib/tsserverlibra } } + // Also extract properties from type literal or interface members + if (ts.isTypeAliasDeclaration(node) && node.type && ts.isTypeLiteralNode(node.type)) { + for (const member of node.type.members) { + if (ts.isPropertySignature(member) && member.name) { + const propName = member.name.getText() + const propJsDoc = (member as any).jsDoc as ts.JSDoc[] | undefined + if (propJsDoc && propJsDoc.length > 0) { + const propDoc = ts.getTextOfJSDocComment(propJsDoc[0].comment) || '' + properties.set(propName, propDoc) + } + } + } + } else if (ts.isInterfaceDeclaration(node)) { + for (const member of node.members) { + if (ts.isPropertySignature(member) && member.name) { + const propName = member.name.getText() + const propJsDoc = (member as any).jsDoc as ts.JSDoc[] | undefined + if (propJsDoc && propJsDoc.length > 0) { + const propDoc = ts.getTextOfJSDocComment(propJsDoc[0].comment) || '' + properties.set(propName, propDoc) + } + } + } + } + docCache[typeName] = { documentation: fullComment || '', properties, @@ -133,28 +158,103 @@ function init(modules: { typescript: typeof import('typescript/lib/tsserverlibra // Rebuild cache on each request (in production, you'd want smarter invalidation) buildDocCache() - // Check if documentation contains @inheritDoc - const docParts = quickInfo.documentation || [] - const docText = docParts.map((part) => part.text).join('') - const inheritFrom = parseInheritDoc(docText) + // Get the source file and node at position to check for JSDoc + const sourceFile = program?.getSourceFile(fileName) + if (!sourceFile) { + return quickInfo + } + + // Find the node at the cursor position + const node = findNodeAtPosition(sourceFile, position) + if (!node) { + return quickInfo + } + + // Get JSDoc from the node or its parent (for property signatures) + let inheritFrom: null | string = null + + // Check current node and parent for JSDoc + const nodesToCheck = [node, node.parent].filter(Boolean) + + for (const n of nodesToCheck) { + if (!n) {continue} + + // Check if node has jsDoc property (TypeScript internal) + const jsDoc = (n as any).jsDoc as ts.JSDoc[] | undefined + if (jsDoc && jsDoc.length > 0) { + for (const doc of jsDoc) { + if (doc.tags) { + for (const tag of doc.tags) { + if (tag.tagName.text === 'inheritDoc') { + const commentText = + typeof tag.comment === 'string' + ? tag.comment + : ts.getTextOfJSDocComment(tag.comment) + + if (commentText) { + inheritFrom = commentText.trim() + break + } + } + // Also check if the whole comment contains @inheritDoc + if (tag.comment) { + const commentText = + typeof tag.comment === 'string' + ? tag.comment + : ts.getTextOfJSDocComment(tag.comment) - // Add debug marker to ALL hovers to verify plugin is running - const debugMarker: ts.SymbolDisplayPart[] = [{ text: '\n\n[Plugin Active ✓]', kind: 'text' }] + if (commentText) { + const parsed = parseInheritDoc(commentText) + if (parsed) { + inheritFrom = parsed + break + } + } + } + } + } + // Check the doc comment itself + if (!inheritFrom && doc.comment) { + const commentText = + typeof doc.comment === 'string' + ? doc.comment + : ts.getTextOfJSDocComment(doc.comment) + + if (commentText) { + inheritFrom = parseInheritDoc(commentText) + } + } + if (inheritFrom) {break} + } + } + if (inheritFrom) {break} + } + + // If no @inheritDoc in tags, check the documentation text as fallback + if (!inheritFrom) { + const docParts = quickInfo.documentation || [] + const docText = docParts.map((part) => part.text).join('') + inheritFrom = parseInheritDoc(docText) + } if (inheritFrom) { return { ...quickInfo, - documentation: [ - ...mergeDocumentation(quickInfo.documentation, inheritFrom), - ...debugMarker, - ], + documentation: mergeDocumentation(quickInfo.documentation, inheritFrom), } } - return { - ...quickInfo, - documentation: [...docParts, ...debugMarker], + return quickInfo + } + + function findNodeAtPosition(sourceFile: ts.SourceFile, position: number): ts.Node | undefined { + function find(node: ts.Node): ts.Node | undefined { + if (position >= node.getStart() && position < node.getEnd()) { + return ts.forEachChild(node, find) || node + } + return undefined } + return find(sourceFile) } // Proxy all other methods From a5ddad9122f4055d8f2c289b3786e2835f33000f Mon Sep 17 00:00:00 2001 From: Elliot DeNolf Date: Fri, 17 Oct 2025 23:56:36 -0400 Subject: [PATCH 4/4] test: use same jest config as other unit tests --- pnpm-lock.yaml | 239 ------------------ tools/ts-plugin-inherit-doc/jest.config.js | 23 +- tools/ts-plugin-inherit-doc/package.json | 3 +- .../src/{index.test.ts => index.spec.ts} | 8 +- 4 files changed, 23 insertions(+), 250 deletions(-) rename tools/ts-plugin-inherit-doc/src/{index.test.ts => index.spec.ts} (94%) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88fab4f20ef..bfc5611ec42 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2641,9 +2641,6 @@ importers: jest: specifier: ^29.7.0 version: 29.7.0(@types/node@22.15.30)(babel-plugin-macros@3.1.0) - ts-jest: - specifier: ^29.2.0 - version: 29.4.5(@babel/core@7.27.4)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.4))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.15.30)(babel-plugin-macros@3.1.0))(typescript@5.7.3) packages: @@ -8878,10 +8875,6 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} - bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} @@ -10674,11 +10667,6 @@ packages: resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} engines: {node: '>=10'} - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} - engines: {node: '>=0.4.7'} - hasBin: true - has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} @@ -11622,9 +11610,6 @@ packages: lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -11695,9 +11680,6 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -13400,11 +13382,6 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} - engines: {node: '>=10'} - hasBin: true - send@1.2.0: resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} engines: {node: '>= 18'} @@ -14125,33 +14102,6 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - ts-jest@29.4.5: - resolution: {integrity: sha512-HO3GyiWn2qvTQA4kTgjDcXiMwYQt68a1Y8+JuLRVpdIzm+UOLSHgl/XqR4c6nzJkq5rOkjc02O2I7P7l/Yof0Q==} - engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/transform': ^29.0.0 || ^30.0.0 - '@jest/types': ^29.0.0 || ^30.0.0 - babel-jest: ^29.0.0 || ^30.0.0 - esbuild: '*' - jest: ^29.0.0 || ^30.0.0 - jest-util: ^29.0.0 || ^30.0.0 - typescript: 5.7.3 - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/transform': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - jest-util: - optional: true - ts-pattern@5.6.2: resolution: {integrity: sha512-d4IxJUXROL5NCa3amvMg6VQW2HVtZYmUTPfvVtO7zJWGYLJ+mry9v2OmYm+z67aniQoQ8/yFNadiEwtNS9qQiw==} @@ -14263,10 +14213,6 @@ packages: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - type-is@2.0.1: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} @@ -14321,11 +14267,6 @@ packages: ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - uglify-js@3.19.3: - resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} - engines: {node: '>=0.8.0'} - hasBin: true - uint8array-extras@1.4.0: resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} engines: {node: '>=18'} @@ -14753,9 +14694,6 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - wordwrap@1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - workerd@1.20251004.0: resolution: {integrity: sha512-1YajTH54RdrQrO5FY1HuH1t87H3bWjbM4MtOTF6XdPQL8LxVWACC46aGjmhyVJKMQNLECs64d+AYFGxVrFTOAA==} engines: {node: '>=16'} @@ -16949,45 +16887,21 @@ snapshots: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 @@ -16998,12 +16912,6 @@ snapshots: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 @@ -17014,23 +16922,11 @@ snapshots: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 @@ -17046,89 +16942,41 @@ snapshots: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.4)': - dependencies: - '@babel/core': 7.27.4 - '@babel/helper-plugin-utils': 7.27.1 - optional: true - '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.27.3)': dependencies: '@babel/core': 7.27.3 @@ -23180,20 +23028,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-jest@29.7.0(@babel/core@7.27.4): - dependencies: - '@babel/core': 7.27.4 - '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.27.4) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - optional: true - babel-plugin-istanbul@6.1.1: dependencies: '@babel/helper-plugin-utils': 7.27.1 @@ -23268,39 +23102,12 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.3) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.3) - babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.4): - dependencies: - '@babel/core': 7.27.4 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.4) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.4) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.4) - '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.27.4) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.4) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.4) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.4) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.4) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.4) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.4) - optional: true - babel-preset-jest@29.6.3(@babel/core@7.27.3): dependencies: '@babel/core': 7.27.3 babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.3) - babel-preset-jest@29.6.3(@babel/core@7.27.4): - dependencies: - '@babel/core': 7.27.4 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) - optional: true - balanced-match@1.0.2: {} bare-events@2.5.0: @@ -23412,10 +23219,6 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.3(browserslist@4.25.0) - bs-logger@0.2.6: - dependencies: - fast-json-stable-stringify: 2.1.0 - bser@2.1.1: dependencies: node-int64: 0.4.0 @@ -25576,15 +25379,6 @@ snapshots: dependencies: duplexer: 0.1.2 - handlebars@4.7.8: - dependencies: - minimist: 1.2.8 - neo-async: 2.6.2 - source-map: 0.6.1 - wordwrap: 1.0.0 - optionalDependencies: - uglify-js: 3.19.3 - has-bigints@1.0.2: {} has-flag@3.0.0: {} @@ -26705,8 +26499,6 @@ snapshots: lodash.isplainobject@4.0.6: {} - lodash.memoize@4.1.2: {} - lodash.merge@4.6.2: {} lodash@4.17.21: {} @@ -26772,8 +26564,6 @@ snapshots: dependencies: semver: 7.7.2 - make-error@1.3.6: {} - makeerror@1.0.12: dependencies: tmpl: 1.0.5 @@ -28688,8 +28478,6 @@ snapshots: semver@7.7.2: {} - semver@7.7.3: {} - send@1.2.0: dependencies: debug: 4.4.1 @@ -29600,26 +29388,6 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.4.5(@babel/core@7.27.4)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.4))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.15.30)(babel-plugin-macros@3.1.0))(typescript@5.7.3): - dependencies: - bs-logger: 0.2.6 - fast-json-stable-stringify: 2.1.0 - handlebars: 4.7.8 - jest: 29.7.0(@types/node@22.15.30)(babel-plugin-macros@3.1.0) - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.7.3 - type-fest: 4.41.0 - typescript: 5.7.3 - yargs-parser: 21.1.1 - optionalDependencies: - '@babel/core': 7.27.4 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.27.4) - jest-util: 29.7.0 - ts-pattern@5.6.2: {} ts-tqdm@0.8.6: {} @@ -29709,8 +29477,6 @@ snapshots: type-fest@0.7.1: {} - type-fest@4.41.0: {} - type-is@2.0.1: dependencies: content-type: 1.0.5 @@ -29798,9 +29564,6 @@ snapshots: ufo@1.6.1: {} - uglify-js@3.19.3: - optional: true - uint8array-extras@1.4.0: {} unbox-primitive@1.0.2: @@ -30406,8 +30169,6 @@ snapshots: word-wrap@1.2.5: {} - wordwrap@1.0.0: {} - workerd@1.20251004.0: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20251004.0 diff --git a/tools/ts-plugin-inherit-doc/jest.config.js b/tools/ts-plugin-inherit-doc/jest.config.js index 83c7a48212b..4a997307ffa 100644 --- a/tools/ts-plugin-inherit-doc/jest.config.js +++ b/tools/ts-plugin-inherit-doc/jest.config.js @@ -1,7 +1,20 @@ -module.exports = { - preset: 'ts-jest', +/** @type {import('jest').Config} */ +const customJestConfig = { + extensionsToTreatAsEsm: ['.ts', '.tsx'], + // setupFilesAfterEnv: ['/jest.setup.js'], + moduleNameMapper: { + '\\.(css|scss)$': '/helpers/mocks/emptyModule.js', + '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': + '/test/helpers/mocks/fileMock.js', + '^(\\.{1,2}/.*)\\.js$': '$1', + }, testEnvironment: 'node', - roots: ['/src'], - testMatch: ['**/*.test.ts'], - collectCoverageFrom: ['src/**/*.ts', '!src/**/*.test.ts'], + testMatch: ['/**/*spec.ts'], + testTimeout: 160000, + transform: { + '^.+\\.(t|j)sx?$': ['@swc/jest'], + }, + verbose: true, } + +export default customJestConfig diff --git a/tools/ts-plugin-inherit-doc/package.json b/tools/ts-plugin-inherit-doc/package.json index dd10c2372d8..962da9aaaa7 100644 --- a/tools/ts-plugin-inherit-doc/package.json +++ b/tools/ts-plugin-inherit-doc/package.json @@ -20,7 +20,6 @@ "devDependencies": { "@types/jest": "^29.5.12", "@types/node": "^22.15.30", - "jest": "^29.7.0", - "ts-jest": "^29.2.0" + "jest": "^29.7.0" } } diff --git a/tools/ts-plugin-inherit-doc/src/index.test.ts b/tools/ts-plugin-inherit-doc/src/index.spec.ts similarity index 94% rename from tools/ts-plugin-inherit-doc/src/index.test.ts rename to tools/ts-plugin-inherit-doc/src/index.spec.ts index d4ba99a1ea8..a7b69163602 100644 --- a/tools/ts-plugin-inherit-doc/src/index.test.ts +++ b/tools/ts-plugin-inherit-doc/src/index.spec.ts @@ -64,7 +64,7 @@ describe('ts-plugin-inherit-doc', () => { return plugin.create(pluginInfo) } - test('plugin adds debug marker to all hovers', () => { + it('plugin adds debug marker to all hovers', () => { const content = ` type MyType = { prop: string @@ -78,7 +78,7 @@ type MyType = { expect(quickInfo!.documentation).toBeDefined() }) - test('inherits documentation from referenced type', () => { + it('inherits documentation from referenced type', () => { const content = ` /** * Base type with documentation @@ -107,7 +107,7 @@ type DerivedType = { expect(docText).toContain('prop: A property') }) - test('shows debug message when type not found', () => { + it('shows debug message when type not found', () => { const content = ` type MyType = { /** @@ -126,7 +126,7 @@ type MyType = { expect(docText).toContain('not found') }) - test('works with interface declarations', () => { + it('works with interface declarations', () => { const content = ` /** * Interface documentation