|
9 | 9 |
|
10 | 10 | import mkdirp from 'mkdirp';
|
11 | 11 | import { readFileSync, existsSync, writeFileSync, writeFile } from 'fs';
|
12 |
| -import { fileURLToPath, pathToFileURL } from 'url'; |
| 12 | +import { pathToFileURL } from 'url'; |
13 | 13 | import * as path from 'path';
|
| 14 | +import glob from 'fast-glob'; |
14 | 15 | import {
|
15 | 16 | CachedContent,
|
16 | 17 | Uri,
|
@@ -191,7 +192,7 @@ export class MessageProcessor {
|
191 | 192 | throw new Error('GraphQL Language Server is not initialized.');
|
192 | 193 | }
|
193 | 194 |
|
194 |
| - this._logger.log( |
| 195 | + this._logger.info( |
195 | 196 | JSON.stringify({
|
196 | 197 | type: 'usage',
|
197 | 198 | messageType: 'initialize',
|
@@ -584,7 +585,7 @@ export class MessageProcessor {
|
584 | 585 | ) {
|
585 | 586 | const uri = change.uri;
|
586 | 587 |
|
587 |
| - const text = readFileSync(fileURLToPath(uri), { encoding: 'utf8' }); |
| 588 | + const text = readFileSync(new URL(uri).pathname).toString(); |
588 | 589 | const contents = this._parser(text, uri);
|
589 | 590 |
|
590 | 591 | await this._updateFragmentDefinition(uri, contents);
|
@@ -863,37 +864,83 @@ export class MessageProcessor {
|
863 | 864 | return path.resolve(projectTmpPath);
|
864 | 865 | }
|
865 | 866 | }
|
| 867 | + /** |
| 868 | + * Safely attempts to cache schema files based on a glob or path |
| 869 | + * Exits without warning in several cases because these strings can be almost |
| 870 | + * anything! |
| 871 | + * @param uri |
| 872 | + * @param project |
| 873 | + */ |
| 874 | + async _cacheSchemaPath(uri: string, project: GraphQLProjectConfig) { |
| 875 | + try { |
| 876 | + const files = await glob(uri); |
| 877 | + if (files && files.length > 0) { |
| 878 | + await Promise.all( |
| 879 | + files.map(uriPath => this._cacheSchemaFile(uriPath, project)), |
| 880 | + ); |
| 881 | + } else { |
| 882 | + try { |
| 883 | + this._cacheSchemaFile(uri, project); |
| 884 | + } catch (err) { |
| 885 | + // this string may be an SDL string even, how do we even evaluate this? haha |
| 886 | + } |
| 887 | + } |
| 888 | + } catch (err) {} |
| 889 | + } |
| 890 | + async _cacheObjectSchema( |
| 891 | + pointer: { [key: string]: any }, |
| 892 | + project: GraphQLProjectConfig, |
| 893 | + ) { |
| 894 | + await Promise.all( |
| 895 | + Object.keys(pointer).map(async schemaUri => |
| 896 | + this._cacheSchemaPath(schemaUri, project), |
| 897 | + ), |
| 898 | + ); |
| 899 | + } |
| 900 | + async _cacheArraySchema( |
| 901 | + pointers: UnnormalizedTypeDefPointer[], |
| 902 | + project: GraphQLProjectConfig, |
| 903 | + ) { |
| 904 | + await Promise.all( |
| 905 | + pointers.map(async schemaEntry => { |
| 906 | + if (typeof schemaEntry === 'string') { |
| 907 | + await this._cacheSchemaPath(schemaEntry, project); |
| 908 | + } else if (schemaEntry) { |
| 909 | + await this._cacheObjectSchema(schemaEntry, project); |
| 910 | + } |
| 911 | + }), |
| 912 | + ); |
| 913 | + } |
866 | 914 |
|
867 | 915 | async _cacheSchemaFilesForProject(project: GraphQLProjectConfig) {
|
868 | 916 | const schema = project?.schema;
|
869 | 917 | const config = project?.extensions?.languageService;
|
870 | 918 | /**
|
871 |
| - * By default, let's only cache the full graphql config schema. |
872 |
| - * This allows us to rely on graphql-config's schema building features |
873 |
| - * And our own cache implementations |
874 |
| - * This prefers schema instead of SDL first schema development, but will still |
875 |
| - * work with lookup of the actual .graphql schema files if the option is enabled, |
876 |
| - * however results may vary. |
| 919 | + * By default, we look for schema definitions in SDL files |
| 920 | + * |
| 921 | + * with the opt-in feature `cacheSchemaOutputFileForLookup` enabled, |
| 922 | + * the resultant `graphql-config` .getSchema() schema output will be cached |
| 923 | + * locally and available as a single file for definition lookup and peek |
877 | 924 | *
|
878 |
| - * The default temporary schema file seems preferrable until we have graphql source maps |
| 925 | + * this is helpful when your `graphql-config` `schema` input is: |
| 926 | + * - a remote or local URL |
| 927 | + * - compiled from graphql files and code sources |
| 928 | + * - otherwise where you don't have schema SDL in the codebase or don't want to use it for lookup |
| 929 | + * |
| 930 | + * it is disabled by default |
879 | 931 | */
|
880 |
| - const useSchemaFileDefinitions = |
881 |
| - (config?.useSchemaFileDefinitions ?? |
882 |
| - this?._settings?.useSchemaFileDefinitions) || |
| 932 | + const cacheSchemaFileForLookup = |
| 933 | + config?.cacheSchemaFileForLookup ?? |
| 934 | + this?._settings?.cacheSchemaFileForLookup ?? |
883 | 935 | false;
|
884 |
| - if (!useSchemaFileDefinitions) { |
| 936 | + if (cacheSchemaFileForLookup) { |
885 | 937 | await this._cacheConfigSchema(project);
|
886 |
| - } else { |
887 |
| - if (Array.isArray(schema)) { |
888 |
| - Promise.all( |
889 |
| - schema.map(async (uri: UnnormalizedTypeDefPointer) => { |
890 |
| - await this._cacheSchemaFile(uri, project); |
891 |
| - }), |
892 |
| - ); |
893 |
| - } else { |
894 |
| - const uri = schema.toString(); |
895 |
| - await this._cacheSchemaFile(uri, project); |
896 |
| - } |
| 938 | + } else if (typeof schema === 'string') { |
| 939 | + await this._cacheSchemaPath(schema, project); |
| 940 | + } else if (Array.isArray(schema)) { |
| 941 | + await this._cacheArraySchema(schema, project); |
| 942 | + } else if (schema) { |
| 943 | + await this._cacheObjectSchema(schema, project); |
897 | 944 | }
|
898 | 945 | }
|
899 | 946 | /**
|
@@ -995,7 +1042,7 @@ export class MessageProcessor {
|
995 | 1042 | if (config?.projects) {
|
996 | 1043 | return Promise.all(
|
997 | 1044 | Object.keys(config.projects).map(async projectName => {
|
998 |
| - const project = await config.getProject(projectName); |
| 1045 | + const project = config.getProject(projectName); |
999 | 1046 | await this._cacheSchemaFilesForProject(project);
|
1000 | 1047 | await this._cacheDocumentFilesforProject(project);
|
1001 | 1048 | }),
|
@@ -1057,13 +1104,11 @@ export class MessageProcessor {
|
1057 | 1104 | contents,
|
1058 | 1105 | });
|
1059 | 1106 | }
|
1060 |
| - } else if (textDocument?.version) { |
1061 |
| - return this._textDocumentCache.set(uri, { |
1062 |
| - version: textDocument.version, |
1063 |
| - contents, |
1064 |
| - }); |
1065 | 1107 | }
|
1066 |
| - return null; |
| 1108 | + return this._textDocumentCache.set(uri, { |
| 1109 | + version: textDocument.version ?? 0, |
| 1110 | + contents, |
| 1111 | + }); |
1067 | 1112 | }
|
1068 | 1113 | }
|
1069 | 1114 |
|
|
0 commit comments