@astrojs/ts-plugin 0.2.1 → 0.3.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.
package/src/astro2tsx.ts CHANGED
@@ -1,53 +1,49 @@
1
1
  import type { FileMapping } from './source-mapper';
2
- import { Project } from 'ts-morph';
3
2
 
4
3
  // Note that this is a bit of a hack until the new compiler with proper
5
4
  // source map support.
6
5
 
7
6
  interface Astro2TSXOptions {
8
- filename: string | undefined;
9
- isTsFile: boolean;
7
+ filename: string | undefined;
8
+ isTsFile: boolean;
10
9
  }
11
10
 
12
11
  interface Astro2TSXResult {
13
- code: string;
14
- map: {
15
- mappings: FileMapping
16
- }
12
+ code: string;
13
+ map: {
14
+ mappings: FileMapping;
15
+ };
17
16
  }
18
17
 
19
18
  export function astro2tsx(code: string, options: Astro2TSXOptions): Astro2TSXResult {
20
- const compiled = transformContent(code);
19
+ const compiled = transformContent(code);
21
20
 
22
- const result: Astro2TSXResult = {
23
- code: compiled,
24
- map: {
25
- mappings: []
26
- }
27
- };
21
+ const result: Astro2TSXResult = {
22
+ code: compiled,
23
+ map: {
24
+ mappings: [],
25
+ },
26
+ };
28
27
 
29
- return result;
28
+ return result;
30
29
  }
31
30
 
32
31
  // This is hacky but it works for now
33
32
  function addProps(content: string): string {
34
- let defaultExportType = 'Record<string, any>';
35
-
36
- // See if this has an interface already
37
- const project = new Project({});
38
- const sourceFile = project.createSourceFile("testing.ts", content);
39
- const declarations = sourceFile.getExportedDeclarations();
40
- if(declarations.has('Props')) {
41
- defaultExportType = 'Props';
42
- }
43
- return '\n' + `export default function (props: ${defaultExportType}): string;`
33
+ let defaultExportType = 'Record<string, any>';
34
+
35
+ if (/(interface|type) Props/.test(content)) {
36
+ defaultExportType = 'Props';
37
+ }
38
+
39
+ return '\n' + `export default function (props: ${defaultExportType}): string;`;
44
40
  }
45
41
 
46
42
  function transformContent(content: string) {
47
- const ts = content.replace(/---/g, '///');
48
- return (
49
- ts +
50
- // Add TypeScript definitions
51
- addProps(ts)
52
- );
43
+ const ts = content.replace(/---/g, '///');
44
+ return (
45
+ ts +
46
+ // Add TypeScript definitions
47
+ addProps(ts)
48
+ );
53
49
  }
package/src/index.ts CHANGED
@@ -1,76 +1,65 @@
1
1
  import type ts from 'typescript/lib/tsserverlibrary';
2
- import { dirname, resolve } from 'path';
2
+ import { AstroSnapshotManager } from './astro-snapshots.js';
3
3
  import { decorateLanguageService } from './language-service/index.js';
4
4
  import { Logger } from './logger.js';
5
5
  import { patchModuleLoader } from './module-loader.js';
6
- import { AstroSnapshotManager } from './astro-snapshots.js';
7
6
 
