Skip to content

feat: add astro support for VSCode extension #3475

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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