@astrojs/ts-plugin 1.0.10 → 1.1.0

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.
Files changed (38) hide show
  1. package/README.md +25 -1
  2. package/dist/astro2tsx.d.ts +15 -2
  3. package/dist/astro2tsx.js +121 -5
  4. package/dist/index.d.ts +1 -6
  5. package/dist/index.js +21 -47
  6. package/dist/language.d.ts +17 -0
  7. package/dist/language.js +47 -0
  8. package/package.json +6 -3
  9. package/dist/astro-snapshots.d.ts +0 -44
  10. package/dist/astro-snapshots.js +0 -234
  11. package/dist/astro-sys.d.ts +0 -6
  12. package/dist/astro-sys.js +0 -30
  13. package/dist/language-service/completions.d.ts +0 -3
  14. package/dist/language-service/completions.js +0 -45
  15. package/dist/language-service/definition.d.ts +0 -3
  16. package/dist/language-service/definition.js +0 -38
  17. package/dist/language-service/diagnostics.d.ts +0 -7
  18. package/dist/language-service/diagnostics.js +0 -62
  19. package/dist/language-service/file-references.d.ts +0 -3
  20. package/dist/language-service/file-references.js +0 -30
  21. package/dist/language-service/find-references.d.ts +0 -4
  22. package/dist/language-service/find-references.js +0 -66
  23. package/dist/language-service/implementation.d.ts +0 -3
  24. package/dist/language-service/implementation.js +0 -30
  25. package/dist/language-service/index.d.ts +0 -5
  26. package/dist/language-service/index.js +0 -44
  27. package/dist/language-service/line-column-offset.d.ts +0 -3
  28. package/dist/language-service/line-column-offset.js +0 -21
  29. package/dist/language-service/rename.d.ts +0 -4
  30. package/dist/language-service/rename.js +0 -34
  31. package/dist/logger.d.ts +0 -8
  32. package/dist/logger.js +0 -40
  33. package/dist/module-loader.d.ts +0 -13
  34. package/dist/module-loader.js +0 -146
  35. package/dist/project-astro-files.d.ts +0 -28
  36. package/dist/project-astro-files.js +0 -102
  37. package/dist/utils.d.ts +0 -16
  38. package/dist/utils.js +0 -61