8
7
  function init(modules: { typescript: typeof ts }) {
9
- function create(info: ts.server.PluginCreateInfo) {
10
- const logger = new Logger(info.project.projectService.logger);
8
+ function create(info: ts.server.PluginCreateInfo) {
9
+ const logger = new Logger(info.project.projectService.logger);
11
10
 
12
- if (!isAstroProject(info)) {
13
- logger.log('Detected that this is not an Astro project, abort patching TypeScript');
14
- return info.languageService;
15
- }
11
+ if (!isAstroProject(info)) {
12
+ logger.log('Detected that this is not an Astro project, abort patching TypeScript');
13
+ return info.languageService;
14
+ }
16
15
 
17
- logger.log('Starting Astro plugin');
16
+ logger.log('Starting Astro plugin');
18
17
 
19
- const snapshotManager = new AstroSnapshotManager(
20
- modules.typescript,
21
- info.project.projectService,
22
- logger
23
- );
18
+ const snapshotManager = new AstroSnapshotManager(modules.typescript, info.project.projectService, logger);
24
19
 
25
- patchCompilerOptions(info.project);
26
- patchModuleLoader(
27
- logger,
28
- snapshotManager,
29
- modules.typescript,
30
- info.languageServiceHost,
31
- info.project
32
- );
33
- return decorateLanguageService(info.languageService, snapshotManager, logger);
34
- }
20
+ patchCompilerOptions(info.project);
21
+ patchModuleLoader(logger, snapshotManager, modules.typescript, info.languageServiceHost, info.project);
22
+ return decorateLanguageService(info.languageService, snapshotManager, logger);
23
+ }
35
24
 
36
- function getExternalFiles(_project: ts.server.ConfiguredProject) {
37
- // Needed so the ambient definitions are known inside the tsx files
38
- /*const astroTsPath = dirname(require.resolve('astro2tsx'));
25
+ function getExternalFiles(_project: ts.server.ConfiguredProject) {
26
+ // Needed so the ambient definitions are known inside the tsx files
27
+ /*const astroTsPath = dirname(require.resolve('astro2tsx'));
39
28
  const astroTsxFiles = [
40
29
  './astro-shims.d.ts',
41
30
  './astro-jsx.d.ts',
42
31
  './astro-native-jsx.d.ts'
43
32
  ].map((f) => modules.typescript.sys.resolvePath(resolve(astroTsPath, f)));
44
33
  return astroTsxFiles;*/
45
- return [];
46
- }
34
+ return [];
35
+ }
47
36
 
48
- function patchCompilerOptions(project: ts.server.Project) {
49
- const compilerOptions = project.getCompilerOptions();
50
- // Patch needed because astro2tsx creates jsx/tsx files
51
- compilerOptions.jsx = modules.typescript.JsxEmit.Preserve;
37
+ function patchCompilerOptions(project: ts.server.Project) {
38
+ const compilerOptions = project.getCompilerOptions();
39
+ // Patch needed because astro2tsx creates jsx/tsx files
40
+ compilerOptions.jsx = modules.typescript.JsxEmit.Preserve;
52
41
 
53
- // detect which JSX namespace to use (astro | astronative) if not specified or not compatible
54
- if (!compilerOptions.jsxFactory?.startsWith('astro')) {
55
- // Default to regular astro, this causes the usage of the "astro.JSX" namespace
56
- // We don't need to add a switch for astro-native because the jsx is only relevant
57
- // within Astro files, which this plugin does not deal with.
58
- compilerOptions.jsxFactory = 'astro.createElement';
59
- }
60
- }
42
+ // detect which JSX namespace to use (astro | astronative) if not specified or not compatible
43
+ if (!compilerOptions.jsxFactory?.startsWith('astro')) {
44
+ // Default to regular astro, this causes the usage of the "astro.JSX" namespace
45
+ // We don't need to add a switch for astro-native because the jsx is only relevant
46
+ // within Astro files, which this plugin does not deal with.
47
+ compilerOptions.jsxFactory = 'astro.createElement';
48
+ }
49
+ }
61
50
 
62
- function isAstroProject(info: ts.server.PluginCreateInfo) {
63
- // Add more checks like "no Astro file found" or "no config file found"?
64
- const compilerOptions = info.project.getCompilerOptions();
65
- const isNoJsxProject =
66
- (!compilerOptions.jsx || compilerOptions.jsx === modules.typescript.JsxEmit.Preserve) &&
67
- (!compilerOptions.jsxFactory || compilerOptions.jsxFactory.startsWith('astro')) &&
68
- !compilerOptions.jsxFragmentFactory &&
69
- !compilerOptions.jsxImportSource;
70
- return isNoJsxProject;
71
- }
51
+ function isAstroProject(info: ts.server.PluginCreateInfo) {
52
+ // Add more checks like "no Astro file found" or "no config file found"?
53
+ const compilerOptions = info.project.getCompilerOptions();
54
+ const isNoJsxProject =
55
+ (!compilerOptions.jsx || compilerOptions.jsx === modules.typescript.JsxEmit.Preserve) &&
56
+ (!compilerOptions.jsxFactory || compilerOptions.jsxFactory.startsWith('astro')) &&
57
+ !compilerOptions.jsxFragmentFactory &&
58
+ !compilerOptions.jsxImportSource;
59
+ return isNoJsxProject;
60
+ }
72
61
 
73
- return { create, getExternalFiles };
62
+ return { create, getExternalFiles };
74
63
  }
75
64
 
76
- export = init;
65
+ export = init;
@@ -5,69 +5,50 @@ import { isAstroFilePath, replaceDeep } from '../utils.js';
5
5
  const componentPostfix = '__AstroComponent_';
6
6
 
7
7
  export function decorateCompletions(ls: ts.LanguageService, logger: Logger): void {
8
- const getCompletionsAtPosition = ls.getCompletionsAtPosition;
9
- ls.getCompletionsAtPosition = (fileName, position, options) => {
10
- const completions = getCompletionsAtPosition(fileName, position, options);
11
- if (!completions) {
12
- return completions;
13
- }
14
- return {
15
- ...completions,
16
- entries: completions.entries.map((entry) => {
17
- if (
18
- !isAstroFilePath(entry.source || '') ||
19
- !entry.name.endsWith(componentPostfix)
20
- ) {
21
- return entry;
22
- }
23
- return {
24
- ...entry,
25
- name: entry.name.slice(0, -componentPostfix.length)
26
- };
27
- })
28
- };
29
- };
8
+ const getCompletionsAtPosition = ls.getCompletionsAtPosition;
9
+ ls.getCompletionsAtPosition = (fileName, position, options) => {
10
+ const completions = getCompletionsAtPosition(fileName, position, options);
11
+ if (!completions) {
12
+ return completions;
13
+ }
14
+ return {
15
+ ...completions,
16
+ entries: completions.entries.map((entry) => {
17
+ if (!isAstroFilePath(entry.source || '') || !entry.name.endsWith(componentPostfix)) {
18
+ return entry;
19
+ }
20
+ return {
21
+ ...entry,
22
+ name: entry.name.slice(0, -componentPostfix.length),
23
+ };
24
+ }),
25
+ };
26
+ };
30
27
 
31
- const getCompletionEntryDetails = ls.getCompletionEntryDetails;
32
- ls.getCompletionEntryDetails = (
33
- fileName,
34
- position,
35
- entryName,
36
- formatOptions,
37
- source,
38
- preferences,
39
- data
40
- ) => {
41
- const details = getCompletionEntryDetails(
42
- fileName,
43
- position,
44
- entryName,
45
- formatOptions,
46
- source,
47
- preferences,
48
- data
49
- );
50
- if (details || !isAstroFilePath(source || '')) {
51
- return details;
52
- }
28
+ const getCompletionEntryDetails = ls.getCompletionEntryDetails;
29
+ ls.getCompletionEntryDetails = (fileName, position, entryName, formatOptions, source, preferences, data) => {
30
+ const details = getCompletionEntryDetails(fileName, position, entryName, formatOptions, source, preferences, data);
31
+ if (details || !isAstroFilePath(source || '')) {
32
+ return details;
33
+ }
53
34
 
54
- // In the completion list we removed the component postfix. Internally,
55
- // the language service saved the list with the postfix, so details
56
- // won't match anything. Therefore add it back and remove it afterwards again.
57
- const astroDetails = getCompletionEntryDetails(
58
- fileName,
59
- position,
60
- entryName + componentPostfix,
61
- formatOptions,
62
- source,
63
- preferences,
64
- data
65
- );
66
- if (!astroDetails) {
67
- return undefined;
68
- }
69
- logger.debug('Found Astro Component import completion details');
35
+ // In the completion list we removed the component postfix. Internally,
36
+ // the language service saved the list with the postfix, so details
37
+ // won't match anything. Therefore add it back and remove it afterwards again.
38
+ const astroDetails = getCompletionEntryDetails(
39
+ fileName,
40
+ position,
41
+ entryName + componentPostfix,
42
+ formatOptions,
43
+ source,
44
+ preferences,
45
+ data
46
+ );
47
+ if (!astroDetails) {
48
+ return undefined;
49
+ }
50
+ logger.debug('Found Astro Component import completion details');
70
51
 
71
- return replaceDeep(astroDetails, componentPostfix, '');
72
- };
73
- }
52
+ return replaceDeep(astroDetails, componentPostfix, '');
53
+ };
54
+ }
@@ -1,46 +1,44 @@
1
1
  import type ts from 'typescript/lib/tsserverlibrary';
