@typed/virtual-modules-ts-plugin 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -0
- package/dist/plugin.d.ts +16 -0
- package/dist/plugin.js +2475 -0
- package/package.json +40 -0
- package/src/plugin.d.ts +16 -0
- package/src/plugin.test.ts +419 -0
- package/src/plugin.ts +410 -0
- package/src/sample-project.integration.test.ts +39 -0
- package/src/types.ts +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# @typed/virtual-modules-ts-plugin
|
|
2
|
+
|
|
3
|
+
TypeScript Language Service plugin that integrates [@typed/virtual-modules](../virtual-modules) into the TypeScript Language Service so editors (VS Code, Cursor, etc.) get full type-checking and IntelliSense for virtual imports such as `virtual:foo`, `router:./routes`, and `api:./endpoints`. Uses the same `vmc.config.ts` as the `vmc` CLI and Vite plugin — a single config for editor, build, and dev server.
|
|
4
|
+
|
|
5
|
+
## What this enables
|
|
6
|
+
|
|
7
|
+
- Live type-checking and IntelliSense for virtual modules in the editor
|
|
8
|
+
- Support for plugins that use the TypeInfo API (e.g. router route validation, HttpApi endpoint validation)
|
|
9
|
+
- No "Cannot find module" errors for virtual IDs when correctly configured
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add -D @typed/virtual-modules-ts-plugin
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
Define your virtual module resolver/plugins in `vmc.config.ts` (project root):
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// vmc.config.ts
|
|
23
|
+
import { createRouterVirtualModulePlugin } from "@typed/app";
|
|
24
|
+
|
|
25
|
+
export default {
|
|
26
|
+
plugins: [createRouterVirtualModulePlugin()],
|
|
27
|
+
};
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Then add the TS plugin to `tsconfig.json`:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"compilerOptions": {
|
|
35
|
+
"plugins": [
|
|
36
|
+
{
|
|
37
|
+
"name": "@typed/virtual-modules-ts-plugin",
|
|
38
|
+
"debounceMs": 50
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Important:** Use the package name `@typed/virtual-modules-ts-plugin` rather than path-style names like `"../"`. Path-style names often fail to resolve when the workspace root is a monorepo parent, because tsserver loads plugins from `node_modules` using the plugin name.
|
|
46
|
+
|
|
47
|
+
### Config options
|
|
48
|
+
|
|
49
|
+
| Option | Type | Default | Description |
|
|
50
|
+
| --------------- | -------- | ----------------------------------- | --------------------------------------------------------------- |
|
|
51
|
+
| `vmcConfigPath` | `string` | `"vmc.config.ts"` (auto-discovered) | Optional explicit path to vmc config, relative to project root. |
|
|
52
|
+
| `debounceMs` | `number` | `50` | Debounce rapid watch events (ms). |
|
|
53
|
+
|
|
54
|
+
## Plugin format
|
|
55
|
+
|
|
56
|
+
Plugin modules referenced from `vmc.config.ts` can be synchronous ESM modules (no top-level await):
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
// virtual/foo.mjs
|
|
60
|
+
export default {
|
|
61
|
+
name: "foo",
|
|
62
|
+
shouldResolve: (id) => id === "virtual:foo",
|
|
63
|
+
build: () => "export interface Foo { n: number }",
|
|
64
|
+
};
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Local testing
|
|
68
|
+
|
|
69
|
+
### Automated tests
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pnpm build && pnpm test
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Manual test with sample project
|
|
76
|
+
|
|
77
|
+
From the repo root:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
cd packages/virtual-modules-ts-plugin
|
|
81
|
+
pnpm build
|
|
82
|
+
cd sample-project
|
|
83
|
+
pnpm install
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Then open `sample-project` in VS Code (or another editor that uses tsserver). The `entry.ts` file imports `virtual:foo`; with the plugin enabled, you should get full type-checking and no diagnostics.
|
|
87
|
+
|
|
88
|
+
To test changes: rebuild the plugin, then run **TypeScript: Restart TS Server** in VS Code (Command Palette) to pick up the new build.
|
|
89
|
+
|
|
90
|
+
## When the plugin can throw
|
|
91
|
+
|
|
92
|
+
The plugin may throw in these cases (see [virtual-modules-errors-and-gotchas](../virtual-modules/.docs/virtual-modules-errors-and-gotchas.md) for full reference):
|
|
93
|
+
|
|
94
|
+
- **"Program not yet available"** — When virtual module resolution runs before the TypeScript project is fully loaded (e.g. first file open, before first compile). Retry when the project is loaded.
|
|
95
|
+
- **Session creation failure** — When `createTypeInfoApiSession` throws (e.g. type targets cannot be resolved) and no fallback session exists. Ensure type targets are imported or use `createTypeTargetBootstrapContent`.
|
|
96
|
+
|
|
97
|
+
Sample scripts (`typecheck-with-plugin.mjs`, `verify-virtual-modules.mjs`) throw on tsconfig read failure, missing vmc config, plugin load failure, or no plugins — document as expected for CLI entry points.
|
|
98
|
+
|
|
99
|
+
## Debug log
|
|
100
|
+
|
|
101
|
+
The plugin writes diagnostic events to `/tmp/vm-ts-plugin-debug.log` when the file is writable. Use this to confirm whether the plugin loads and whether resolution runs.
|
|
102
|
+
|
|
103
|
+
- **`create`** – Plugin `create()` was called; includes `projectRoot` and `configPath`
|
|
104
|
+
- **`attach`** – Adapter was attached to the language service host
|
|
105
|
+
- **`vmc`** – vmc.config load result; includes `status`, `hasResolver`, `typeTargetSpecs` count
|
|
106
|
+
- **`LS:resolve`** / **`LS:resolveLiterals`** – `resolveModuleNames` / `resolveModuleNameLiterals` were invoked (resolution is using the patched host)
|
|
107
|
+
- **`fallbackProgram`** – Fallback program creation result
|
|
108
|
+
|
|
109
|
+
If virtual modules still show "Cannot find module" but the log shows `create` and `attach`, resolution is being invoked and the issue is likely in the resolver or vmc.config. If the log has no `create`, the plugin did not load (check plugin name and `node_modules`).
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type * as ts from "typescript";
|
|
2
|
+
|
|
3
|
+
interface VirtualModulesTsPluginConfig {
|
|
4
|
+
readonly debounceMs?: number;
|
|
5
|
+
readonly vmcConfigPath?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
declare function init(modules: { typescript: typeof import("typescript") }): {
|
|
9
|
+
create: (info: {
|
|
10
|
+
languageService: ts.LanguageService;
|
|
11
|
+
project: ts.LanguageServiceHost;
|
|
12
|
+
config?: VirtualModulesTsPluginConfig;
|
|
13
|
+
}) => ts.LanguageService;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export = init;
|