@raphiniert/ra-data-postgrest 2.0.0-alpha.1 → 2.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/IDEAS.md +46 -0
- package/README.md +50 -17
- package/esm/index.d.ts +58 -7
- package/esm/index.js +220 -219
- package/esm/urlBuilder.d.ts +4 -4
- package/esm/urlBuilder.js +95 -28
- package/lib/index.d.ts +58 -7
- package/lib/index.js +221 -218
- package/lib/urlBuilder.d.ts +4 -4
- package/lib/urlBuilder.js +102 -35
- package/package.json +10 -10
- package/src/index.ts +208 -138
- package/src/urlBuilder.ts +96 -31
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
Find all notable changes of this project in this file.
|
|
4
4
|
|
|
5
|
+
## v2.0.0-alpha.4 - 2023-10-23
|
|
6
|
+
### Improvements
|
|
7
|
+
- updated dependencies
|
|
8
|
+
|
|
9
|
+
### New feature
|
|
10
|
+
- [#100](https://github.com/raphiniert-com/ra-data-postgrest/pull/100) support "meta.columns" on all code paths (useful when the user does not have permissions on all the columns in which case doing select=* gives permissions errors) - @[ruslantalpa](https://github.com/ruslantalpa)
|
|
11
|
+
|
|
12
|
+
### Fixes
|
|
13
|
+
- [#50](https://github.com/raphiniert-com/ra-data-postgrest/issues/50) and [#88](https://github.com/raphiniert-com/ra-data-postgrest/issues/88) solved by [#100](https://github.com/raphiniert-com/ra-data-postgrest/pull/100) including other fixes - @[ruslantalpa](https://github.com/ruslantalpa)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## v2.0.0-alpha.3 - 2023-06-16
|
|
17
|
+
### Improvements
|
|
18
|
+
- updated dependencies
|
|
19
|
+
|
|
20
|
+
### New feature
|
|
21
|
+
- [#82](https://github.com/raphiniert-com/ra-data-postgrest/pull/82), add logical operator filter parsing - @[jordiyapz](https://github.com/jordiyapz)
|
|
22
|
+
|
|
23
|
+
### Fixes
|
|
24
|
+
- [#81](https://github.com/raphiniert-com/ra-data-postgrest/pull/81), use {} with cs and cd operators url - @[YannBeauxis](https://github.com/YannBeauxis)
|
|
25
|
+
|
|
26
|
+
### Breaking changes
|
|
27
|
+
- Changed from from regular parameters to instantiate the dataProvider to a configuration interface/class. Thus, in future initalize the dataProvider by creating a structure which implements the interface:
|
|
28
|
+
|
|
29
|
+
```jsx
|
|
30
|
+
import { fetchUtils } from 'react-admin';
|
|
31
|
+
import postgrestRestProvider,
|
|
32
|
+
{ IDataProviderConfig,
|
|
33
|
+
defaultPrimaryKeys,
|
|
34
|
+
defaultSchema } from '@raphiniert/ra-data-postgrest';
|
|
35
|
+
|
|
36
|
+
const config: IDataProviderConfig = {
|
|
37
|
+
apiUrl: 'http://path.to.my.api/',
|
|
38
|
+
httpClient: fetchUtils.fetchJson,
|
|
39
|
+
defaultListOp: 'eq',
|
|
40
|
+
primaryKeys: defaultPrimaryKeys,
|
|
41
|
+
schema: defaultSchema
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
dp = postgrestRestProvider(config);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## v2.0.0-alpha.2 - 2023-04-24
|
|
48
|
+
### Improvements
|
|
49
|
+
- updated dependencies
|
|
50
|
+
|
|
51
|
+
### New feature
|
|
52
|
+
- [#49](https://github.com/raphiniert-com/ra-data-postgrest/issues/49), custom schema name can be used
|
|
53
|
+
|
|
5
54
|
## v2.0.0-alpha.1 - 2023-04-09
|
|
6
55
|
### Improvements
|
|
7
56
|
- updated dependencies
|
package/IDEAS.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Here's a list of customizations that I have implemented locally in an old local version of ra-data-postgrest. The gaps in the numbers means it has already been imlemented in master. My customizations are relatively low quality and without tests. I thought I'd leave it here with you for inspiration or maybe it has overlap with one of the thins you want to work on.
|
|
2
|
+
- 1: Allowing calls like dataProvider.getOne('rpc/xxx') that actually returns a single object
|
|
3
|
+
- 6: column filtering voor getOne en getMany
|
|
4
|
+
- 8: Be able to use useGetOne with an array of ids for rpc/xxx functions
|
|
5
|
+
- 8b: Be able to use useGetMany with an array of ids for rpc/xxx functions
|
|
6
|
+
- 9: Be able to use useGetList with rpc functions (that return a list)
|
|
7
|
+
- 10: we could do null valued parameters, but undefined valued paramters do not make sense to pass to Postgrest
|
|
8
|
+
- 11: be able to filter on an array of values (and use 'in' operator by default)
|
|
9
|
+
- 12: be able to sort on multiple fields
|
|
10
|
+
- 13: with calls to getOne using rpc functions do not use eq.xxx but simply xxx
|
|
11
|
+
- 17: Allow a null response with getManyReference instead of an empty array (because that's what som of my rpcs return)
|
|
12
|
+
Some might be so niche that you should ignore them and that I instead should actually implement in a decorator (a function that alters the params a bit before the dataprovider function is called)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
About the decorator. Not sure if know how to use it, but I use it like this:
|
|
16
|
+
```jsx
|
|
17
|
+
import { CreateParams, DataProvider } from 'react-admin';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Gives opportunity to alter method, resource and params before calling the original dataProvider
|
|
21
|
+
*/
|
|
22
|
+
export const decorator = (dataProvider: DataProvider) => ({
|
|
23
|
+
...dataProvider,
|
|
24
|
+
create: (originalResource: string, originalParams: CreateParams) => {
|
|
25
|
+
const method = 'create';
|
|
26
|
+
|
|
27
|
+
const newParams = {
|
|
28
|
+
...originalParams,
|
|
29
|
+
// alterations
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return dataProvider[method](originalResource, newParams);
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
And then to use it.
|
|
38
|
+
```jsx
|
|
39
|
+
const restClient = postgrestRestProvider(
|
|
40
|
+
httpClientApi,
|
|
41
|
+
defaultListOp,
|
|
42
|
+
resourcePimaryKeys
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
export const dataProvider = decorator(restClient);
|
|
46
|
+
```
|
package/README.md
CHANGED
|
@@ -47,14 +47,25 @@ Access-Control-Expose-Headers: Content-Range
|
|
|
47
47
|
|
|
48
48
|
```jsx
|
|
49
49
|
// in src/App.js
|
|
50
|
-
import React from 'react';
|
|
51
|
-
import { Admin, Resource } from 'react-admin';
|
|
52
|
-
import postgrestRestProvider
|
|
50
|
+
import * as React from 'react';
|
|
51
|
+
import { Admin, Resource, fetchUtils } from 'react-admin';
|
|
52
|
+
import postgrestRestProvider,
|
|
53
|
+
{ IDataProviderConfig,
|
|
54
|
+
defaultPrimaryKeys,
|
|
55
|
+
defaultSchema } from '@raphiniert/ra-data-postgrest';
|
|
53
56
|
|
|
54
57
|
import { PostList } from './posts';
|
|
55
58
|
|
|
59
|
+
const config: IDataProviderConfig = {
|
|
60
|
+
apiUrl: 'http://path.to.my.api/',
|
|
61
|
+
httpClient: fetchUtils.fetchJson,
|
|
62
|
+
defaultListOp: 'eq',
|
|
63
|
+
primaryKeys: defaultPrimaryKeys,
|
|
64
|
+
schema: defaultSchema
|
|
65
|
+
}
|
|
66
|
+
|
|
56
67
|
const App = () => (
|
|
57
|
-
<Admin dataProvider={postgrestRestProvider(
|
|
68
|
+
<Admin dataProvider={postgrestRestProvider(config)}>
|
|
58
69
|
<Resource name="posts" list={PostList} />
|
|
59
70
|
</Admin>
|
|
60
71
|
);
|
|
@@ -80,7 +91,14 @@ const httpClient = (url, options = {}) => {
|
|
|
80
91
|
options.headers.set('X-Custom-Header', 'foobar');
|
|
81
92
|
return fetchUtils.fetchJson(url, options);
|
|
82
93
|
};
|
|
83
|
-
|
|
94
|
+
|
|
95
|
+
const config: IDataProviderConfig = {
|
|
96
|
+
...
|
|
97
|
+
httpClient: httpClient,
|
|
98
|
+
...
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const dataProvider = postgrestRestProvider(config);
|
|
84
102
|
|
|
85
103
|
render(
|
|
86
104
|
<Admin dataProvider={dataProvider} title="Example Admin">
|
|
@@ -137,22 +155,36 @@ Given a RPC call as `GET /rpc/add_them?post_author=Herbert HTTP/1.1`, the dataPr
|
|
|
137
155
|
If one has data resources without primary keys named `id`, one will have to define this specifically. Also, if there is a primary key, which is defined over multiple columns:
|
|
138
156
|
|
|
139
157
|
```jsx
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
'eq',
|
|
144
|
-
new Map([
|
|
158
|
+
const config: IDataProviderConfig = {
|
|
159
|
+
...
|
|
160
|
+
primaryKeys: new Map([
|
|
145
161
|
['some_table', ['custom_id']],
|
|
146
162
|
['another_table', ['first_column', 'second_column']],
|
|
147
|
-
])
|
|
148
|
-
|
|
163
|
+
]),
|
|
164
|
+
...
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const dataProvider = postgrestRestProvider(config);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Custom schema
|
|
171
|
+
PostgREST allows to [select and switch the database schema](https://postgrest.org/en/stable/api.html#switching-schemas) by setting a custom header. Thus, one way to use this function would be adding the custom header as a string while using react-admin hooks within `meta.schema` (compare to next section) or to set it up as function of `() => (string)` while using the data provider just component based. The latter can be done as follows and gives the opportunity to use some central storage (e.g. localStorage) which can be changed at multiple points of the application:
|
|
172
|
+
```jsx
|
|
173
|
+
const config: IDataProviderConfig = {
|
|
174
|
+
...
|
|
175
|
+
schema: localStorage.getItem("schema") || "api",
|
|
176
|
+
...
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const dataProvider = postgrestRestProvider(config);
|
|
149
180
|
```
|
|
150
181
|
|
|
151
182
|
### Passing extra headers via meta
|
|
152
183
|
Postgrest supports calling functions with a single JSON parameter by sending the header Prefer: params=single-object with your request according to its [docs](https://postgrest.org/en/stable/api.html#calling-functions-with-a-single-json-parameter).
|
|
153
184
|
|
|
154
185
|
Within the data provider one can add any kind of header to the request while calling react-admin hooks, e.g.:
|
|
155
|
-
|
|
186
|
+
|
|
187
|
+
```jsx
|
|
156
188
|
const [create, { isLoading, error }] = useCreate(
|
|
157
189
|
'rpc/my-function',
|
|
158
190
|
{
|
|
@@ -164,7 +196,8 @@ const [create, { isLoading, error }] = useCreate(
|
|
|
164
196
|
|
|
165
197
|
### Vertical filtering
|
|
166
198
|
Postgrest supports a feature of [Vertical Filtering (Columns)](https://postgrest.org/en/stable/api.html#vertical-filtering-columns). Within the react-admin hooks this feature can be used as in the following example:
|
|
167
|
-
|
|
199
|
+
|
|
200
|
+
```jsx
|
|
168
201
|
const { data, total, isLoading, error } = useGetList(
|
|
169
202
|
'posts',
|
|
170
203
|
{
|
|
@@ -176,15 +209,15 @@ const { data, total, isLoading, error } = useGetList(
|
|
|
176
209
|
```
|
|
177
210
|
|
|
178
211
|
Further, one should be able to leverage this feature to rename columns:
|
|
179
|
-
```
|
|
212
|
+
```jsx
|
|
180
213
|
columns: ['id', 'somealias:title']
|
|
181
214
|
```
|
|
182
215
|
, to cast columns:
|
|
183
|
-
```
|
|
216
|
+
```jsx
|
|
184
217
|
columns: ['id::text', 'title']
|
|
185
218
|
```
|
|
186
219
|
and even get bits from a json or jsonb column"
|
|
187
|
-
```
|
|
220
|
+
```jsx
|
|
188
221
|
columns: ['id', 'json_data->>blood_type', 'json_data->phones']
|
|
189
222
|
```
|
|
190
223
|
|
package/esm/index.d.ts
CHANGED
|
@@ -1,9 +1,60 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DataProvider } from 'ra-core';
|
|
2
2
|
import { PrimaryKey, PostgRestOperator } from './urlBuilder';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Maps react-admin queries to a postgrest REST API
|
|
5
|
+
*
|
|
6
|
+
* This REST dialect uses postgrest syntax
|
|
7
|
+
*
|
|
8
|
+
* @see https://postgrest.org/en/stable/api.html#embedded-filters
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
*
|
|
12
|
+
* getList => GET http://my.api.url/posts?order=title.asc&offset=0&limit=24&filterField=eq.value
|
|
13
|
+
* getOne => GET http://my.api.url/posts?id=eq.123
|
|
14
|
+
* getMany => GET http://my.api.url/posts?id=in.(123,456,789)
|
|
15
|
+
* getManyReference => GET http://my.api.url/posts?author_id=eq.345
|
|
16
|
+
* create => POST http://my.api.url/posts
|
|
17
|
+
* update => PATCH http://my.api.url/posts?id=eq.123
|
|
18
|
+
* updateMany => PATCH http://my.api.url/posts?id=in.(123,456,789)
|
|
19
|
+
* delete => DELETE http://my.api.url/posts?id=eq.123
|
|
20
|
+
* deleteMany => DELETE http://my.api.url/posts?id=in.(123,456,789)
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
*
|
|
24
|
+
* import * as React from 'react';
|
|
25
|
+
* import { Admin, Resource, fetchUtils } from 'react-admin';
|
|
26
|
+
* import postgrestRestProvider,
|
|
27
|
+
* { IDataProviderConfig,
|
|
28
|
+
* defaultPrimaryKeys,
|
|
29
|
+
* defaultSchema } from '@raphiniert/ra-data-postgrest';
|
|
30
|
+
*
|
|
31
|
+
* import { PostList } from './posts';
|
|
32
|
+
*
|
|
33
|
+
* const config: IDataProviderConfig = {
|
|
34
|
+
* apiUrl: 'http://path.to.my.api/',
|
|
35
|
+
* httpClient: fetchUtils.fetchJson,
|
|
36
|
+
* defaultListOp: 'eq',
|
|
37
|
+
* primaryKeys: defaultPrimaryKeys,
|
|
38
|
+
* schema: defaultSchema
|
|
39
|
+
* }
|
|
40
|
+
*
|
|
41
|
+
* const App = () => (
|
|
42
|
+
* <Admin dataProvider={postgrestRestProvider(config)}>
|
|
43
|
+
* <Resource name="posts" list={PostList} />
|
|
44
|
+
* </Admin>
|
|
45
|
+
* );
|
|
46
|
+
*
|
|
47
|
+
* export default App;
|
|
48
|
+
*/
|
|
49
|
+
export type MetaOption = string | undefined;
|
|
50
|
+
export declare const defaultPrimaryKeys: Map<string, PrimaryKey>;
|
|
51
|
+
export declare const defaultSchema: () => string;
|
|
52
|
+
export interface IDataProviderConfig {
|
|
53
|
+
apiUrl: string;
|
|
54
|
+
httpClient: (string: any, Options: any) => Promise<any>;
|
|
55
|
+
defaultListOp: PostgRestOperator;
|
|
56
|
+
primaryKeys: Map<string, PrimaryKey>;
|
|
57
|
+
schema: () => string;
|
|
58
|
+
}
|
|
59
|
+
declare const _default: (config: IDataProviderConfig) => DataProvider;
|
|
9
60
|
export default _default;
|