diff --git a/packages/ra-core/src/core/CoreAdminUI.tsx b/packages/ra-core/src/core/CoreAdminUI.tsx index 347a114f76f..1d6a29e33ee 100644 --- a/packages/ra-core/src/core/CoreAdminUI.tsx +++ b/packages/ra-core/src/core/CoreAdminUI.tsx @@ -152,8 +152,8 @@ export interface CoreAdminUIProps { resetErrorBoundary, }: { errorInfo?: ErrorInfo; - error?: Error; - resetErrorBoundary?: (args) => void; + error: Error; + resetErrorBoundary: (args) => void; }) => ReactElement; /** diff --git a/packages/ra-data-fakerest/src/index.ts b/packages/ra-data-fakerest/src/index.ts index 1a1d7d65efe..883a402b97a 100644 --- a/packages/ra-data-fakerest/src/index.ts +++ b/packages/ra-data-fakerest/src/index.ts @@ -3,6 +3,7 @@ import { DataProvider } from 'ra-core'; /* eslint-disable no-console */ function log(type, resource, params, response) { + // @ts-ignore if (console.group) { // Better logging in Chrome console.groupCollapsed(type, resource, JSON.stringify(params)); diff --git a/packages/ra-data-fakerest/tsconfig.json b/packages/ra-data-fakerest/tsconfig.json index a18665f388c..1194b48345b 100644 --- a/packages/ra-data-fakerest/tsconfig.json +++ b/packages/ra-data-fakerest/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "outDir": "lib", "rootDir": "src", - "allowJs": false + "allowJs": false, + "strictNullChecks": true }, "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], "include": ["src"] diff --git a/packages/ra-data-graphql/src/buildApolloClient.ts b/packages/ra-data-graphql/src/buildApolloClient.ts index 2b1c52a64fd..d72f8470091 100644 --- a/packages/ra-data-graphql/src/buildApolloClient.ts +++ b/packages/ra-data-graphql/src/buildApolloClient.ts @@ -5,7 +5,7 @@ import { InMemoryCache, } from '@apollo/client'; -export default (options: Partial>) => { +export default (options?: Partial>) => { if (!options) { return new ApolloClient({ cache: new InMemoryCache().restore({}), diff --git a/packages/ra-data-graphql/src/index.ts b/packages/ra-data-graphql/src/index.ts index c8d489e3ed2..c405a5bf82b 100644 --- a/packages/ra-data-graphql/src/index.ts +++ b/packages/ra-data-graphql/src/index.ts @@ -74,7 +74,11 @@ export const defaultOptions = { }; const getOptions = ( - options: GetQueryOptions | GetMutationOptions | GetWatchQueryOptions, + options: + | GetQueryOptions + | GetMutationOptions + | GetWatchQueryOptions + | undefined, raFetchMethod: string, resource: string ) => { diff --git a/packages/ra-data-graphql/src/introspection.ts b/packages/ra-data-graphql/src/introspection.ts index e147915b32b..9d389923207 100644 --- a/packages/ra-data-graphql/src/introspection.ts +++ b/packages/ra-data-graphql/src/introspection.ts @@ -1,5 +1,6 @@ import { getIntrospectionQuery, + IntrospectionField, IntrospectionObjectType, IntrospectionQuery, IntrospectionSchema, @@ -51,8 +52,8 @@ export type IntrospectionResult = { const fetchSchema = ( client: ApolloClient -): Promise => { - return client +): Promise => + client .query({ fetchPolicy: 'network-only', query: gql` @@ -60,12 +61,11 @@ const fetchSchema = ( `, }) .then(({ data: { __schema } }) => __schema); -}; const getQueriesFromSchema = ( schema: IntrospectionSchema -): IntrospectionObjectType[] => { - return schema.types.reduce((acc, type) => { +): IntrospectionField[] => + schema.types.reduce((acc, type) => { if ( type.name !== schema.queryType?.name && type.name !== schema.mutationType?.name && @@ -76,19 +76,17 @@ const getQueriesFromSchema = ( return [...acc, ...((type as IntrospectionObjectType).fields || [])]; }, []); -}; -const getTypesFromSchema = (schema: IntrospectionSchema) => { - return schema.types.filter( +const getTypesFromSchema = (schema: IntrospectionSchema) => + schema.types.filter( type => type.name !== (schema.queryType && schema.queryType.name) && type.name !== (schema.mutationType && schema.mutationType.name) ); -}; const getResources = ( types: IntrospectionType[], - queries: IntrospectionObjectType[], + queries: IntrospectionField[], options: IntrospectionOptions ): IntrospectedResource[] => { const filteredResources = types.filter(type => @@ -101,7 +99,7 @@ const getResources = ( const isResource = ( type: IntrospectionType, - queries: IntrospectionObjectType[], + queries: IntrospectionField[], options: IntrospectionOptions ) => { if (isResourceIncluded(type, options)) return true; @@ -150,10 +148,10 @@ export const isResourceExcluded = ( const buildResource = ( type: IntrospectionObjectType, - queries: IntrospectionObjectType[], + queries: IntrospectionField[], options: IntrospectionOptions -): IntrospectedResource => { - return ALL_TYPES.reduce( +): IntrospectedResource => + ALL_TYPES.reduce( (acc, raFetchMethod) => { const query = queries.find( ({ name }) => @@ -170,4 +168,3 @@ const buildResource = ( }, { type } ); -}; diff --git a/packages/ra-data-graphql/tsconfig.json b/packages/ra-data-graphql/tsconfig.json index d4980ef9fa6..6ac2e21ab53 100644 --- a/packages/ra-data-graphql/tsconfig.json +++ b/packages/ra-data-graphql/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "outDir": "lib", "rootDir": "src", - "allowJs": false + "allowJs": false, + "strictNullChecks": true }, "exclude": [ "**/*.spec.ts", diff --git a/packages/ra-data-json-server/src/index.ts b/packages/ra-data-json-server/src/index.ts index 32a28ec9314..427afd0f02b 100644 --- a/packages/ra-data-json-server/src/index.ts +++ b/packages/ra-data-json-server/src/index.ts @@ -35,14 +35,17 @@ import { fetchUtils, DataProvider } from 'ra-core'; */ export default (apiUrl, httpClient = fetchUtils.fetchJson): DataProvider => ({ getList: (resource, params) => { - const { page, perPage } = params.pagination; - const { field, order } = params.sort; + const { page, perPage } = params.pagination || {}; + const { field, order } = params.sort || {}; const query = { ...fetchUtils.flattenObject(params.filter), _sort: field, _order: order, - _start: (page - 1) * perPage, - _end: page * perPage, + _start: + page != null && perPage != null + ? (page - 1) * perPage + : undefined, + _end: page != null && perPage != null ? page * perPage : undefined, }; const url = `${apiUrl}/${resource}?${stringify(query)}`; @@ -53,12 +56,18 @@ export default (apiUrl, httpClient = fetchUtils.fetchJson): DataProvider => ({ 'The X-Total-Count header is missing in the HTTP Response. The jsonServer Data Provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare X-Total-Count in the Access-Control-Expose-Headers header?' ); } + const totalString = headers + .get('x-total-count')! + .split('/') + .pop(); + if (totalString == null) { + throw new Error( + 'The X-Total-Count header is invalid in the HTTP Response.' + ); + } return { data: json, - total: parseInt( - headers.get('x-total-count').split('/').pop(), - 10 - ), + total: parseInt(totalString, 10), }; } ); @@ -101,12 +110,18 @@ export default (apiUrl, httpClient = fetchUtils.fetchJson): DataProvider => ({ 'The X-Total-Count header is missing in the HTTP Response. The jsonServer Data Provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare X-Total-Count in the Access-Control-Expose-Headers header?' ); } + const totalString = headers + .get('x-total-count')! + .split('/') + .pop(); + if (totalString == null) { + throw new Error( + 'The X-Total-Count header is invalid in the HTTP Response.' + ); + } return { data: json, - total: parseInt( - headers.get('x-total-count').split('/').pop(), - 10 - ), + total: parseInt(totalString, 10), }; } ); diff --git a/packages/ra-data-json-server/tsconfig.json b/packages/ra-data-json-server/tsconfig.json index a18665f388c..1194b48345b 100644 --- a/packages/ra-data-json-server/tsconfig.json +++ b/packages/ra-data-json-server/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "outDir": "lib", "rootDir": "src", - "allowJs": false + "allowJs": false, + "strictNullChecks": true }, "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], "include": ["src"] diff --git a/packages/ra-data-localforage/tsconfig.json b/packages/ra-data-localforage/tsconfig.json index f9f0259f05b..279cbd554ea 100644 --- a/packages/ra-data-localforage/tsconfig.json +++ b/packages/ra-data-localforage/tsconfig.json @@ -5,7 +5,8 @@ "rootDir": "src", "declaration": true, "declarationMap": true, - "allowJs": false + "allowJs": false, + "strictNullChecks": true, }, "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], "include": ["src"] diff --git a/packages/ra-data-localstorage/src/index.ts b/packages/ra-data-localstorage/src/index.ts index 1a91949f3dc..ff26fce4861 100644 --- a/packages/ra-data-localstorage/src/index.ts +++ b/packages/ra-data-localstorage/src/index.ts @@ -55,7 +55,7 @@ export default (params?: LocalStorageDataProviderParams): DataProvider => { window?.addEventListener('storage', event => { if (event.key === localStorageKey) { - const newData = JSON.parse(event.newValue); + const newData = event.newValue ? JSON.parse(event.newValue) : {}; data = newData; baseDataProvider = fakeRestProvider( newData, diff --git a/packages/ra-data-localstorage/tsconfig.json b/packages/ra-data-localstorage/tsconfig.json index a18665f388c..1194b48345b 100644 --- a/packages/ra-data-localstorage/tsconfig.json +++ b/packages/ra-data-localstorage/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "outDir": "lib", "rootDir": "src", - "allowJs": false + "allowJs": false, + "strictNullChecks": true }, "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], "include": ["src"] diff --git a/packages/ra-data-simple-rest/src/index.ts b/packages/ra-data-simple-rest/src/index.ts index a731279b81f..965fe8599f3 100644 --- a/packages/ra-data-simple-rest/src/index.ts +++ b/packages/ra-data-simple-rest/src/index.ts @@ -39,8 +39,8 @@ export default ( countHeader: string = 'Content-Range' ): DataProvider => ({ getList: (resource, params) => { - const { page, perPage } = params.pagination; - const { field, order } = params.sort; + const { page, perPage } = params.pagination || { page: 1, perPage: 10 }; + const { field, order } = params.sort || { field: 'id', order: 'ASC' }; const rangeStart = (page - 1) * perPage; const rangeEnd = page * perPage - 1; @@ -73,10 +73,11 @@ export default ( total: countHeader === 'Content-Range' ? parseInt( - headers.get('content-range').split('/').pop(), + headers.get('content-range')!.split('/').pop() || + '', 10 ) - : parseInt(headers.get(countHeader.toLowerCase())), + : parseInt(headers.get(countHeader.toLowerCase())!), }; }); }, @@ -136,10 +137,11 @@ export default ( total: countHeader === 'Content-Range' ? parseInt( - headers.get('content-range').split('/').pop(), + headers.get('content-range')!.split('/').pop() || + '', 10 ) - : parseInt(headers.get(countHeader.toLowerCase())), + : parseInt(headers.get(countHeader.toLowerCase())!), }; }); }, diff --git a/packages/ra-data-simple-rest/tsconfig.json b/packages/ra-data-simple-rest/tsconfig.json index a18665f388c..1194b48345b 100644 --- a/packages/ra-data-simple-rest/tsconfig.json +++ b/packages/ra-data-simple-rest/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { "outDir": "lib", "rootDir": "src", - "allowJs": false + "allowJs": false, + "strictNullChecks": true }, "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], "include": ["src"]