Add shared extension toolkit for DI and extension infrastructure#22416
Open
aasimkhan30 wants to merge 4 commits into
Open
Add shared extension toolkit for DI and extension infrastructure#22416aasimkhan30 wants to merge 4 commits into
aasimkhan30 wants to merge 4 commits into
Conversation
- Introduced the extension-toolkit package for reusable building blocks in VS Code extensions. - Added ESLint configuration and custom rules for enforcing layering within the toolkit. - Implemented logging services and context management for extensions. - Created necessary TypeScript files and configurations for building and testing.
…factor activation logic
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a new shared packages/extension-toolkit package providing VS Code-style DI primitives and a VS Code extension context service, then refactors multiple extensions’ activation flows to use the shared DI foundation. It also updates repo tooling (workspace scripts + ESLint) to treat extension-toolkit as a first-class target with layering rules.
Changes:
- Added
packages/extension-toolkitwith DI primitives, lifecycle helpers, and VS Code extension-host services (plus testing helpers). - Refactored
mssql,sql-database-projects, anddata-workspaceactivation entrypoints to use the new DI primitives andIExtensionContextService. - Updated workspace scripts to support target dependencies and added an ESLint rule to enforce toolkit layering.
Reviewed changes
Copilot reviewed 27 out of 31 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/workspaces.mjs | Adds dependency expansion when resolving workspace targets. |
| scripts/workspace-targets.mjs | Introduces extension-toolkit as a workspace target and adds it as a dependency for other targets. |
| packages/extension-toolkit/tsconfig.json | TypeScript config for building the new toolkit package. |
| packages/extension-toolkit/src/vscode/testing/index.ts | Re-exports toolkit VS Code testing utilities. |
| packages/extension-toolkit/src/vscode/testing/fakeExtensionContext.ts | Adds a fake ExtensionContext helper for tests. |
| packages/extension-toolkit/src/vscode/index.ts | Public VS Code layer entrypoint for the toolkit. |
| packages/extension-toolkit/src/vscode/context/extensionContextService.ts | Adds an IExtensionContextService DI service for ExtensionContext. |
| packages/extension-toolkit/src/base/lifecycle/index.ts | Base lifecycle barrel export. |
| packages/extension-toolkit/src/base/lifecycle/disposable.ts | Adds disposable primitives (DisposableStore, Disposable). |
| packages/extension-toolkit/src/base/index.ts | Base layer barrel export. |
| packages/extension-toolkit/src/base/di/serviceIdentifier.ts | Implements service identifiers + dependency metadata collection. |
| packages/extension-toolkit/src/base/di/serviceDescriptor.ts | Adds a descriptor for deferred service construction. |
| packages/extension-toolkit/src/base/di/serviceCollection.ts | Adds a map-backed service registry. |
| packages/extension-toolkit/src/base/di/instantiationService.ts | Implements an instantiation service + builder for DI-based construction. |
| packages/extension-toolkit/src/base/di/index.ts | DI barrel export. |
| packages/extension-toolkit/README.md | Documents toolkit layers and import guidance. |
| packages/extension-toolkit/package.json | Declares toolkit package metadata, exports, and build/lint scripts. |
| packages/extension-toolkit/package-lock.json | Locks toolkit dev dependencies. |
| extensions/sql-database-projects/src/extension.ts | Refactors activation to use InstantiationServiceBuilder and IExtensionContextService. |
| extensions/sql-database-projects/package.json | Adds extension-toolkit file dependency. |
| extensions/sql-database-projects/package-lock.json | Locks the new local toolkit dependency linkage. |
| extensions/mssql/src/extension.ts | Refactors activation into an activation class created by the DI container. |
| extensions/mssql/package.json | Adds extension-toolkit file dependency. |
| extensions/mssql/package-lock.json | Locks the new local toolkit dependency linkage. |
| extensions/data-workspace/src/main.ts | Refactors activation to use InstantiationServiceBuilder and an activation class. |
| extensions/data-workspace/src/common/iconHelper.ts | Renames static context field to _extensionContext. |
| extensions/data-workspace/package.json | Adds extension-toolkit file dependency. |
| extensions/data-workspace/package-lock.json | Locks the new local toolkit dependency linkage. |
| eslint/custom-rules/index.js | Registers the new toolkit layering rule. |
| eslint/custom-rules/extension-toolkit-layering.js | Adds ESLint rule enforcing base/vscode/testing layering boundaries inside the toolkit. |
| eslint.config.mjs | Enables TypeScript-aware linting and layering rule for toolkit sources. |
Files not reviewed (4)
- extensions/data-workspace/package-lock.json: Generated file
- extensions/mssql/package-lock.json: Generated file
- extensions/sql-database-projects/package-lock.json: Generated file
- packages/extension-toolkit/package-lock.json: Generated file
Comment on lines
89
to
94
| function resolveTargets(action, targetValue) { | ||
| const availableTargets = workspaceTargets.filter((target) => target.scripts.includes(action)); | ||
|
|
||
| if (!targetValue) { | ||
| return availableTargets; | ||
| return expandTargetsWithDependencies(action, availableTargets); | ||
| } |
Comment on lines
+23
to
+46
| export function createServiceIdentifier<T>(id: string): ServiceIdentifier<T> { | ||
| const decorator = function ( | ||
| target: Function, | ||
| _propertyKey: string | symbol | undefined, | ||
| parameterIndex: number, | ||
| ): void { | ||
| if (typeof parameterIndex !== "number") { | ||
| throw new Error( | ||
| `Service '${id}' can only be used as a constructor parameter decorator.`, | ||
| ); | ||
| } | ||
|
|
||
| const existing = serviceDependencies.get(target) ?? []; | ||
| existing.push({ id: decorator as ServiceIdentifier<unknown>, index: parameterIndex }); | ||
| serviceDependencies.set(target, existing); | ||
| } as ServiceIdentifier<T>; | ||
|
|
||
| Object.defineProperties(decorator, { | ||
| id: { value: id, enumerable: true }, | ||
| type: { value: undefined }, | ||
| }); | ||
|
|
||
| return decorator; | ||
| } |
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 31 changed files in this pull request and generated 3 comments.
Files not reviewed (4)
- extensions/data-workspace/package-lock.json: Generated file
- extensions/mssql/package-lock.json: Generated file
- extensions/sql-database-projects/package-lock.json: Generated file
- packages/extension-toolkit/package-lock.json: Generated file
Comment on lines
23
to
+32
| target: "sql-database-projects", | ||
| aliases: ["sql-database-projects", "sqlproj"], | ||
| packageName: "sql-database-projects-vscode", | ||
| directory: "extensions/sql-database-projects", | ||
| scripts: ["build", "watch", "test", "lint", "package"], | ||
| dependencies: { | ||
| build: ["extension-toolkit"], | ||
| watch: ["extension-toolkit"], | ||
| lint: ["extension-toolkit"], | ||
| }, |
Comment on lines
35
to
+44
| target: "data-workspace", | ||
| aliases: ["data-workspace", "dataworkspace"], | ||
| packageName: "data-workspace-vscode", | ||
| directory: "extensions/data-workspace", | ||
| scripts: ["build", "watch", "test", "lint", "package"], | ||
| dependencies: { | ||
| build: ["extension-toolkit"], | ||
| watch: ["extension-toolkit"], | ||
| lint: ["extension-toolkit"], | ||
| }, |
Comment on lines
321
to
349
| if (prerelease && action !== "package") { | ||
| throw new Error( | ||
| `The --preview/--pre-release flag is only supported for the "package" action.`, | ||
| ); | ||
| } | ||
|
|
||
| const targets = resolveTargets(action, targetValue); | ||
| ensureProdBuildSupport(targets, prod); | ||
| const { targets, requestedTargets } = resolveTargets(action, targetValue); | ||
| const requestedTargetNames = new Set(requestedTargets.map((target) => target.target)); | ||
| ensureProdBuildSupport(requestedTargets, prod); | ||
|
|
||
| let actionArgs = forwardedArgs; | ||
| if (prod) { | ||
| actionArgs = [...actionArgs, "--prod"]; | ||
| } | ||
| const getActionArgs = (target) => { | ||
| let actionArgs = forwardedArgs; | ||
|
|
||
| if (prerelease) { | ||
| actionArgs = [...actionArgs, "--pre-release"]; | ||
| } | ||
| if (prod && requestedTargetNames.has(target.target)) { | ||
| actionArgs = [...actionArgs, "--prod"]; | ||
| } | ||
|
|
||
| if (prerelease && requestedTargetNames.has(target.target)) { | ||
| actionArgs = [...actionArgs, "--pre-release"]; | ||
| } | ||
|
|
||
| return actionArgs; | ||
| }; | ||
|
|
||
| if (action === "watch") { | ||
| const watchableTargets = pruneRedundantWatchTargets(targets); | ||
| watchTargets(watchableTargets, actionArgs); | ||
| watchTargets(watchableTargets, forwardedArgs); | ||
| return; | ||
| } |
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.
Description
Adds a shared
extension-toolkitpackage with VS Code-style DI primitives and an extension context service, then wires it into the mssql, SQL Database Projects, and Data Workspace extensions.This keeps activation readable in each extension while giving us a common foundation for future shared extension infrastructure and DI.
Code Changes Checklist
npm run test)Reviewers: Please read our reviewer guidelines