2
- import { Logger } from '../logger';
3
2
  import { AstroSnapshotManager } from '../astro-snapshots';
4
- import { isNotNullOrUndefined, isAstroFilePath } from '../utils';
3
+ import { Logger } from '../logger';
4
+ import { isAstroFilePath, isNotNullOrUndefined } from '../utils';
5
5
 
6
6
  export function decorateGetDefinition(
7
- ls: ts.LanguageService,
8
- snapshotManager: AstroSnapshotManager,
9
- logger: Logger
7
+ ls: ts.LanguageService,
8
+ snapshotManager: AstroSnapshotManager,
9
+ logger: Logger
10
10
  ): void {
11
- const getDefinitionAndBoundSpan = ls.getDefinitionAndBoundSpan;
12
- ls.getDefinitionAndBoundSpan = (fileName, position) => {
13
- const definition = getDefinitionAndBoundSpan(fileName, position);
14
- if (!definition?.definitions) {
15
- return definition;
16
- }
11
+ const getDefinitionAndBoundSpan = ls.getDefinitionAndBoundSpan;
12
+ ls.getDefinitionAndBoundSpan = (fileName, position) => {
13
+ const definition = getDefinitionAndBoundSpan(fileName, position);
14
+ if (!definition?.definitions) {
15
+ return definition;
16
+ }
17
17
 
18
- return {
19
- ...definition,
20
- definitions: definition.definitions
21
- .map((def) => {
22
- if (!isAstroFilePath(def.fileName)) {
23
- return def;
24
- }
18
+ return {
19
+ ...definition,
20
+ definitions: definition.definitions
21
+ .map((def) => {
22
+ if (!isAstroFilePath(def.fileName)) {
23
+ return def;
24
+ }
25
25
 
26
- let textSpan = snapshotManager
27
- .get(def.fileName)
28
- ?.getOriginalTextSpan(def.textSpan);
29
- if (!textSpan) {
30
- // Unmapped positions are for example the default export.
31
- // Fall back to the start of the file to at least go to the correct file.
32
- textSpan = { start: 0, length: 1 };
33
- }
34
- return {
35
- ...def,
36
- textSpan,
37
- // Spare the work for now
38
- originalTextSpan: undefined,
39
- contextSpan: undefined,
40
- originalContextSpan: undefined
41
- };
42
- })
43
- .filter(isNotNullOrUndefined)
44
- };
45
- };
46
- }
26
+ let textSpan = snapshotManager.get(def.fileName)?.getOriginalTextSpan(def.textSpan);
27
+ if (!textSpan) {
28
+ // Unmapped positions are for example the default export.
29
+ // Fall back to the start of the file to at least go to the correct file.
30
+ textSpan = { start: 0, length: 1 };
31
+ }
32
+ return {
33
+ ...def,
34
+ textSpan,
35
+ // Spare the work for now
36
+ originalTextSpan: undefined,
37
+ contextSpan: undefined,
38
+ originalContextSpan: undefined,
39
+ };
40
+ })
41
+ .filter(isNotNullOrUndefined),
42
+ };
43
+ };
44
+ }
@@ -3,43 +3,43 @@ import { Logger } from '../logger.js';
3
3
  import { isAstroFilePath } from '../utils.js';
4
4
 
5
5
  export function decorateDiagnostics(ls: ts.LanguageService, logger: Logger): void {
6
- decorateSyntacticDiagnostics(ls);
7
- decorateSemanticDiagnostics(ls);
8
- decorateSuggestionDiagnostics(ls);
6
+ decorateSyntacticDiagnostics(ls);
7
+ decorateSemanticDiagnostics(ls);
8
+ decorateSuggestionDiagnostics(ls);
9
9
  }
10
10
 
11
11
  function decorateSyntacticDiagnostics(ls: ts.LanguageService): void {
12
- const getSyntacticDiagnostics = ls.getSyntacticDiagnostics;
13
- ls.getSyntacticDiagnostics = (fileName: string) => {
14
- // Diagnostics inside Astro files are done
15
- // by the @astrojs/language-server / Astro for VS Code extension
16
- if (isAstroFilePath(fileName)) {
17
- return [];
18
- }
19
- return getSyntacticDiagnostics(fileName);
20
- };
12
+ const getSyntacticDiagnostics = ls.getSyntacticDiagnostics;
13
+ ls.getSyntacticDiagnostics = (fileName: string) => {
14
+ // Diagnostics inside Astro files are done
15
+ // by the @astrojs/language-server / Astro for VS Code extension
16
+ if (isAstroFilePath(fileName)) {
17
+ return [];
18
+ }
19
+ return getSyntacticDiagnostics(fileName);
20
+ };
21
21
  }
22
22
 
23
23
  function decorateSemanticDiagnostics(ls: ts.LanguageService): void {
24
- const getSemanticDiagnostics = ls.getSemanticDiagnostics;
25
- ls.getSemanticDiagnostics = (fileName: string) => {
26
- // Diagnostics inside Astro files are done
27
- // by the @astrojs/language-server / Astro for VS Code extension
28
- if (isAstroFilePath(fileName)) {
29
- return [];
30
- }
31
- return getSemanticDiagnostics(fileName);
32
- };
24
+ const getSemanticDiagnostics = ls.getSemanticDiagnostics;
25
+ ls.getSemanticDiagnostics = (fileName: string) => {
26
+ // Diagnostics inside Astro files are done
27
+ // by the @astrojs/language-server / Astro for VS Code extension
28
+ if (isAstroFilePath(fileName)) {
29
+ return [];
30
+ }
31
+ return getSemanticDiagnostics(fileName);
32
+ };
33
33
  }
34
34
 
35
35
  function decorateSuggestionDiagnostics(ls: ts.LanguageService): void {
36
- const getSuggestionDiagnostics = ls.getSuggestionDiagnostics;
37
- ls.getSuggestionDiagnostics = (fileName: string) => {
38
- // Diagnostics inside Astro files are done
39
- // by the @astrojs/language-server / Astro for VS Code extension
40
- if (isAstroFilePath(fileName)) {
41
- return [];
42
- }
43
- return getSuggestionDiagnostics(fileName);
44
- };
45
- }
36
+ const getSuggestionDiagnostics = ls.getSuggestionDiagnostics;
37
+ ls.getSuggestionDiagnostics = (fileName: string) => {
38
+ // Diagnostics inside Astro files are done
39
+ // by the @astrojs/language-server / Astro for VS Code extension
40
+ if (isAstroFilePath(fileName)) {
41
+ return [];
42
+ }
43
+ return getSuggestionDiagnostics(fileName);
44
+ };
45
+ }
@@ -1,95 +1,86 @@
1
1
  import type ts from 'typescript/lib/tsserverlibrary';
2
- import { Logger } from '../logger';
3
2
  import { AstroSnapshotManager } from '../astro-snapshots.js';
4
- import { isNotNullOrUndefined, isAstroFilePath } from '../utils.js';
3
+ import { Logger } from '../logger';
4
+ import { isAstroFilePath, isNotNullOrUndefined } from '../utils.js';
5
5
 
6
6
  export function decorateFindReferences(
7
- ls: ts.LanguageService,
8
- snapshotManager: AstroSnapshotManager,
9
- logger: Logger
7
+ ls: ts.LanguageService,
8
+ snapshotManager: AstroSnapshotManager,
9
+ logger: Logger
10
10
  ): void {
11
- decorateGetReferencesAtPosition(ls, snapshotManager, logger);
12
- _decorateFindReferences(ls, snapshotManager, logger);
11
+ decorateGetReferencesAtPosition(ls, snapshotManager, logger);
12
+ _decorateFindReferences(ls, snapshotManager, logger);
13
13
  }
14
14
 
