Skip to content

Add shared extension toolkit for DI and extension infrastructure#22416

Open
aasimkhan30 wants to merge 4 commits into
mainfrom
aasim/feat/toolkitPackage
Open

Add shared extension toolkit for DI and extension infrastructure#22416
aasimkhan30 wants to merge 4 commits into
mainfrom
aasim/feat/toolkitPackage

Conversation

@aasimkhan30

Copy link
Copy Markdown
Contributor

Description

Adds a shared extension-toolkit package 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

  • New or updated unit tests added
  • All existing tests pass (npm run test)
  • Code follows contributing guidelines
  • Telemetry/logging updated if relevant
  • No regressions or UX breakage

Reviewers: Please read our reviewer guidelines

- 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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-toolkit with DI primitives, lifecycle helpers, and VS Code extension-host services (plus testing helpers).
  • Refactored mssql, sql-database-projects, and data-workspace activation entrypoints to use the new DI primitives and IExtensionContextService.
  • 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 thread scripts/workspaces.mjs
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;
}
Copilot AI review requested due to automatic review settings July 2, 2026 20:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 thread scripts/workspaces.mjs
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants