Repository: api-platform/admin (ts)

Issue:
Validation errors are shown as "Server communication error"
**API Platform version(s) affected**: 3.4.3

**Description**  

I'm trying to submit a form that returns validation errors. The errors are properly highlighted in the form, but the main message says "Server communication error" (which is confusing). 

Hydra response has proper fields set:

```
@context: "/api/contexts/ConstraintViolationList"
@type: "ConstraintViolationList"
hydra:title: "An error occurred"
hydra:description: "purchasePrice: A valid number is expected\ncurrentValue: A valid number is expected"
```

**How to reproduce**  

Just use Hydra and submit a form with a server-side validation failure.

**Possible Solution**  

I think, `hydra:title` (and maybe `hydra:description`) should be used instead of `Server communication error` message. And in general, 4xx statuses are probably not server communication errors.

**Additional Context**

This can be also seen on the official Admin demo:

![image](https://user-images.githubusercontent.com/5462781/197391245-6b337ddd-4a99-47e1-a317-dd5ed1635202.png)


Pull request:
Fixed #488 Validation errors are shown as "Server communication error" 
| Q             | A
| ------------- | ---
| Branch?       | main 
| Tickets       | 
| License       | MIT
| Doc PR        | 

This fixes a bug which is a combination of 2 bugs in [api-doc-parser library](https://github.com/api-platform/api-doc-parser) and 2 bugs in this repo. 

Fix also requires PR to be merged https://github.com/api-platform/api-doc-parser/pull/132

Patch:
diff --git a/jest.setup.ts b/jest.setup.ts
index 85e8030..663e582 100644
--- a/jest.setup.ts
+++ b/jest.setup.ts
@@ -1,8 +1,9 @@
 // eslint-disable-next-line import/no-extraneous-dependencies
 import '@testing-library/jest-dom';
-import { TextEncoder } from 'util';
+import { TextEncoder, TextDecoder } from 'util';
 // eslint-disable-next-line import/no-extraneous-dependencies
 import { Request } from 'node-fetch';
 
 global.TextEncoder = TextEncoder;
+global.TextDecoder = TextDecoder as any;
 global.Request = Request as any;
diff --git a/src/hydra/dataProvider.ts b/src/hydra/dataProvider.ts
index 017f545..bf1ff01 100644
--- a/src/hydra/dataProvider.ts
+++ b/src/hydra/dataProvider.ts
@@ -722,7 +722,7 @@ function dataProvider(
               page: 1,
             },
             filter: { id: params.ids },
-            sort: { field: '', order: '' },
+            sort: { field: '', order: 'ASC' },
           }).then(({ data }) => ({ data }));
         }
 
diff --git a/src/hydra/fetchHydra.ts b/src/hydra/fetchHydra.ts
index 99c8afa..dcc9f70 100644
--- a/src/hydra/fetchHydra.ts
+++ b/src/hydra/fetchHydra.ts
@@ -4,7 +4,7 @@ import {
   getDocumentationUrlFromHeaders,
 } from '@api-platform/api-doc-parser';
 import jsonld from 'jsonld';
-import type { NodeObject } from 'jsonld';
+import type { ContextDefinition, NodeObject } from 'jsonld';
 import type { JsonLdObj } from 'jsonld/jsonld-spec';
 import type { HttpClientOptions, HydraHttpClientResponse } from '../types.js';
 
@@ -40,8 +40,12 @@ function fetchHydra(
 
       delete (body as NodeObject).trace;
 
-      const documentLoader = (input: string) =>
-        fetchJsonLd(input, authOptions).then((response) => {
+      const documentLoader = (input: string) => {
+        const loaderOptions = authOptions;
+        loaderOptions.method = 'GET';
+        delete loaderOptions.body;
+
+        return fetchJsonLd(input, loaderOptions).then((response) => {
           if (!('body' in response)) {
             throw new Error(
               'An empty response was received when expanding JSON-LD error document.',
@@ -49,12 +53,15 @@ function fetchHydra(
           }
           return response;
         });
+      };
+
+      return documentLoader(getDocumentationUrlFromHeaders(headers))
+        .then((response) =>
+          jsonld.expand(body, {
+            expandContext: response.document as ContextDefinition,
+          }),
+        )
 
-      return jsonld
-        .expand(body, {
-          base: getDocumentationUrlFromHeaders(headers),
-          documentLoader,
-        })
         .then((json) =>
           Promise.reject(
             new HttpError(
diff --git a/src/types.ts b/src/types.ts
index f060ef1..30032f7 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -226,22 +226,22 @@ export type ApiPlatformAdminDataProviderTypeParams<T extends DataProviderType> =
   T extends typeof GET_LIST
     ? ApiPlatformAdminGetListParams
     : T extends typeof GET_ONE
-    ? ApiPlatformAdminGetOneParams
-    : T extends typeof GET_MANY
-    ? ApiPlatformAdminGetManyParams
-    : T extends typeof GET_MANY_REFERENCE
-    ? ApiPlatformAdminGetManyReferenceParams
-    : T extends typeof UPDATE
-    ? ApiPlatformAdminUpdateParams
-    : T extends typeof UPDATE_MANY
-    ? ApiPlatformAdminUpdateManyParams
-    : T extends typeof CREATE
-    ? ApiPlatformAdminCreateParams
-    : T extends typeof DELETE
-    ? ApiPlatformAdminDeleteParams
-    : T extends typeof DELETE_MANY
-    ? ApiPlatformAdminDeleteManyParams
-    : never;
+      ? ApiPlatformAdminGetOneParams
+      : T extends typeof GET_MANY
+        ? ApiPlatformAdminGetManyParams
+        : T extends typeof GET_MANY_REFERENCE
+          ? ApiPlatformAdminGetManyReferenceParams
+          : T extends typeof UPDATE
+            ? ApiPlatformAdminUpdateParams
+            : T extends typeof UPDATE_MANY
+              ? ApiPlatformAdminUpdateManyParams
+              : T extends typeof CREATE
+                ? ApiPlatformAdminCreateParams
+                : T extends typeof DELETE
+                  ? ApiPlatformAdminDeleteParams
+                  : T extends typeof DELETE_MANY
+                    ? ApiPlatformAdminDeleteManyParams
+                    : never;
 
 export interface ApiPlatformAdminDataProviderFactoryParams {
   entrypoint: string;


Test patch:
diff --git a/src/hydra/dataProvider.test.ts b/src/hydra/dataProvider.test.ts
index 44674b4..1d07e17 100644
--- a/src/hydra/dataProvider.test.ts
+++ b/src/hydra/dataProvider.test.ts
@@ -138,7 +138,7 @@ describe('Transform a React Admin request to an Hydra request', () => {
         perPage: 30,
       },
       sort: {
-        order: '',
+        order: 'ASC',
         field: '',
       },
       filter: {