Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

(chore) - Add ES5 linting and ensure polyfill-less ES5 support (#991)

* Extract common ESLint settings into preset

* Mute excess eslint warnings

* Add ES5 compliance rules

We wish to forbid all uses of methods that were introduced after ES5
that IE11 doesn't support and requires polyfilling. The exceptions are
Map/Set/WeakMap/WeakSet as these classes are required to be polyfilled
for React already to support IE.

* Remove use of for-of and excessive Object.keys from schemaPredicates

* Remove use of Array.prototype.find from traversal.ts

* Add changeset

authored by

Phil Pluckthun and committed by
GitHub
794b34c2 8f3c7572

+115 -112
+5
.changeset/fuzzy-peas-shop.md
··· 1 + --- 2 + '@urql/exchange-graphcache': patch 3 + --- 4 + 5 + Fix small pieces of code where polyfill-less ES5 usage was compromised. This was unlikely to have affected anyone in production as `Array.prototype.find` (the only usage of an ES6 method) is commonly used and polyfilled.
+16 -20
exchanges/graphcache/src/ast/schemaPredicates.ts
··· 127 127 keys: KeyingConfig 128 128 ): void { 129 129 if (process.env.NODE_ENV !== 'production') { 130 - const types = Object.keys(schema.getTypeMap()); 131 - Object.keys(keys).forEach(key => { 132 - if (types.indexOf(key) === -1) { 130 + const types = schema.getTypeMap(); 131 + for (const key in keys) { 132 + if (!types[key]) { 133 133 warn( 134 134 'Invalid Object type: The type `' + 135 135 key + ··· 137 137 20 138 138 ); 139 139 } 140 - }); 140 + } 141 141 } 142 142 } 143 143 ··· 194 194 return; 195 195 } 196 196 197 - const validTypes = Object.keys(schema.getTypeMap()); 198 - 197 + const validTypes = schema.getTypeMap(); 199 198 for (const key in resolvers) { 200 199 if (key === 'Query') { 201 200 const queryType = schema.getQueryType(); 202 201 if (queryType) { 203 - const validQueries = Object.keys(queryType.toConfig().fields); 202 + const validQueries = queryType.getFields(); 204 203 for (const resolverQuery in resolvers.Query) { 205 - if (validQueries.indexOf(resolverQuery) === -1) { 204 + if (!validQueries[resolverQuery]) { 206 205 warnAboutResolver('Query.' + resolverQuery); 207 206 } 208 207 } ··· 210 209 warnAboutResolver('Query'); 211 210 } 212 211 } else { 213 - if (validTypes.indexOf(key) === -1) { 212 + if (!validTypes[key]) { 214 213 warnAboutResolver(key); 215 214 } else { 216 - const validTypeProperties = Object.keys( 217 - (schema.getType(key) as GraphQLObjectType).getFields() 218 - ); 219 - const resolverProperties = Object.keys(resolvers[key]); 220 - for (const resolverProperty of resolverProperties) { 221 - if (validTypeProperties.indexOf(resolverProperty) === -1) { 215 + const validTypeProperties = (schema.getType( 216 + key 217 + ) as GraphQLObjectType).getFields(); 218 + for (const resolverProperty in resolvers[key]) { 219 + if (!validTypeProperties[resolverProperty]) { 222 220 warnAboutResolver(key + '.' + resolverProperty); 223 221 } 224 222 } ··· 236 234 } 237 235 238 236 const validMutations = schema.getMutationType() 239 - ? Object.keys( 240 - (schema.getMutationType() as GraphQLObjectType).toConfig().fields 241 - ) 242 - : []; 237 + ? (schema.getMutationType() as GraphQLObjectType).getFields() 238 + : {}; 243 239 244 240 for (const mutation in optimisticMutations) { 245 - if (validMutations.indexOf(mutation) === -1) { 241 + if (!validMutations[mutation]) { 246 242 warn( 247 243 `Invalid optimistic mutation field: \`${mutation}\` is not a mutation field in the defined schema, but the \`optimistic\` option is referencing it.`, 248 244 24
+6 -6
exchanges/graphcache/src/ast/traversal.ts
··· 20 20 export const getMainOperation = ( 21 21 doc: DocumentNode 22 22 ): OperationDefinitionNode => { 23 - const operation = doc.definitions.find( 24 - node => node.kind === Kind.OPERATION_DEFINITION 25 - ) as OperationDefinitionNode; 23 + for (let i = 0; i < doc.definitions.length; i++) { 24 + if (doc.definitions[i].kind === Kind.OPERATION_DEFINITION) { 25 + return doc.definitions[i] as OperationDefinitionNode; 26 + } 27 + } 26 28 27 29 invariant( 28 - !!operation, 30 + false, 29 31 'Invalid GraphQL document: All GraphQL documents must contain an OperationDefinition' + 30 32 'node for a query, subscription, or mutation.', 31 33 1 32 34 ); 33 - 34 - return operation; 35 35 }; 36 36 37 37 /** Returns a mapping from fragment names to their selections */
+1
package.json
··· 63 63 "dotenv": "^8.2.0", 64 64 "eslint": "^7.8.1", 65 65 "eslint-config-prettier": "^6.11.0", 66 + "eslint-plugin-es5": "^1.5.0", 66 67 "eslint-plugin-import": "^2.22.0", 67 68 "eslint-plugin-prettier": "^3.1.4", 68 69 "eslint-plugin-react": "^7.20.6",
+1
packages/next-urql/src/with-urql-client.tsx
··· 60 60 61 61 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 62 62 return initUrqlClient(clientConfig, shouldBindGetInitialprops)!; 63 + // eslint-disable-next-line react-hooks/exhaustive-deps 63 64 }, [urqlClient, urqlState, forceUpdate[0]]); 64 65 65 66 const resetUrqlClient = () => {
+1
packages/preact-urql/src/hooks/useMutation.ts
··· 63 63 return result; 64 64 }); 65 65 }, 66 + // eslint-disable-next-line react-hooks/exhaustive-deps 66 67 [client, query, setState] 67 68 ); 68 69
+1
packages/react-urql/src/hooks/useMutation.ts
··· 62 62 return result; 63 63 }); 64 64 }, 65 + // eslint-disable-next-line react-hooks/exhaustive-deps 65 66 [client, query, setState] 66 67 ); 67 68
+75
scripts/eslint/common.js
··· 1 + module.exports = { 2 + parserOptions: { 3 + ecmaVersion: 9, 4 + sourceType: 'module', 5 + ecmaFeatures: { 6 + modules: true, 7 + jsx: true, 8 + }, 9 + }, 10 + extends: [ 11 + 'plugin:react/recommended', 12 + 'prettier', 13 + ], 14 + ignorePatterns: [ 15 + 'node_modules/', 16 + 'dist/', 17 + 'build/', 18 + 'coverage/', 19 + 'benchmark/', 20 + 'example/', 21 + 'examples/', 22 + 'scripts/' 23 + ], 24 + plugins: [ 25 + 'react-hooks', 26 + 'prettier', 27 + 'es5', 28 + ], 29 + rules: { 30 + 'react-hooks/rules-of-hooks': 'error', 31 + 'react-hooks/exhaustive-deps': 'warn', 32 + 'react/react-in-jsx-scope': 'off', 33 + 'react/prop-types': 'off', 34 + 'react/no-children-prop': 'off', 35 + 'sort-keys': 'off', 36 + 'no-console': ['error', { allow: ['warn', 'error'] }], 37 + 'prefer-arrow/prefer-arrow-functions': 'off', 38 + 39 + 'es5/no-for-of': 'error', 40 + 'es5/no-generators': 'error', 41 + 'es5/no-typeof-symbol': 'error', 42 + 'es5/no-es6-methods': 'error', 43 + 44 + 'es5/no-es6-static-methods': ['error', { 45 + exceptMethods: ['Object.assign'] 46 + }], 47 + 48 + 'prettier/prettier': ['error', { 49 + singleQuote: true, 50 + arrowParens: 'avoid', 51 + trailingComma: 'es5', 52 + }], 53 + }, 54 + 55 + overrides: [ 56 + { 57 + files: [ 58 + '*.test.ts', 59 + '*.test.tsx', 60 + '*.spec.ts', 61 + '*.spec.tsx', 62 + ], 63 + rules: { 64 + 'es5/no-es6-methods': 'off', 65 + 'es5/no-es6-static-methods': 'off', 66 + } 67 + } 68 + ], 69 + 70 + settings: { 71 + react: { 72 + version: 'detect', 73 + }, 74 + }, 75 + };
+3 -43
scripts/eslint/js-preset.js
··· 1 1 module.exports = { 2 - parserOptions: { 3 - ecmaVersion: 9, 4 - sourceType: 'module', 5 - ecmaFeatures: { 6 - modules: true, 7 - jsx: true, 8 - }, 9 - }, 10 2 extends: [ 11 - 'plugin:react/recommended', 3 + './common.js', 12 4 'plugin:import/errors', 13 - 'prettier', 14 - ], 15 - ignorePatterns: [ 16 - 'node_modules/', 17 - 'dist/', 18 - 'build/', 19 - 'coverage/', 20 - 'benchmark/', 21 - 'example/', 22 - 'examples/', 23 - 'scripts/' 24 - ], 25 - plugins: [ 26 - 'react-hooks', 27 - 'prettier', 28 5 ], 29 6 rules: { 30 7 'consistent-return': 'warn', 31 8 'no-magic-numbers': 'off', // TODO 32 9 'react/jsx-key': 'off', 33 10 'react/jsx-handler-names': 'off', 34 - 'react-hooks/rules-of-hooks': 'error', 35 - 'react-hooks/exhaustive-deps': 'warn', 36 - 'react/react-in-jsx-scope': 'off', 37 - 'react/prop-types': 'off', 38 - 'react/no-children-prop': 'off', 39 - 'sort-keys': 'off', 40 - 'no-console': ['error', { allow: ['warn', 'error'] }], 41 - 'prefer-arrow/prefer-arrow-functions': 'off', 42 - 43 - 'prettier/prettier': ['error', { 44 - singleQuote: true, 45 - arrowParens: 'avoid', 46 - trailingComma: 'es5', 47 - }], 48 - }, 49 - settings: { 50 - react: { 51 - version: 'detect', 52 - }, 11 + 'import/no-internal-modules': 'off', 12 + 'es5/no-es6-methods': 'off', 53 13 }, 54 14 };
+1 -43
scripts/eslint/preset.js
··· 1 1 module.exports = { 2 2 parser: '@typescript-eslint/parser', 3 - parserOptions: { 4 - ecmaVersion: 9, 5 - sourceType: 'module', 6 - ecmaFeatures: { 7 - modules: true, 8 - jsx: true, 9 - }, 10 - }, 11 3 extends: [ 4 + './common.js', 12 5 'plugin:@typescript-eslint/recommended', 13 - 'plugin:react/recommended', 14 - 'prettier', 15 6 'prettier/@typescript-eslint', 16 7 ], 17 - ignorePatterns: [ 18 - 'node_modules/', 19 - 'dist/', 20 - 'build/', 21 - 'coverage/', 22 - 'benchmark/', 23 - 'example/', 24 - 'examples/', 25 - 'scripts/' 26 - ], 27 - plugins: [ 28 - 'react-hooks', 29 - 'prettier', 30 - ], 31 8 rules: { 32 9 '@typescript-eslint/explicit-module-boundary-types': 'off', 33 10 '@typescript-eslint/no-use-before-define': 'off', ··· 41 18 '@typescript-eslint/no-non-null-assertion': 'off', 42 19 '@typescript-eslint/no-explicit-any': 'off', 43 20 '@typescript-eslint/array-type': 'off', 44 - 'react-hooks/rules-of-hooks': 'error', 45 - 'react-hooks/exhaustive-deps': 'warn', 46 - 'react/react-in-jsx-scope': 'off', 47 - 'react/prop-types': 'off', 48 - 'react/no-children-prop': 'off', 49 - 'sort-keys': 'off', 50 - 'no-console': ['error', { allow: ['warn', 'error'] }], 51 21 'import/no-internal-modules': 'off', 52 - 'prefer-arrow/prefer-arrow-functions': 'off', 53 - 54 - 'prettier/prettier': ['error', { 55 - singleQuote: true, 56 - arrowParens: 'avoid', 57 - trailingComma: 'es5', 58 - }], 59 - }, 60 - settings: { 61 - react: { 62 - version: 'detect', 63 - }, 64 22 }, 65 23 };
+5
yarn.lock
··· 7087 7087 debug "^2.6.9" 7088 7088 pkg-dir "^2.0.0" 7089 7089 7090 + eslint-plugin-es5@^1.5.0: 7091 + version "1.5.0" 7092 + resolved "https://registry.yarnpkg.com/eslint-plugin-es5/-/eslint-plugin-es5-1.5.0.tgz#aab19af3d4798f7924bba309bc4f87087280fbba" 7093 + integrity sha512-Qxmfo7v2B7SGAEURJo0dpBweFf+JU15kSyALfiB2rXWcBuJ96r6X9kFHXFnhdopPHCaHjoQs1xQPUJVbGMb1AA== 7094 + 7090 7095 eslint-plugin-import@^2.22.0: 7091 7096 version "2.22.0" 7092 7097 resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz#92f7736fe1fde3e2de77623c838dd992ff5ffb7e"