Skip to content

Commit

Permalink
feat: add astro support for VSCode extension (#3475)
Browse files Browse the repository at this point in the history
* feat: add astro syntax grammar support
* feat: add astro support for language server
  • Loading branch information
XiNiHa committed Jan 24, 2024
1 parent 88ae243 commit 98af530
Show file tree
Hide file tree
Showing 15 changed files with 195 additions and 41 deletions.
7 changes: 7 additions & 0 deletions .changeset/grumpy-moles-grin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'graphql-language-service-server': minor
'vscode-graphql': minor
'vscode-graphql-syntax': minor
---

Add Astro file support
2 changes: 2 additions & 0 deletions custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ yoshiakis

// packages and tools
argparse
astro
astrojs
changesets
clsx
codemirror
Expand Down
8 changes: 5 additions & 3 deletions packages/graphql-language-service-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@
},
"COMMENT": "please do not remove depenencies without thorough testing. many dependencies are not imported directly, as they are peer dependencies",
"dependencies": {
"@astrojs/compiler": "^2.5.0",
"@babel/parser": "^7.23.6",
"@babel/types": "^7.23.5",
"@graphql-tools/code-file-loader": "8.0.3",
"@vue/compiler-sfc": "^3.4.5",
"astrojs-compiler-sync": "^0.3.5",
"cosmiconfig-toml-loader": "^1.0.0",
"dotenv": "10.0.0",
"fast-glob": "^3.2.7",
Expand All @@ -51,12 +53,12 @@
"mkdirp": "^1.0.4",
"node-abort-controller": "^3.0.1",
"nullthrows": "^1.0.0",
"source-map-js": "1.0.2",
"svelte": "^4.1.1",
"vscode-jsonrpc": "^8.0.1",
"vscode-languageserver": "^8.0.1",
"vscode-languageserver-types": "^3.17.2",
"vscode-uri": "^3.0.2",
"svelte": "^4.1.1",
"source-map-js": "1.0.2"
"vscode-uri": "^3.0.2"
},
"devDependencies": {
"@types/glob": "^8.1.0",
Expand Down
1 change: 1 addition & 0 deletions packages/graphql-language-service-server/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const DEFAULT_SUPPORTED_EXTENSIONS = [
'.tsx',
'.vue',
'.svelte',
'.astro',
'.cts',
'.mts',
] as const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { TAG_MAP } from './constants';
import { ecmaParser, tsParser } from './parsers/babel';
// import { svelteParser } from './parsers/svelte';
import { vueParser } from './parsers/vue';
import { astroParser } from './parsers/astro';
import type { Logger, NoopLogger } from './Logger';
import { RangeMapper } from './parsers/types';

Expand All @@ -44,6 +45,7 @@ const parserMap = {
// '.svelte': svelteParser,
'.svelte': vueParser,
'.vue': vueParser,
'.astro': astroParser,
};

export function findGraphQLTags(
Expand Down
69 changes: 69 additions & 0 deletions packages/graphql-language-service-server/src/parsers/astro.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { parse } from 'astrojs-compiler-sync';
import { Position, Range } from 'graphql-language-service';
import { RangeMapper, SourceParser } from './types';
import { babelParser } from './babel';

type ParseAstroResult =
| { type: 'error'; errors: string[] }
| {
type: 'ok';
scriptOffset: number;
scriptAst: any[];
};

function parseAstro(source: string): ParseAstroResult {
// eslint-disable-next-line unicorn/no-useless-undefined
const { ast, diagnostics } = parse(source, undefined);
if (diagnostics.some(d => d.severity === /* Error */ 1)) {
return {
type: 'error',
errors: diagnostics.map(d => JSON.stringify(d)),
};
}

for (const node of ast.children) {
if (node.type === 'frontmatter') {
try {
return {
type: 'ok',
scriptOffset: (node.position?.start.line ?? 1) - 1,
scriptAst: [babelParser(node.value, ['typescript'])],
};
} catch (error) {
return {
type: 'error',
errors: [String(error)],
};
}
}
}

return { type: 'error', errors: ['Could not find frontmatter block'] };
}

export const astroParser: SourceParser = (text, uri, logger) => {
const parseAstroResult = parseAstro(text);
if (parseAstroResult.type === 'error') {
logger.error(
`Could not parse the astro file at ${uri} to extract the graphql tags:`,
);
for (const error of parseAstroResult.errors) {
logger.error(String(error));
}
return null;
}

const rangeMapper: RangeMapper = range => {
return new Range(
new Position(
range.start.line + parseAstroResult.scriptOffset,
range.start.character,
),
new Position(
range.end.line + parseAstroResult.scriptOffset,
range.end.character,
),
);
};
return { asts: parseAstroResult.scriptAst, rangeMapper };
};
4 changes: 2 additions & 2 deletions packages/vscode-graphql-execution/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@
"@types/node": "^16.18.4",
"@types/vscode": "1.62.0",
"@types/ws": "8.2.2",
"@vscode/vsce": "^2.22.1-2",
"esbuild": "0.18.10",
"ovsx": "0.5.1",
"vsce": "^2.13.0"
"ovsx": "0.5.1"
},
"dependencies": {
"@graphql-tools/code-file-loader": "8.0.3",
Expand Down
20 changes: 16 additions & 4 deletions packages/vscode-graphql-syntax/grammars/graphql.js.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"scopeName": "inline.graphql",
"injectionSelector": "L:(meta.embedded.block.javascript | meta.embedded.block.typescript | source.js | source.ts | source.tsx | source.vue | source.svelte) -source.graphql -inline.graphql -string -comment",
"injectionSelector": "L:(meta.embedded.block.javascript | meta.embedded.block.typescript | source.js | source.ts | source.tsx | source.vue | source.svelte | source.astro) -source.graphql -inline.graphql -string -comment",
"patterns": [
{
"contentName": "meta.embedded.block.graphql",
Expand Down Expand Up @@ -28,7 +28,11 @@
"name": "punctuation.definition.string.template.end.js"
}
},
"patterns": [{ "include": "source.graphql" }]
"patterns": [
{
"include": "source.graphql"
}
]
},
{
"contentName": "meta.embedded.block.graphql",
Expand All @@ -53,7 +57,11 @@
"name": "punctuation.definition.string.template.end.js"
}
},
"patterns": [{ "include": "source.graphql" }]
"patterns": [
{
"include": "source.graphql"
}
]
},
{
"name": "taggedTemplates",
Expand All @@ -73,7 +81,11 @@
"name": "punctuation.definition.string.template.end.js"
}
},
"patterns": [{ "include": "source.graphql" }]
"patterns": [
{
"include": "source.graphql"
}
]
}
]
}
1 change: 1 addition & 0 deletions packages/vscode-graphql-syntax/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"source.tsx",
"source.vue",
"source.svelte",
"source.astro",
"text.html.markdown"
],
"scopeName": "inline.graphql",
Expand Down
12 changes: 12 additions & 0 deletions packages/vscode-graphql/.vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,15 @@ renovate.json
*.tsbuildinfo
esbuild.js
dist/**

# exclude all node_modules by default
../../node_modules/**

# @astrojs/compiler relies on the filesystem structure, therefore can't be bundled
!../../node_modules/@astrojs/compiler
# astrojs-compiler-sync relies on the filesystem structure, therefore can't be bundled
!../../node_modules/astrojs-compiler-sync
# synckit is the dependency of astrojs-compiler-sync
!../../node_modules/synckit
# @pkgr/core is the dependency of synckit
!../../node_modules/@pkgr/core
5 changes: 4 additions & 1 deletion packages/vscode-graphql/esbuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ build({
outdir: 'out/',
format: 'cjs',
sourcemap: true,
// Avoid bundling @vue/compiler-sfc's dynamic dependencies
external: [
// Avoid bundling @astrojs/compiler since esbuild can't handle WASM correctly
'@astrojs/compiler',
'astrojs-compiler-sync',
// Avoid bundling @vue/compiler-sfc's dynamic dependencies
'squirrelly',
'teacup',
'coffee-script',
Expand Down
4 changes: 2 additions & 2 deletions packages/vscode-graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@
"devDependencies": {
"@types/capitalize": "2.0.0",
"@types/vscode": "1.62.0",
"@vscode/vsce": "^2.22.1-2",
"esbuild": "0.18.10",
"ovsx": "0.5.1",
"vsce": "^2.13.0"
"ovsx": "0.5.1"
},
"dependencies": {
"graphql": "^16.8.1",
Expand Down
1 change: 1 addition & 0 deletions packages/vscode-graphql/src/apis/statusBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const statusBarActivationLanguageIds = [
'typescriptreact',
'vue',
'svelte',
'astro',
];

export const createStatusBar = () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/vscode-graphql/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export async function activate(context: ExtensionContext) {
{ scheme: 'file', language: 'vue' },
{ scheme: 'file', language: 'vue-html' },
{ scheme: 'file', language: 'svelte' },
{ scheme: 'file', language: 'astro' },
],
synchronize: {
// TODO: This should include any referenced graphql files inside the graphql-config
Expand All @@ -77,7 +78,7 @@ export async function activate(context: ExtensionContext) {
// TODO: load ignore
// These ignore node_modules and .git by default
workspace.createFileSystemWatcher(
'**/{*.graphql,*.graphqls,*.gql,*.js,*.mjs,*.cjs,*.esm,*.es,*.es6,*.jsx,*.ts,*.tsx,*.vue,*.svelte,*.cts,*.mts,*.json}',
'**/{*.graphql,*.graphqls,*.gql,*.js,*.mjs,*.cjs,*.esm,*.es,*.es6,*.jsx,*.ts,*.tsx,*.vue,*.svelte,*.cts,*.mts,*.json,*.astro}',
),
],
},
Expand Down
Loading

0 comments on commit 98af530

Please sign in to comment.