Add bundled schema support to LSP server and VS Code client#310
Open
holodorum wants to merge 18 commits intokson-org:mainfrom
Open
Add bundled schema support to LSP server and VS Code client#310holodorum wants to merge 18 commits intokson-org:mainfrom
holodorum wants to merge 18 commits intokson-org:mainfrom
Conversation
Introduce BundledSchemaProvider and CompositeSchemaProvider to enable schemas to be shipped with the extension. CompositeSchemaProvider chains multiple providers with priority ordering, ensuring user-configured schemas take precedence over bundled ones. - Add BundledSchemaProvider for extension-bundled schemas - Add CompositeSchemaProvider with priority-based provider chaining - Extend SchemaProvider interface with optional languageId parameter - Add unit and integration tests for both providers # Conflicts: # tooling/language-server-protocol/src/core/document/KsonDocumentsManager.ts
- Add bundledSchemaLoader utility to load schemas from extension - Update languageConfig to extract bundledSchema from package.json - Update clientOptions to pass bundled schemas via initializationOptions - Update both node and browser clients to load and pass bundled schemas - Update StatusBarManager to show (bundled) indicator for bundled schemas - Add enableBundledSchemas setting to package.json - Update esbuild to copy schemas directory to dist
VS Code failed to navigate to bundled schemas with error:
"Unable to resolve resource bundled://schema/xxx"
The LSP server creates schema documents with bundled:// URIs for schemas
shipped with the extension. VS Code doesn't natively understand this
scheme, so "Go to Definition" failed when pointing to these URIs.
Fix: Register a TextDocumentContentProvider for the bundled:// scheme
that maps bundled://schema/{languageId} URIs to the pre-loaded schema
content.
The bundled:// approach was chosen over file:// URIs because:
- Browser environments may not have access to extension files via file://
- The server doesn't need to know the extension's installation path
- Schema content is loaded once at startup and kept in memory
Added integration tests for bundled schema navigation by bundling the
json draft 7 metaschema.
Change bundled schema URIs from bundled://schema/{languageId} to
bundled://schema/{languageId}.schema.kson. This enables VS Code to
recognize bundled schemas as KSON files and apply syntax highlighting
when navigating to definitions.
- Match schemas by file extension instead of languageId
- Deduplicate BundledSchemaConfig interface across packages
The deactivate() function was being called immediately at module load instead of being exported for VS Code to call during extension deactivation. This caused "command already exists" errors when files with bundled schemas were opened, as the language client tried to re-register commands without the previous client being properly cleaned up. By adding it to the subscriptions this deactivation is handled by VSCode
Schema validation already includes parse errors, so use it exclusively when available instead of combining both sources.
Extract duplicated schema resolution logic in KsonDocumentsManager into a resolveSchema() helper. Remove unused context parameter from registerBundledSchemaContentProvider.
Add KsonSchemaDocument extending KsonDocument to encode the domain rule that only schema files get metaschema resolution. Move extractSchemaId into KsonDocument, replace resolveSchema with type-aware resolveDocument, and update all services to explicitly check document type at each call site.
The same 3-line pattern (refreshDocumentSchemas, sendNotification, sendRequest) was duplicated in onDidChangeWatchedFiles, onDidChangeConfiguration, and onNotification handlers. Extract into a single notifySchemaChange() helper.
The onNotification handler duplicated the onDidChangeConfiguration handler's behavior for the enableBundledSchemas setting, and no client code sends this notification. Remove the redundant code path.
Replace fragile positional parameters with a named options object. The old constructor had metaSchemas as 4th parameter after an optional logger, requiring callers to pass logger explicitly to reach it.
Remove isBundled from the kson/getDocumentSchema server response. The client already has the schema URI and can derive the bundled status from the bundled:// scheme directly.
- Move .gitkeep instructions to schemas/README.md (conventionally empty) - Add trailing newlines to both ksonClientMain.ts files - Fix brittle regex key normalization in BundledSchemaContentProvider with explicit path handling - Remove backslash handling from findMatchingExtension (LSP URIs always use forward slashes) - Add validation warning for common fileExtension format mistakes (leading dot, glob patterns)
Add exact definition.length assertions to tests that use .find() to locate results. This catches regressions where one source unexpectedly returns too many or too few results.
Replace fixed setTimeout delays with waitForDiagnostics and waitForDefinitions polling helpers. This eliminates timing-dependent false passes (the Go-to-Definition test had an early return that silently passed when definitions weren't ready yet).
Deduplicate waitForDiagnostics, waitForDefinitions, waitForHover, and waitForCompletions from 5 test files into common.ts, backed by a generic pollUntil helper.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
BundledSchemaProviderfor schemas shipped with the extension, matched by file extension — works in both desktop and browser (unlikeFileSystemSchemaProviderwhich requires Node.jsfs)'$schema': 'http://json-schema.org/draft-07/schema#'automatically get hover, completion, and go-to-definition from the bundled Draft 7metaschema
CompositeSchemaProviderto chain providers by priority (file system > bundled > metaschema)TextDocumentContentProviderforbundled://URIs so go-to-definition can navigate into bundled schema contentbundledSchemafield to the language contribution inpackage.jsonHow it works
Schema resolution has two layers:
bundledSchemapath inpackage.jsonmaps file-extensions to a schema file shipped in the extension. This is the bundled equivalent of the existing.kson-schema.ksonfile system approach.$schemacontent — if no extension match is found, the LSP parses the document's$schemafield and matches it against bundled metaschemas. This is how the Draft 7 metaschema kicks in for any.schema.ksonfile.Schemas are loaded client-side via
vscode.workspace.fs(cross-platform), serialized through LSPinitializationOptions, and reconstructed server-side byBundledSchemaProvider.