15
- function _decorateFindReferences(
16
- ls: ts.LanguageService,
17
- snapshotManager: AstroSnapshotManager,
18
- logger: Logger
19
- ) {
20
- const findReferences = ls.findReferences;
21
- ls.findReferences = (fileName, position) => {
22
- const references = findReferences(fileName, position);
23
- return references
24
- ?.map((reference) => {
25
- const snapshot = snapshotManager.get(reference.definition.fileName);
26
- if (!isAstroFilePath(reference.definition.fileName) || !snapshot) {
27
- return reference;
28
- }
15
+ function _decorateFindReferences(ls: ts.LanguageService, snapshotManager: AstroSnapshotManager, logger: Logger) {
16
+ const findReferences = ls.findReferences;
17
+ ls.findReferences = (fileName, position) => {
18
+ const references = findReferences(fileName, position);
19
+ return references
20
+ ?.map((reference) => {
21
+ const snapshot = snapshotManager.get(reference.definition.fileName);
22
+ if (!isAstroFilePath(reference.definition.fileName) || !snapshot) {
23
+ return reference;
24
+ }
29
25
 
30
- const textSpan = snapshot.getOriginalTextSpan(reference.definition.textSpan);
31
- if (!textSpan) {
32
- return null;
33
- }
26
+ const textSpan = snapshot.getOriginalTextSpan(reference.definition.textSpan);
27
+ if (!textSpan) {
28
+ return null;
29
+ }
34
30
 
35
- return {
36
- definition: {
37
- ...reference.definition,
38
- textSpan,
39
- // Spare the work for now
40
- originalTextSpan: undefined
41
- },
42
- references: mapReferences(reference.references, snapshotManager, logger)
43
- };
44
- })
45
- .filter(isNotNullOrUndefined);
46
- };
31
+ return {
32
+ definition: {
33
+ ...reference.definition,
34
+ textSpan,
35
+ // Spare the work for now
36
+ originalTextSpan: undefined,
37
+ },
38
+ references: mapReferences(reference.references, snapshotManager, logger),
39
+ };
40
+ })
41
+ .filter(isNotNullOrUndefined);
42
+ };
47
43
  }
48
44
 
49
45
  function decorateGetReferencesAtPosition(
50
- ls: ts.LanguageService,
51
- snapshotManager: AstroSnapshotManager,
52
- logger: Logger
46
+ ls: ts.LanguageService,
47
+ snapshotManager: AstroSnapshotManager,
48
+ logger: Logger
53
49
  ) {
54
- const getReferencesAtPosition = ls.getReferencesAtPosition;
55
- ls.getReferencesAtPosition = (fileName, position) => {
56
- const references = getReferencesAtPosition(fileName, position);
57
- return references && mapReferences(references, snapshotManager, logger);
58
- };
50
+ const getReferencesAtPosition = ls.getReferencesAtPosition;
51
+ ls.getReferencesAtPosition = (fileName, position) => {
52
+ const references = getReferencesAtPosition(fileName, position);
53
+ return references && mapReferences(references, snapshotManager, logger);
54
+ };
59
55
  }
60
56
 
61
57
  function mapReferences(
62
- references: ts.ReferenceEntry[],
63
- snapshotManager: AstroSnapshotManager,
64
- logger: Logger
58
+ references: ts.ReferenceEntry[],
59
+ snapshotManager: AstroSnapshotManager,
60
+ logger: Logger
65
61
  ): ts.ReferenceEntry[] {
66
- return references
67
- .map((reference) => {
68
- const snapshot = snapshotManager.get(reference.fileName);
69
- if (!isAstroFilePath(reference.fileName) || !snapshot) {
70
- return reference;
71
- }
62
+ return references
63
+ .map((reference) => {
64
+ const snapshot = snapshotManager.get(reference.fileName);
65
+ if (!isAstroFilePath(reference.fileName) || !snapshot) {
66
+ return reference;
67
+ }
72
68
 
73
- const textSpan = snapshot.getOriginalTextSpan(reference.textSpan);
74
- if (!textSpan) {
75
- return null;
76
- }
69
+ const textSpan = snapshot.getOriginalTextSpan(reference.textSpan);
70
+ if (!textSpan) {
71
+ return null;
72
+ }
77
73
 
78
- logger.debug(
79
- 'Find references; map textSpan: changed',
80
- reference.textSpan,
81
- 'to',
82
- textSpan
83
- );
74
+ logger.debug('Find references; map textSpan: changed', reference.textSpan, 'to', textSpan);
84
75
 
85
- return {
86
- ...reference,
87
- textSpan,
88
- // Spare the work for now
89
- contextSpan: undefined,
90
- originalTextSpan: undefined,
91
- originalContextSpan: undefined
92
- };
93
- })
94
- .filter(isNotNullOrUndefined);
95
- }
76
+ return {
77
+ ...reference,
78
+ textSpan,
79
+ // Spare the work for now
80
+ contextSpan: undefined,
81
+ originalTextSpan: undefined,
82
+ originalContextSpan: undefined,
83
+ };
84
+ })
85
+ .filter(isNotNullOrUndefined);
86
+ }