@@ -1,146 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.patchModuleLoader = void 0;
4
- const astro_sys_js_1 = require("./astro-sys.js");
5
- const utils_js_1 = require("./utils.js");
6
- /**
7
- * Caches resolved modules.
8
- */
9
- class ModuleResolutionCache {
10
- constructor() {
11
- this.cache = new Map();
12
- }
13
- /**
14
- * Tries to get a cached module.
15
- */
16
- get(moduleName, containingFile) {
17
- return this.cache.get(this.getKey(moduleName, containingFile));
18
- }
19
- /**
20
- * Caches resolved module, if it is not undefined.
21
- */
22
- set(moduleName, containingFile, resolvedModule) {
23
- if (!resolvedModule) {
24
- return;
25
- }
26
- this.cache.set(this.getKey(moduleName, containingFile), resolvedModule);
27
- }
28
- /**
29
- * Deletes module from cache. Call this if a file was deleted.
30
- * @param resolvedModuleName full path of the module
31
- */
32
- delete(resolvedModuleName) {
33
- this.cache.forEach((val, key) => {
34
- if (val.resolvedFileName === resolvedModuleName) {
35
- this.cache.delete(key);
36
- }
37
- });
38
- }
39
- getKey(moduleName, containingFile) {
40
- return containingFile + ':::' + (0, utils_js_1.ensureRealAstroFilePath)(moduleName);
41
- }
42
- }
43
- /**
44
- * Creates a module loader than can also resolve `.astro` files.
45
- *
46
- * The typescript language service tries to look up other files that are referenced in the currently open astro file.
47
- * For `.ts`/`.js` files this works, for `.astro` files it does not by default.
48
- * Reason: The typescript language service does not know about the `.astro` file ending,
49
- * so it assumes it's a normal typescript file and searches for files like `../Component.astro.ts`, which is wrong.
50
- * In order to fix this, we need to wrap typescript's module resolution and reroute all `.astro.ts` file lookups to .astro.
51
- */
52
- function patchModuleLoader(logger, snapshotManager, typescript, lsHost, project) {
53
- const astroSys = (0, astro_sys_js_1.createAstroSys)(logger, typescript);
54
- const moduleCache = new ModuleResolutionCache();
55
- const origResolveModuleNames = lsHost.resolveModuleNames?.bind(lsHost);
56
- const origResolveModuleNamLiterals = lsHost.resolveModuleNameLiterals?.bind(lsHost);
57
- if (lsHost.resolveModuleNameLiterals) {
58
- lsHost.resolveModuleNameLiterals = resolveModuleNameLiterals;
59
- }
60
- else {
61
- lsHost.resolveModuleNames = resolveModuleNames;
62
- }
63
- const origRemoveFile = project.removeFile.bind(project);
64
- project.removeFile = (info, fileExists, detachFromProject) => {
65
- logger.log('File is being removed. Delete from cache: ', info.fileName);
66
- moduleCache.delete(info.fileName);
67
- return origRemoveFile(info, fileExists, detachFromProject);
68
- };
69
- // Patch readDirectory so we get completions for .astro files
70
- const origReadDirectory = project.readDirectory.bind(project);
71
- project.readDirectory = (path, extensions, exclude, include, depth) => {
72
- const extensionsWithAstro = (extensions ?? []).concat('.astro', '.md', '.mdx');
73
- return origReadDirectory(path, extensionsWithAstro, exclude, include, depth);
74
- };
75
- function resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference, compilerOptions) {
76
- // logger.log('Resolving modules names for ' + containingFile);
77
- // Try resolving all module names with the original method first.
78
- // The ones that are undefined will be re-checked if they are a
79
- // astro file and if so, are resolved, too. This way we can defer
80
- // all module resolving logic except for astro files to TypeScript.
81
- const resolved = origResolveModuleNames?.(moduleNames, containingFile, reusedNames, redirectedReference, compilerOptions) || Array.from(Array(moduleNames.length));
82
- return resolved.map((moduleName, idx) => {
83
- const fileName = moduleNames[idx];
84
- if (moduleName || !(0, utils_js_1.ensureRealAstroFilePath)(fileName).endsWith('.astro')) {
85
- return moduleName;
86
- }
87
- const cachedModule = moduleCache.get(fileName, containingFile);
88
- if (cachedModule) {
89
- return cachedModule;
90
- }
91
- const resolvedModule = resolveModuleName(fileName, containingFile, compilerOptions);
92
- moduleCache.set(fileName, containingFile, resolvedModule);
93
- return resolvedModule;
94
- });
95
- }
96
- function resolveModuleName(name, containingFile, compilerOptions) {
97
- const astroResolvedModule = typescript.resolveModuleName(name, containingFile, compilerOptions, astroSys).resolvedModule;
98
- if (!astroResolvedModule || !(0, utils_js_1.isVirtualAstroFilePath)(astroResolvedModule.resolvedFileName)) {
99
- return astroResolvedModule;
100
- }
101
- const resolvedFileName = (0, utils_js_1.ensureRealAstroFilePath)(astroResolvedModule.resolvedFileName);
102
- logger.log('Resolved', name, 'to astro file', resolvedFileName);
103
- const snapshot = snapshotManager.create(resolvedFileName);
104
- if (!snapshot) {
105
- return undefined;
106
- }
107
- const resolvedAstroModule = {
108
- extension: typescript.Extension.Tsx,
109
- resolvedFileName,
110
- };
111
- return resolvedAstroModule;
112
- }
113
- function resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames) {
114
- logger.log('Resolving modules names for ' + containingFile);
115
- // Try resolving all module names with the original method first.
116
- // The ones that are undefined will be re-checked if they are a
117
- // Astro file and if so, are resolved, too. This way we can defer
118
- // all module resolving logic except for Astro files to TypeScript.
119
- const resolved = origResolveModuleNamLiterals?.(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames) ??
120
- moduleLiterals.map(() => ({
121
- resolvedModule: undefined,
122
- }));
123
- return resolved.map((tsResolvedModule, idx) => {
124
- const moduleName = moduleLiterals[idx].text;
125
- if (tsResolvedModule.resolvedModule ||
126
- !(0, utils_js_1.ensureRealAstroFilePath)(moduleName).endsWith('.astro')) {
127
- return tsResolvedModule;
128
- }
129
- return resolveAstroModuleNameFromCache(moduleName, containingFile, options);
130
- });
131
- }
132
- function resolveAstroModuleNameFromCache(moduleName, containingFile, options) {
133
- const cachedModule = moduleCache.get(moduleName, containingFile);
134
- if (cachedModule) {
135
- return {
136
- resolvedModule: cachedModule,
137
- };
138
- }
139
- const resolvedModule = resolveModuleName(moduleName, containingFile, options);
140
- moduleCache.set(moduleName, containingFile, resolvedModule);
141
- return {
142
- resolvedModule: resolvedModule,
143
- };
144
- }
145
- }
146
- exports.patchModuleLoader = patchModuleLoader;
@@ -1,28 +0,0 @@
1
- import type ts from 'typescript/lib/tsserverlibrary';
2
- import type { AstroSnapshotManager } from './astro-snapshots';
3
- export declare class ProjectAstroFilesManager {
4
- private readonly typescript;
5
- private readonly project;
6
- private readonly serverHost;
7
- private readonly snapshotManager;
8
- private parsedCommandLine;
9
- private files;
10
- private directoryWatchers;
11
- private static instances;
12
- static getInstance(projectName: string): ProjectAstroFilesManager | undefined;
13
- constructor(typescript: typeof ts, project: ts.server.Project, serverHost: ts.server.ServerHost, snapshotManager: AstroSnapshotManager, parsedCommandLine: ts.ParsedCommandLine);
14
- updateProjectConfig(serviceHost: ts.LanguageServiceHost): void;
15
- getFiles(): string[];
16
- /**
17
- * Create directory watcher for include and exclude
18
- * The watcher in tsserver doesn't support astro file
19
- * It won't add new created astro file to root
20
- */
21
- private setupWatchers;
22
- private watcherCallback;
23
- private updateProjectAstroFiles;
24
- private addFileToProject;
25
- private removeFileFromProject;
26
- private disposeWatchersAndFiles;
27
- dispose(): void;
28
- }
@@ -1,102 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ProjectAstroFilesManager = void 0;
4
- const utils_1 = require("./utils");
5
- class ProjectAstroFilesManager {
6
- static getInstance(projectName) {
7
- return this.instances.get(projectName);
8
- }
9
- constructor(typescript, project, serverHost, snapshotManager, parsedCommandLine) {
10
- this.typescript = typescript;
11
- this.project = project;
12
- this.serverHost = serverHost;
13
- this.snapshotManager = snapshotManager;
14
- this.parsedCommandLine = parsedCommandLine;
15
- this.files = new Set();
16
- this.directoryWatchers = new Set();
17
- this.setupWatchers();
18
- this.updateProjectAstroFiles();
19
- ProjectAstroFilesManager.instances.set(project.getProjectName(), this);
20
- }
21
- updateProjectConfig(serviceHost) {
22
- const parsedCommandLine = serviceHost.getParsedCommandLine?.((0, utils_1.getConfigPathForProject)(this.project));
23
- if (!parsedCommandLine) {
24
- return;
25
- }
26
- this.disposeWatchersAndFiles();
27
- this.parsedCommandLine = parsedCommandLine;
28
- this.setupWatchers();
29
- this.updateProjectAstroFiles();
30
- }
31
- getFiles() {
32
- return Array.from(this.files);
33
- }
34
- /**
35
- * Create directory watcher for include and exclude
36
- * The watcher in tsserver doesn't support astro file
37
- * It won't add new created astro file to root
38
- */
39
- setupWatchers() {
40
- for (const directory in this.parsedCommandLine.wildcardDirectories) {
41
- if (!Object.prototype.hasOwnProperty.call(this.parsedCommandLine.wildcardDirectories, directory)) {
42
- continue;
43
- }
44
- const watchDirectoryFlags = this.parsedCommandLine.wildcardDirectories[directory];
45
- const watcher = this.serverHost.watchDirectory(directory, this.watcherCallback.bind(this), watchDirectoryFlags === this.typescript.WatchDirectoryFlags.Recursive, this.parsedCommandLine.watchOptions);
46
- this.directoryWatchers.add(watcher);
47
- }
48
- }
49
- watcherCallback(fileName) {
50
- if (!(0, utils_1.isAstroFilePath)(fileName)) {
51
- return;
52
- }
53
- // We can't just add the file to the project directly, because
54
- // - the casing of fileName is different
55
- // - we don't know whether the file was added or deleted
56
- this.updateProjectAstroFiles();
57
- }
58
- updateProjectAstroFiles() {
59
- const fileNamesAfter = (0, utils_1.readProjectAstroFilesFromFs)(this.typescript, this.project, this.parsedCommandLine);
60
- const removedFiles = new Set(...this.files);
61
- const newFiles = fileNamesAfter.filter((fileName) => {
62
- const has = this.files.has(fileName);
63
- if (has) {
64
- removedFiles.delete(fileName);
65
- }
66
- return !has;
67
- });
68
- for (const newFile of newFiles) {
69
- this.addFileToProject(newFile);
70
- this.files.add(newFile);
71
- }
72
- for (const removedFile of removedFiles) {
73
- this.removeFileFromProject(removedFile, false);
74
- this.files.delete(removedFile);
75
- }
76
- }
77
- addFileToProject(newFile) {
78
- this.snapshotManager.create(newFile);
79
- const snapshot = this.project.projectService.getScriptInfo(newFile);
80
- if (snapshot) {
81
- this.project.addRoot(snapshot);
82
- }
83
- }
84
- removeFileFromProject(file, exists = true) {
85
- const info = this.project.getScriptInfo(file);
86
- if (info) {
87
- this.project.removeFile(info, exists, true);
88
- }
89
- }
90
- disposeWatchersAndFiles() {
91
- this.directoryWatchers.forEach((watcher) => watcher.close());
92
- this.directoryWatchers.clear();
93
- this.files.forEach((file) => this.removeFileFromProject(file));
94
- this.files.clear();
95
- }
96
- dispose() {
97
- this.disposeWatchersAndFiles();
98
- ProjectAstroFilesManager.instances.delete(this.project.getProjectName());
99
- }
100
- }
101
- exports.ProjectAstroFilesManager = ProjectAstroFilesManager;
102
- ProjectAstroFilesManager.instances = new Map();
package/dist/utils.d.ts DELETED
@@ -1,16 +0,0 @@
1
- import type ts from 'typescript/lib/tsserverlibrary';
2
- export declare function isAstroFilePath(filePath: string): boolean;
3
- export declare function isVirtualAstroFilePath(filePath: string): boolean;
4
- export declare function toRealAstroFilePath(filePath: string): string;
5
- export declare function ensureRealAstroFilePath(filePath: string): string;
6
- export declare function isNotNullOrUndefined<T>(val: T | undefined | null): val is T;
7
- /**
8
- * Replace all occurrences of a string within an object with another string,
9
- */
10
- export declare function replaceDeep<T extends Record<string, any>>(obj: T, searchStr: string | RegExp, replacementStr: string): T;
11
- export declare function getConfigPathForProject(project: ts.server.Project): ts.server.NormalizedPath;
12
- export declare function readProjectAstroFilesFromFs(ts: typeof import('typescript/lib/tsserverlibrary'), project: ts.server.Project, parsedCommandLine: ts.ParsedCommandLine): ts.server.NormalizedPath[];
13
- export interface TsFilesSpec {
14
- include?: readonly string[];
15
- exclude?: readonly string[];
16
- }
package/dist/utils.js DELETED
@@ -1,61 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readProjectAstroFilesFromFs = exports.getConfigPathForProject = exports.replaceDeep = exports.isNotNullOrUndefined = exports.ensureRealAstroFilePath = exports.toRealAstroFilePath = exports.isVirtualAstroFilePath = exports.isAstroFilePath = void 0;
4
- function isAstroFilePath(filePath) {
5
- return filePath.endsWith('.astro');
6
- }
7
- exports.isAstroFilePath = isAstroFilePath;
8
- function isVirtualAstroFilePath(filePath) {
9
- return filePath.endsWith('.astro.ts');
10
- }
11
- exports.isVirtualAstroFilePath = isVirtualAstroFilePath;
12
- function toRealAstroFilePath(filePath) {
13
- return filePath.slice(0, -'.ts'.length);
14
- }
15
- exports.toRealAstroFilePath = toRealAstroFilePath;
16
- function ensureRealAstroFilePath(filePath) {
17
- return isVirtualAstroFilePath(filePath) ? toRealAstroFilePath(filePath) : filePath;
18
- }
19
- exports.ensureRealAstroFilePath = ensureRealAstroFilePath;
20
- function isNotNullOrUndefined(val) {
21
- return val !== undefined && val !== null;
22
- }
23
- exports.isNotNullOrUndefined = isNotNullOrUndefined;
24
- /**
25
- * Replace all occurrences of a string within an object with another string,
26
- */
27
- function replaceDeep(obj, searchStr, replacementStr) {
28
- return _replaceDeep(obj);
29
- function _replaceDeep(_obj) {
30
- if (typeof _obj === 'string') {
31
- return _obj.replace(searchStr, replacementStr);
32
- }
33
- if (Array.isArray(_obj)) {
34
- return _obj.map((entry) => _replaceDeep(entry));
35
- }
36
- if (typeof _obj === 'object') {
37
- return Object.keys(_obj).reduce((_o, key) => {
38
- _o[key] = _replaceDeep(_obj[key]);
39
- return _o;
40
- }, {});
41
- }
42
- return _obj;
43
- }
44
- }
45
- exports.replaceDeep = replaceDeep;
46
- function getConfigPathForProject(project) {
47
- return (project.canonicalConfigFilePath ??
48
- project.getCompilerOptions().configFilePath);
49
- }
50
- exports.getConfigPathForProject = getConfigPathForProject;
51
- function readProjectAstroFilesFromFs(ts, project, parsedCommandLine) {
52
- const fileSpec = parsedCommandLine.raw;
53
- const { include, exclude } = fileSpec;
54
- if (include?.length === 0) {
55
- return [];
56
- }
57
- return ts.sys
58
- .readDirectory(project.getCurrentDirectory() || process.cwd(), ['.astro'], exclude, include)
59
- .map(ts.server.toNormalizedPath);
60
- }
61
- exports.readProjectAstroFilesFromFs = readProjectAstroFilesFromFs;