@astrojs/ts-plugin 1.0.10 → 1.1.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 +25 -1
- package/dist/astro2tsx.d.ts +15 -2
- package/dist/astro2tsx.js +121 -5
- package/dist/index.d.ts +1 -6
- package/dist/index.js +21 -47
- package/dist/language.d.ts +17 -0
- package/dist/language.js +47 -0
- package/package.json +6 -3
- package/dist/astro-snapshots.d.ts +0 -44
- package/dist/astro-snapshots.js +0 -234
- package/dist/astro-sys.d.ts +0 -6
- package/dist/astro-sys.js +0 -30
- package/dist/language-service/completions.d.ts +0 -3
- package/dist/language-service/completions.js +0 -45
- package/dist/language-service/definition.d.ts +0 -3
- package/dist/language-service/definition.js +0 -38
- package/dist/language-service/diagnostics.d.ts +0 -7
- package/dist/language-service/diagnostics.js +0 -62
- package/dist/language-service/file-references.d.ts +0 -3
- package/dist/language-service/file-references.js +0 -30
- package/dist/language-service/find-references.d.ts +0 -4
- package/dist/language-service/find-references.js +0 -66
- package/dist/language-service/implementation.d.ts +0 -3
- package/dist/language-service/implementation.js +0 -30
- package/dist/language-service/index.d.ts +0 -5
- package/dist/language-service/index.js +0 -44
- package/dist/language-service/line-column-offset.d.ts +0 -3
- package/dist/language-service/line-column-offset.js +0 -21
- package/dist/language-service/rename.d.ts +0 -4
- package/dist/language-service/rename.js +0 -34
- package/dist/logger.d.ts +0 -8
- package/dist/logger.js +0 -40
- package/dist/module-loader.d.ts +0 -13
- package/dist/module-loader.js +0 -146
- package/dist/project-astro-files.d.ts +0 -28
- package/dist/project-astro-files.js +0 -102
- package/dist/utils.d.ts +0 -16
- package/dist/utils.js +0 -61
package/README.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
1
|
# @astrojs/ts-plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Using the Astro VS Code extension? This plugin is automatically installed and configured for you.
|
|
4
|
+
|
|
5
|
+
TypeScript plugin adding support for `.astro` imports in `.ts` files. This plugin also adds support for renaming symbols and finding references across `.ts` and `.astro` files.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install --save-dev @astrojs/ts-plugin
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
Add the plugin to your `tsconfig.json`:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"compilerOptions": {
|
|
20
|
+
"plugins": [
|
|
21
|
+
{
|
|
22
|
+
"name": "@astrojs/ts-plugin"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
package/dist/astro2tsx.d.ts
CHANGED
|
@@ -1,2 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
export declare function astro2tsx(
|
|
1
|
+
import { VirtualFile } from '@volar/language-core';
|
|
2
|
+
export declare function astro2tsx(input: string, fileName: string, ts: typeof import('typescript/lib/tsserverlibrary.js')): {
|
|
3
|
+
virtualFile: VirtualFile;
|
|
4
|
+
diagnostics: import("@astrojs/compiler").DiagnosticMessage[] | {
|
|
5
|
+
code: 1000;
|
|
6
|
+
location: {
|
|
7
|
+
file: string;
|
|
8
|
+
line: number;
|
|
9
|
+
column: number;
|
|
10
|
+
length: number;
|
|
11
|
+
};
|
|
12
|
+
severity: 1;
|
|
13
|
+
text: string;
|
|
14
|
+
}[];
|
|
15
|
+
};
|
package/dist/astro2tsx.js
CHANGED
|
@@ -1,26 +1,142 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.astro2tsx = void 0;
|
|
4
7
|
const sync_1 = require("@astrojs/compiler/sync");
|
|
5
|
-
|
|
8
|
+
const sourcemap_codec_1 = require("@jridgewell/sourcemap-codec");
|
|
9
|
+
const language_core_1 = require("@volar/language-core");
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
|
|
12
|
+
function safeConvertToTSX(content, options) {
|
|
6
13
|
try {
|
|
7
|
-
const tsx = (0, sync_1.convertToTSX)(content, { filename:
|
|
14
|
+
const tsx = (0, sync_1.convertToTSX)(content, { filename: options.filename });
|
|
8
15
|
return tsx;
|
|
9
16
|
}
|
|
10
17
|
catch (e) {
|
|
11
|
-
console.error(`There was an error transforming ${
|
|
18
|
+
console.error(`There was an error transforming ${options.filename} to TSX. An empty file will be returned instead. Please create an issue: https://github.com/withastro/language-tools/issues\nError: ${e}.`);
|
|
12
19
|
return {
|
|
13
20
|
code: '',
|
|
14
21
|
map: {
|
|
15
|
-
file:
|
|
22
|
+
file: options.filename ?? '',
|
|
16
23
|
sources: [],
|
|
17
24
|
sourcesContent: [],
|
|
18
25
|
names: [],
|
|
19
26
|
mappings: '',
|
|
20
27
|
version: 0,
|
|
21
28
|
},
|
|
22
|
-
diagnostics: [
|
|
29
|
+
diagnostics: [
|
|
30
|
+
{
|
|
31
|
+
code: 1000,
|
|
32
|
+
location: { file: options.filename, line: 1, column: 1, length: content.length },
|
|
33
|
+
severity: 1,
|
|
34
|
+
text: `The Astro compiler encountered an unknown error while parsing this file. Please create an issue with your code and the error shown in the server's logs: https://github.com/withastro/language-tools/issues`,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
23
37
|
};
|
|
24
38
|
}
|
|
25
39
|
}
|
|
40
|
+
function astro2tsx(input, fileName, ts) {
|
|
41
|
+
const tsx = safeConvertToTSX(input, { filename: fileName });
|
|
42
|
+
return {
|
|
43
|
+
virtualFile: getVirtualFileTSX(input, tsx, fileName, ts),
|
|
44
|
+
diagnostics: tsx.diagnostics,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
26
47
|
exports.astro2tsx = astro2tsx;
|
|
48
|
+
function getVirtualFileTSX(input, tsx, fileName, ts) {
|
|
49
|
+
tsx.code = patchTSX(tsx.code, fileName);
|
|
50
|
+
const v3Mappings = (0, sourcemap_codec_1.decode)(tsx.map.mappings);
|
|
51
|
+
const sourcedDoc = vscode_languageserver_textdocument_1.TextDocument.create(fileName, 'astro', 0, input);
|
|
52
|
+
const genDoc = vscode_languageserver_textdocument_1.TextDocument.create(fileName + '.tsx', 'typescriptreact', 0, tsx.code);
|
|
53
|
+
const mappings = [];
|
|
54
|
+
let current;
|
|
55
|
+
for (let genLine = 0; genLine < v3Mappings.length; genLine++) {
|
|
56
|
+
for (const segment of v3Mappings[genLine]) {
|
|
57
|
+
const genCharacter = segment[0];
|
|
58
|
+
const genOffset = genDoc.offsetAt({ line: genLine, character: genCharacter });
|
|
59
|
+
if (current) {
|
|
60
|
+
let length = genOffset - current.genOffset;
|
|
61
|
+
const sourceText = input.substring(current.sourceOffset, current.sourceOffset + length);
|
|
62
|
+
const genText = tsx.code.substring(current.genOffset, current.genOffset + length);
|
|
63
|
+
if (sourceText !== genText) {
|
|
64
|
+
length = 0;
|
|
65
|
+
for (let i = 0; i < genOffset - current.genOffset; i++) {
|
|
66
|
+
if (sourceText[i] === genText[i]) {
|
|
67
|
+
length = i + 1;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (length > 0) {
|
|
75
|
+
const lastMapping = mappings.length ? mappings[mappings.length - 1] : undefined;
|
|
76
|
+
if (lastMapping &&
|
|
77
|
+
lastMapping.generatedRange[1] === current.genOffset &&
|
|
78
|
+
lastMapping.sourceRange[1] === current.sourceOffset) {
|
|
79
|
+
lastMapping.generatedRange[1] = current.genOffset + length;
|
|
80
|
+
lastMapping.sourceRange[1] = current.sourceOffset + length;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
mappings.push({
|
|
84
|
+
sourceRange: [current.sourceOffset, current.sourceOffset + length],
|
|
85
|
+
generatedRange: [current.genOffset, current.genOffset + length],
|
|
86
|
+
data: language_core_1.FileRangeCapabilities.full,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
current = undefined;
|
|
91
|
+
}
|
|
92
|
+
if (segment[2] !== undefined && segment[3] !== undefined) {
|
|
93
|
+
const sourceOffset = sourcedDoc.offsetAt({ line: segment[2], character: segment[3] });
|
|
94
|
+
current = {
|
|
95
|
+
genOffset,
|
|
96
|
+
sourceOffset,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const ast = ts.createSourceFile('/a.tsx', tsx.code, ts.ScriptTarget.ESNext);
|
|
102
|
+
if (ast.statements[0]) {
|
|
103
|
+
mappings.push({
|
|
104
|
+
sourceRange: [0, input.length],
|
|
105
|
+
generatedRange: [ast.statements[0].getStart(ast), tsx.code.length],
|
|
106
|
+
data: {},
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
fileName: fileName + '.tsx',
|
|
111
|
+
kind: language_core_1.FileKind.TypeScriptHostFile,
|
|
112
|
+
capabilities: {
|
|
113
|
+
codeAction: true,
|
|
114
|
+
documentFormatting: false,
|
|
115
|
+
diagnostic: true,
|
|
116
|
+
documentSymbol: true,
|
|
117
|
+
inlayHint: true,
|
|
118
|
+
foldingRange: true,
|
|
119
|
+
},
|
|
120
|
+
codegenStacks: [],
|
|
121
|
+
snapshot: {
|
|
122
|
+
getText: (start, end) => tsx.code.substring(start, end),
|
|
123
|
+
getLength: () => tsx.code.length,
|
|
124
|
+
getChangeRange: () => undefined,
|
|
125
|
+
},
|
|
126
|
+
mappings: mappings,
|
|
127
|
+
embeddedFiles: [],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function patchTSX(code, fileName) {
|
|
131
|
+
const basename = node_path_1.default.basename(fileName, node_path_1.default.extname(fileName));
|
|
132
|
+
const isDynamic = basename.startsWith('[') && basename.endsWith(']');
|
|
133
|
+
return code.replace(/\b(\S*)__AstroComponent_/gm, (fullMatch, m1) => {
|
|
134
|
+
// If we don't have a match here, it usually means the file has a weird name that couldn't be expressed with valid identifier characters
|
|
135
|
+
if (!m1) {
|
|
136
|
+
if (basename === '404')
|
|
137
|
+
return 'FourOhFour';
|
|
138
|
+
return fullMatch;
|
|
139
|
+
}
|
|
140
|
+
return isDynamic ? `_${m1}_` : m1[0].toUpperCase() + m1.slice(1);
|
|
141
|
+
});
|
|
142
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
1
|
import type ts from 'typescript/lib/tsserverlibrary';
|
|
2
|
-
declare
|
|
3
|
-
typescript: typeof import('typescript/lib/tsserverlibrary');
|
|
4
|
-
}): {
|
|
5
|
-
create: (info: ts.server.PluginCreateInfo) => ts.LanguageService;
|
|
6
|
-
getExternalFiles: (project: ts.server.ConfiguredProject) => string[];
|
|
7
|
-
};
|
|
2
|
+
declare const init: ts.server.PluginModuleFactory;
|
|
8
3
|
export = init;
|
package/dist/index.js
CHANGED
|
@@ -1,50 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (!isAstroProject(info.project, parsedCommandLine)) {
|
|
14
|
-
logger.log('Detected that this is not an Astro project, abort patching TypeScript');
|
|
2
|
+
const language_core_1 = require("@volar/language-core");
|
|
3
|
+
const typescript_1 = require("@volar/typescript");
|
|
4
|
+
const language_js_1 = require("./language.js");
|
|
5
|
+
const externalFiles = new WeakMap();
|
|
6
|
+
const init = (modules) => {
|
|
7
|
+
const { typescript: ts } = modules;
|
|
8
|
+
const pluginModule = {
|
|
9
|
+
create(info) {
|
|
10
|
+
const virtualFiles = (0, language_core_1.createVirtualFiles)([(0, language_js_1.getLanguageModule)(ts)]);
|
|
11
|
+
(0, typescript_1.decorateLanguageService)(virtualFiles, info.languageService, true);
|
|
12
|
+
(0, typescript_1.decorateLanguageServiceHost)(virtualFiles, info.languageServiceHost, ts, ['.astro']);
|
|
15
13
|
return info.languageService;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return (0, index_js_1.decorateLanguageService)(info.languageService, snapshotManager, ts, logger);
|
|
27
|
-
}
|
|
28
|
-
function getExternalFiles(project) {
|
|
29
|
-
return project_astro_files_js_1.ProjectAstroFilesManager.getInstance(project.getProjectName())?.getFiles() ?? [];
|
|
30
|
-
}
|
|
31
|
-
function isAstroProject(project, parsedCommandLine) {
|
|
32
|
-
if (parsedCommandLine) {
|
|
33
|
-
const astroFiles = (0, utils_js_1.readProjectAstroFilesFromFs)(ts, project, parsedCommandLine);
|
|
34
|
-
if (astroFiles.length > 0)
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
try {
|
|
38
|
-
const compilerOptions = project.getCompilerOptions();
|
|
39
|
-
const hasAstroInstalled = typeof compilerOptions.configFilePath !== 'string' ||
|
|
40
|
-
require.resolve('astro', { paths: [compilerOptions.configFilePath] });
|
|
41
|
-
return hasAstroInstalled;
|
|
42
|
-
}
|
|
43
|
-
catch (e) {
|
|
44
|
-
project.projectService.logger.info(e);
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return { create, getExternalFiles };
|
|
49
|
-
}
|
|
14
|
+
},
|
|
15
|
+
getExternalFiles(project) {
|
|
16
|
+
if (!externalFiles.has(project)) {
|
|
17
|
+
externalFiles.set(project, (0, typescript_1.getExternalFiles)(ts, project, ['.astro']));
|
|
18
|
+
}
|
|
19
|
+
return externalFiles.get(project);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
return pluginModule;
|
|
23
|
+
};
|
|
50
24
|
module.exports = init;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FileCapabilities, FileKind, type Language, type VirtualFile } from '@volar/language-core';
|
|
2
|
+
import type ts from 'typescript/lib/tsserverlibrary.js';
|
|
3
|
+
export declare function getLanguageModule(ts: typeof import('typescript/lib/tsserverlibrary.js')): Language<AstroFile>;
|
|
4
|
+
export declare class AstroFile implements VirtualFile {
|
|
5
|
+
sourceFileName: string;
|
|
6
|
+
snapshot: ts.IScriptSnapshot;
|
|
7
|
+
private readonly ts;
|
|
8
|
+
kind: FileKind;
|
|
9
|
+
capabilities: FileCapabilities;
|
|
10
|
+
fileName: string;
|
|
11
|
+
mappings: VirtualFile['mappings'];
|
|
12
|
+
embeddedFiles: VirtualFile['embeddedFiles'];
|
|
13
|
+
codegenStacks: never[];
|
|
14
|
+
constructor(sourceFileName: string, snapshot: ts.IScriptSnapshot, ts: typeof import('typescript/lib/tsserverlibrary.js'));
|
|
15
|
+
update(newSnapshot: ts.IScriptSnapshot): void;
|
|
16
|
+
onSnapshotUpdated(): void;
|
|
17
|
+
}
|
package/dist/language.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AstroFile = exports.getLanguageModule = void 0;
|
|
4
|
+
const language_core_1 = require("@volar/language-core");
|
|
5
|
+
const astro2tsx_js_1 = require("./astro2tsx.js");
|
|
6
|
+
function getLanguageModule(ts) {
|
|
7
|
+
return {
|
|
8
|
+
createVirtualFile(fileName, snapshot) {
|
|
9
|
+
if (fileName.endsWith('.astro')) {
|
|
10
|
+
return new AstroFile(fileName, snapshot, ts);
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
updateVirtualFile(astroFile, snapshot) {
|
|
14
|
+
astroFile.update(snapshot);
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
exports.getLanguageModule = getLanguageModule;
|
|
19
|
+
class AstroFile {
|
|
20
|
+
constructor(sourceFileName, snapshot, ts) {
|
|
21
|
+
this.sourceFileName = sourceFileName;
|
|
22
|
+
this.snapshot = snapshot;
|
|
23
|
+
this.ts = ts;
|
|
24
|
+
this.kind = language_core_1.FileKind.TextFile;
|
|
25
|
+
this.capabilities = language_core_1.FileCapabilities.full;
|
|
26
|
+
this.codegenStacks = [];
|
|
27
|
+
this.fileName = sourceFileName;
|
|
28
|
+
this.onSnapshotUpdated();
|
|
29
|
+
}
|
|
30
|
+
update(newSnapshot) {
|
|
31
|
+
this.snapshot = newSnapshot;
|
|
32
|
+
this.onSnapshotUpdated();
|
|
33
|
+
}
|
|
34
|
+
onSnapshotUpdated() {
|
|
35
|
+
this.mappings = [
|
|
36
|
+
{
|
|
37
|
+
sourceRange: [0, this.snapshot.getLength()],
|
|
38
|
+
generatedRange: [0, this.snapshot.getLength()],
|
|
39
|
+
data: language_core_1.FileRangeCapabilities.full,
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
this.embeddedFiles = [];
|
|
43
|
+
const tsx = (0, astro2tsx_js_1.astro2tsx)(this.snapshot.getText(0, this.snapshot.getLength()), this.fileName, this.ts);
|
|
44
|
+
this.embeddedFiles.push(tsx.virtualFile);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.AstroFile = AstroFile;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/ts-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "A TypeScript Plugin providing Astro intellisense",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -22,8 +22,11 @@
|
|
|
22
22
|
"author": "withastro",
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@
|
|
26
|
-
"@
|
|
25
|
+
"@volar/language-core": "~1.10.0",
|
|
26
|
+
"@volar/typescript": "~1.10.0",
|
|
27
|
+
"@astrojs/compiler": "1.5.7",
|
|
28
|
+
"@jridgewell/sourcemap-codec": "^1.4.15",
|
|
29
|
+
"vscode-languageserver-textdocument": "^1.0.8"
|
|
27
30
|
},
|
|
28
31
|
"devDependencies": {
|
|
29
32
|
"@types/chai": "^4.3.5",
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { TraceMap } from '@jridgewell/trace-mapping';
|
|
2
|
-
import type ts from 'typescript/lib/tsserverlibrary';
|
|
3
|
-
import type { Logger } from './logger.js';
|
|
4
|
-
export declare class AstroSnapshot {
|
|
5
|
-
private typescript;
|
|
6
|
-
private fileName;
|
|
7
|
-
private astroCode;
|
|
8
|
-
private traceMap;
|
|
9
|
-
private logger;
|
|
10
|
-
private scriptInfo?;
|
|
11
|
-
private lineOffsets?;
|
|
12
|
-
private convertInternalCodePositions;
|
|
13
|
-
constructor(typescript: typeof ts, fileName: string, astroCode: string, traceMap: TraceMap, logger: Logger);
|
|
14
|
-
update(astroCode: string, traceMap: TraceMap): void;
|
|
15
|
-
getOriginalTextSpan(textSpan: ts.TextSpan): ts.TextSpan | null;
|
|
16
|
-
getOriginalOffset(generatedOffset: number): number;
|
|
17
|
-
setAndPatchScriptInfo(scriptInfo: ts.server.ScriptInfo): void;
|
|
18
|
-
/**
|
|
19
|
-
* Get the line and character based on the offset
|
|
20
|
-
* @param offset The index of the position
|
|
21
|
-
*/
|
|
22
|
-
positionAt(offset: number): ts.LineAndCharacter;
|
|
23
|
-
/**
|
|
24
|
-
* Get the index of the line and character position
|
|
25
|
-
* @param position Line and character position
|
|
26
|
-
*/
|
|
27
|
-
offsetAt(position: ts.LineAndCharacter): number;
|
|
28
|
-
private getLineOffsets;
|
|
29
|
-
private clamp;
|
|
30
|
-
private log;
|
|
31
|
-
private debug;
|
|
32
|
-
private toggleMappingMode;
|
|
33
|
-
private getText;
|
|
34
|
-
}
|
|
35
|
-
export declare class AstroSnapshotManager {
|
|
36
|
-
private typescript;
|
|
37
|
-
private projectService;
|
|
38
|
-
private logger;
|
|
39
|
-
private snapshots;
|
|
40
|
-
constructor(typescript: typeof ts, projectService: ts.server.ProjectService, logger: Logger);
|
|
41
|
-
get(fileName: string): AstroSnapshot | undefined;
|
|
42
|
-
create(fileName: string): AstroSnapshot | undefined;
|
|
43
|
-
private patchProjectServiceReadFile;
|
|
44
|
-
}
|
package/dist/astro-snapshots.js
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AstroSnapshotManager = exports.AstroSnapshot = void 0;
|
|
4
|
-
const trace_mapping_1 = require("@jridgewell/trace-mapping");
|
|
5
|
-
const astro2tsx_js_1 = require("./astro2tsx.js");
|
|
6
|
-
const utils_js_1 = require("./utils.js");
|
|
7
|
-
class AstroSnapshot {
|
|
8
|
-
constructor(typescript, fileName, astroCode, traceMap, logger) {
|
|
9
|
-
this.typescript = typescript;
|
|
10
|
-
this.fileName = fileName;
|
|
11
|
-
this.astroCode = astroCode;
|
|
12
|
-
this.traceMap = traceMap;
|
|
13
|
-
this.logger = logger;
|
|
14
|
-
this.convertInternalCodePositions = false;
|
|
15
|
-
}
|
|
16
|
-
update(astroCode, traceMap) {
|
|
17
|
-
this.astroCode = astroCode;
|
|
18
|
-
this.traceMap = traceMap;
|
|
19
|
-
this.lineOffsets = undefined;
|
|
20
|
-
this.log('Updated Snapshot');
|
|
21
|
-
}
|
|
22
|
-
getOriginalTextSpan(textSpan) {
|
|
23
|
-
const start = this.getOriginalOffset(textSpan.start);
|
|
24
|
-
if (start === -1) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
// Assumption: We don't change identifiers itself, so we don't change ranges.
|
|
28
|
-
return {
|
|
29
|
-
start,
|
|
30
|
-
length: textSpan.length,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
getOriginalOffset(generatedOffset) {
|
|
34
|
-
if (!this.scriptInfo) {
|
|
35
|
-
return generatedOffset;
|
|
36
|
-
}
|
|
37
|
-
this.toggleMappingMode(true);
|
|
38
|
-
const lineOffset = this.scriptInfo.positionToLineOffset(generatedOffset);
|
|
39
|
-
this.debug('try convert offset', generatedOffset, '/', lineOffset);
|
|
40
|
-
const original = (0, trace_mapping_1.originalPositionFor)(this.traceMap, {
|
|
41
|
-
line: lineOffset.line,
|
|
42
|
-
column: lineOffset.offset,
|
|
43
|
-
});
|
|
44
|
-
this.toggleMappingMode(false);
|
|
45
|
-
if (!original.line) {
|
|
46
|
-
return -1;
|
|
47
|
-
}
|
|
48
|
-
const originalOffset = this.scriptInfo.lineOffsetToPosition(original.line, original.column);
|
|
49
|
-
this.debug('converted offset to', original, '/', originalOffset);
|
|
50
|
-
return originalOffset;
|
|
51
|
-
}
|
|
52
|
-
setAndPatchScriptInfo(scriptInfo) {
|
|
53
|
-
// @ts-expect-error
|
|
54
|
-
scriptInfo.scriptKind = this.typescript.ScriptKind.TSX;
|
|
55
|
-
const positionToLineOffset = scriptInfo.positionToLineOffset.bind(scriptInfo);
|
|
56
|
-
scriptInfo.positionToLineOffset = (position) => {
|
|
57
|
-
if (this.convertInternalCodePositions) {
|
|
58
|
-
const lineOffset = positionToLineOffset(position);
|
|
59
|
-
this.debug('positionToLineOffset for generated code', position, lineOffset);
|
|
60
|
-
return lineOffset;
|
|
61
|
-
}
|
|
62
|
-
const lineOffset = this.positionAt(position);
|
|
63
|
-
this.debug('positionToLineOffset for original code', position, lineOffset);
|
|
64
|
-
return { line: lineOffset.line + 1, offset: lineOffset.character + 1 };
|
|
65
|
-
};
|
|
66
|
-
const lineOffsetToPosition = scriptInfo.lineOffsetToPosition.bind(scriptInfo);
|
|
67
|
-
scriptInfo.lineOffsetToPosition = (line, offset) => {
|
|
68
|
-
if (this.convertInternalCodePositions) {
|
|
69
|
-
const position = lineOffsetToPosition(line, offset);
|
|
70
|
-
this.debug('lineOffsetToPosition for generated code', { line, offset }, position);
|
|
71
|
-
return position;
|
|
72
|
-
}
|
|
73
|
-
const position = this.offsetAt({ line: line - 1, character: offset - 1 });
|
|
74
|
-
this.debug('lineOffsetToPosition for original code', { line, offset }, position);
|
|
75
|
-
return position;
|
|
76
|
-
};
|
|
77
|
-
this.scriptInfo = scriptInfo;
|
|
78
|
-
this.log('patched scriptInfo');
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Get the line and character based on the offset
|
|
82
|
-
* @param offset The index of the position
|
|
83
|
-
*/
|
|
84
|
-
positionAt(offset) {
|
|
85
|
-
offset = this.clamp(offset, 0, this.astroCode.length);
|
|
86
|
-
const lineOffsets = this.getLineOffsets();
|
|
87
|
-
let low = 0;
|
|
88
|
-
let high = lineOffsets.length;
|
|
89
|
-
if (high === 0) {
|
|
90
|
-
return { line: 0, character: offset };
|
|
91
|
-
}
|
|
92
|
-
while (low < high) {
|
|
93
|
-
const mid = Math.floor((low + high) / 2);
|
|
94
|
-
if (lineOffsets[mid] > offset) {
|
|
95
|
-
high = mid;
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
low = mid + 1;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// low is the least x for which the line offset is larger than the current offset
|
|
102
|
-
// or array.length if no line offset is larger than the current offset
|
|
103
|
-
const line = low - 1;
|
|
104
|
-
return { line, character: offset - lineOffsets[line] };
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Get the index of the line and character position
|
|
108
|
-
* @param position Line and character position
|
|
109
|
-
*/
|
|
110
|
-
offsetAt(position) {
|
|
111
|
-
const lineOffsets = this.getLineOffsets();
|
|
112
|
-
if (position.line >= lineOffsets.length) {
|
|
113
|
-
return this.astroCode.length;
|
|
114
|
-
}
|
|
115
|
-
else if (position.line < 0) {
|
|
116
|
-
return 0;
|
|
117
|
-
}
|
|
118
|
-
const lineOffset = lineOffsets[position.line];
|
|
119
|
-
const nextLineOffset = position.line + 1 < lineOffsets.length
|
|
120
|
-
? lineOffsets[position.line + 1]
|
|
121
|
-
: this.astroCode.length;
|
|
122
|
-
return this.clamp(nextLineOffset, lineOffset, lineOffset + position.character);
|
|
123
|
-
}
|
|
124
|
-
getLineOffsets() {
|
|
125
|
-
if (this.lineOffsets) {
|
|
126
|
-
return this.lineOffsets;
|
|
127
|
-
}
|
|
128
|
-
const lineOffsets = [];
|
|
129
|
-
const text = this.astroCode;
|
|
130
|
-
let isLineStart = true;
|
|
131
|
-
for (let i = 0; i < text.length; i++) {
|
|
132
|
-
if (isLineStart) {
|
|
133
|
-
lineOffsets.push(i);
|
|
134
|
-
isLineStart = false;
|
|
135
|
-
}
|
|
136
|
-
const ch = text.charAt(i);
|
|
137
|
-
isLineStart = ch === '\r' || ch === '\n';
|
|
138
|
-
if (ch === '\r' && i + 1 < text.length && text.charAt(i + 1) === '\n') {
|
|
139
|
-
i++;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (isLineStart && text.length > 0) {
|
|
143
|
-
lineOffsets.push(text.length);
|
|
144
|
-
}
|
|
145
|
-
this.lineOffsets = lineOffsets;
|
|
146
|
-
return lineOffsets;
|
|
147
|
-
}
|
|
148
|
-
clamp(num, min, max) {
|
|
149
|
-
return Math.max(min, Math.min(max, num));
|
|
150
|
-
}
|
|
151
|
-
log(...args) {
|
|
152
|
-
this.logger.log('AstroSnapshot:', this.fileName, '-', ...args);
|
|
153
|
-
}
|
|
154
|
-
debug(...args) {
|
|
155
|
-
this.logger.debug('AstroSnapshot:', this.fileName, '-', ...args);
|
|
156
|
-
}
|
|
157
|
-
toggleMappingMode(convertInternalCodePositions) {
|
|
158
|
-
this.convertInternalCodePositions = convertInternalCodePositions;
|
|
159
|
-
}
|
|
160
|
-
getText() {
|
|
161
|
-
const snapshot = this.scriptInfo?.getSnapshot();
|
|
162
|
-
if (!snapshot) {
|
|
163
|
-
return '';
|
|
164
|
-
}
|
|
165
|
-
return snapshot.getText(0, snapshot.getLength());
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
exports.AstroSnapshot = AstroSnapshot;
|
|
169
|
-
class AstroSnapshotManager {
|
|
170
|
-
constructor(typescript, projectService, logger) {
|
|
171
|
-
this.typescript = typescript;
|
|
172
|
-
this.projectService = projectService;
|
|
173
|
-
this.logger = logger;
|
|
174
|
-
this.snapshots = new Map();
|
|
175
|
-
this.patchProjectServiceReadFile();
|
|
176
|
-
}
|
|
177
|
-
get(fileName) {
|
|
178
|
-
return this.snapshots.get(fileName);
|
|
179
|
-
}
|
|
180
|
-
create(fileName) {
|
|
181
|
-
if (this.snapshots.has(fileName)) {
|
|
182
|
-
return this.snapshots.get(fileName);
|
|
183
|
-
}
|
|
184
|
-
// This will trigger projectService.host.readFile which is patched below
|
|
185
|
-
const scriptInfo = this.projectService.getOrCreateScriptInfoForNormalizedPath(this.typescript.server.toNormalizedPath(fileName), false);
|
|
186
|
-
if (!scriptInfo) {
|
|
187
|
-
this.logger.log('Was not able get snapshot for', fileName);
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
try {
|
|
191
|
-
scriptInfo.getSnapshot(); // needed to trigger readFile
|
|
192
|
-
}
|
|
193
|
-
catch (e) {
|
|
194
|
-
this.logger.log('Loading Snapshot failed', fileName);
|
|
195
|
-
}
|
|
196
|
-
const snapshot = this.snapshots.get(fileName);
|
|
197
|
-
if (!snapshot) {
|
|
198
|
-
this.logger.log('Astro snapshot was not found after trying to load script snapshot for', fileName);
|
|
199
|
-
return; // should never get here
|
|
200
|
-
}
|
|
201
|
-
snapshot.setAndPatchScriptInfo(scriptInfo);
|
|
202
|
-
this.snapshots.set(fileName, snapshot);
|
|
203
|
-
return snapshot;
|
|
204
|
-
}
|
|
205
|
-
patchProjectServiceReadFile() {
|
|
206
|
-
const readFile = this.projectService.host.readFile;
|
|
207
|
-
this.projectService.host.readFile = (path) => {
|
|
208
|
-
if ((0, utils_js_1.isAstroFilePath)(path)) {
|
|
209
|
-
this.logger.debug('Read Astro file:', path);
|
|
210
|
-
const astroCode = readFile(path) || '';
|
|
211
|
-
try {
|
|
212
|
-
const result = (0, astro2tsx_js_1.astro2tsx)(astroCode, path);
|
|
213
|
-
const existingSnapshot = this.snapshots.get(path);
|
|
214
|
-
if (existingSnapshot) {
|
|
215
|
-
existingSnapshot.update(astroCode, new trace_mapping_1.TraceMap(result.map));
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
this.snapshots.set(path, new AstroSnapshot(this.typescript, path, astroCode, new trace_mapping_1.TraceMap(result.map), this.logger));
|
|
219
|
-
}
|
|
220
|
-
this.logger.log('Successfully read Astro file contents of', path);
|
|
221
|
-
return result.code;
|
|
222
|
-
}
|
|
223
|
-
catch (e) {
|
|
224
|
-
this.logger.log('Error loading Astro file:', path);
|
|
225
|
-
this.logger.debug('Error:', e);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
return readFile(path);
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
exports.AstroSnapshotManager = AstroSnapshotManager;
|
package/dist/astro-sys.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type ts from 'typescript/lib/tsserverlibrary';
|
|
2
|
-
import type { Logger } from './logger.js';
|
|
3
|
-
/**
|
|
4
|
-
* This should only be accessed by TS astro module resolution.
|
|
5
|
-
*/
|
|
6
|
-
export declare function createAstroSys(logger: Logger, typescript: typeof import('typescript/lib/tsserverlibrary')): ts.System;
|