Skip to content

Commit

Permalink
bugfixes (raphiniert-com#100)
Browse files Browse the repository at this point in the history
* remove id prop when the PK of table is not "id"

* support meta on create path also

* add dist files to repo

* fix update/updateMany paths

* upgrade dev dependencies

* new compiled files

* remove unused functions

* new build

* remove dist folders from main branch
  • Loading branch information
ruslantalpa authored Oct 23, 2023
1 parent 98634d5 commit 464f6ec
Show file tree
Hide file tree
Showing 11 changed files with 2,107 additions and 5,579 deletions.
7,456 changes: 2,027 additions & 5,429 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@
"prettier": "prettier --config ./.prettierrc.js --write --list-different \"src/**/*.{js,json,ts,tsx,css,md}\""
},
"devDependencies": {
"@types/jest": "^28.1.4",
"@types/jest": "^29.5.6",
"@types/qs": "^6.9.7",
"cross-env": "^7.0.3",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"install-peers-cli": "^2.2.0",
"jest": "^28.1.2",
"prettier": "~2.8.8",
"jest": "^29.7.0",
"prettier": "^3.0.3",
"rimraf": "^5.0.0",
"ts-jest": "^28.0.5",
"ts-jest": "^29.1.1",
"typescript": "^5.0.4"
},
"peerDependencies": {
Expand Down
63 changes: 21 additions & 42 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
fetchUtils,
DataProvider,
GetListParams,
GetOneParams,
Expand All @@ -17,12 +16,11 @@ import {
getPrimaryKey,
parseFilters,
getOrderBy,
dataWithId,
dataWithVirtualId,
dataWithoutVirtualId,
removePrimaryKey,
getQuery,
getKeyData,
encodeId,
decodeId,
isCompoundKey,
} from './urlBuilder';
import qs from 'qs';

Expand Down Expand Up @@ -154,7 +152,7 @@ export default (config: IDataProviderConfig): DataProvider => ({
);
}
return {
data: json.map(obj => dataWithId(obj, primaryKey)),
data: json.map(obj => dataWithVirtualId(obj, primaryKey)),
total: parseInt(
headers.get('content-range').split('/').pop(),
10
Expand All @@ -181,7 +179,7 @@ export default (config: IDataProviderConfig): DataProvider => ({
}),
})
.then(({ json }) => ({
data: dataWithId(json, primaryKey),
data: dataWithVirtualId(json, primaryKey),
}));
},

Expand All @@ -201,7 +199,7 @@ export default (config: IDataProviderConfig): DataProvider => ({
}),
})
.then(({ json }) => ({
data: json.map(data => dataWithId(data, primaryKey)),
data: json.map(data => dataWithVirtualId(data, primaryKey)),
}));
},

Expand Down Expand Up @@ -257,7 +255,7 @@ export default (config: IDataProviderConfig): DataProvider => ({
);
}
return {
data: json.map(data => dataWithId(data, primaryKey)),
data: json.map(data => dataWithVirtualId(data, primaryKey)),
total: parseInt(
headers.get('content-range').split('/').pop(),
10
Expand All @@ -269,17 +267,12 @@ export default (config: IDataProviderConfig): DataProvider => ({
update: (resource, params: Partial<UpdateParams> = {}) => {
const { id, data, meta } = params;
const primaryKey = getPrimaryKey(resource, config.primaryKeys);

const query = getQuery(primaryKey, id, resource, meta);

const primaryKeyData = getKeyData(primaryKey, data);

const url = `${config.apiUrl}/${resource}?${qs.stringify(query)}`;
const metaSchema = params.meta?.schema;

const body = JSON.stringify({
...data,
...primaryKeyData,
...dataWithoutVirtualId(removePrimaryKey(data, primaryKey), primaryKey),
});

return config
Expand All @@ -294,35 +287,18 @@ export default (config: IDataProviderConfig): DataProvider => ({
}),
body,
})
.then(({ json }) => ({ data: dataWithId(json, primaryKey) }));
.then(({ json }) => ({ data: dataWithVirtualId(json, primaryKey) }));
},

updateMany: (resource, params: Partial<UpdateManyParams> = {}) => {
const ids = params.ids;
const { ids, meta, data } = params;
const primaryKey = getPrimaryKey(resource, config.primaryKeys);
const query = getQuery(primaryKey, ids, resource, meta);
const url = `${config.apiUrl}/${resource}?${qs.stringify(query)}`;
const body = JSON.stringify({
...dataWithoutVirtualId(removePrimaryKey(data, primaryKey), primaryKey),
});

const body = JSON.stringify(
params.ids.map(id => {
const { data } = params;
const primaryKeyParams = decodeId(id, primaryKey);

const primaryKeyData = {};
if (isCompoundKey(primaryKey)) {
primaryKey.forEach((key, index) => {
primaryKeyData[key] = primaryKeyParams[index];
});
} else {
primaryKeyData[primaryKey[0]] = primaryKeyParams[0];
}

return {
...data,
...primaryKeyData,
};
})
);

const url = `${config.apiUrl}/${resource}`;
const metaSchema = params.meta?.schema;

return config
Expand All @@ -342,8 +318,11 @@ export default (config: IDataProviderConfig): DataProvider => ({
},

create: (resource, params: Partial<CreateParams> = {}) => {
const { meta } = params;
const primaryKey = getPrimaryKey(resource, config.primaryKeys);
const url = `${config.apiUrl}/${resource}`;
const query = getQuery(primaryKey, undefined, resource, meta);
const queryStr = qs.stringify(query);
const url = `${config.apiUrl}/${resource}${queryStr.length > 0 ? '?' : ''}${queryStr}`;
const metaSchema = params.meta?.schema;

return config
Expand All @@ -356,7 +335,7 @@ export default (config: IDataProviderConfig): DataProvider => ({
...(params.meta?.headers || {}),
...useCustomSchema(config.schema, metaSchema, 'POST'),
}),
body: JSON.stringify(params.data),
body: JSON.stringify(dataWithoutVirtualId(params.data, primaryKey)),
})
.then(({ json }) => ({
data: {
Expand Down Expand Up @@ -386,7 +365,7 @@ export default (config: IDataProviderConfig): DataProvider => ({
...useCustomSchema(config.schema, metaSchema, 'DELETE'),
}),
})
.then(({ json }) => ({ data: dataWithId(json, primaryKey) }));
.then(({ json }) => ({ data: dataWithVirtualId(json, primaryKey) }));
},

deleteMany: (resource, params: Partial<DeleteManyParams> = {}) => {
Expand Down
39 changes: 20 additions & 19 deletions src/urlBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,14 @@ export const encodeId = (data: any, primaryKey: PrimaryKey): Identifier => {
}
};

export const dataWithId = (data: any, primaryKey: PrimaryKey) => {
if (JSON.stringify(primaryKey) === JSON.stringify(['id'])) {
export const removePrimaryKey = (data: any, primaryKey: PrimaryKey) => {
const newData = { ...data };
primaryKey.forEach(key => {delete newData[key];});
return newData;
}

export const dataWithVirtualId = (data: any, primaryKey: PrimaryKey) => {
if (primaryKey.length === 1 && primaryKey[0] === 'id') {
return data;
}

Expand All @@ -212,13 +218,22 @@ export const dataWithId = (data: any, primaryKey: PrimaryKey) => {
});
};

export const isCompoundKey = (primaryKey: PrimaryKey): Boolean => {
export const dataWithoutVirtualId = (data: any, primaryKey: PrimaryKey) => {
if (primaryKey.length === 1 && primaryKey[0] === 'id') {
return data;
}

const { id, ...dataWithoutId } = data;
return dataWithoutId;
}

const isCompoundKey = (primaryKey: PrimaryKey): Boolean => {
return primaryKey.length > 1;
};

export const getQuery = (
primaryKey: PrimaryKey,
ids: Identifier | Array<Identifier>,
ids: Identifier | Array<Identifier> | undefined,
resource: string,
meta: any = null
): any => {
Expand Down Expand Up @@ -247,7 +262,7 @@ export const getQuery = (
[primaryKey[0]]: `in.(${ids.join(',')})`,
};
}
} else {
} else if (ids) {
// if ids is one Identifier
const id: Identifier = ids.toString();
const primaryKeyParams = decodeId(id, primaryKey);
Expand Down Expand Up @@ -283,20 +298,6 @@ export const getQuery = (
return result;
};

export const getKeyData = (primaryKey: PrimaryKey, data: object): object => {
if (isCompoundKey(primaryKey)) {
return primaryKey.reduce(
(keyData, key) => ({
...keyData,
[key]: data[key],
}),
{}
);
} else {
return { [primaryKey[0]]: data[primaryKey[0]] };
}
};

export const getOrderBy = (
field: string,
order: string,
Expand Down
20 changes: 5 additions & 15 deletions tests/dataProvider/basic.schema.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { enc } from '../urlBuilder/helper';
import { makeTestFromCase, Case } from './helper';

import qs from 'qs'
const customSchema = () => ('custom');

const cases: Case[] = [
Expand Down Expand Up @@ -126,15 +126,10 @@ const cases: Case[] = [
method: 'updateMany',
resource: 'posts',
params: { ids: [1, 2, 3], data: { title: 'hello, world!' }, meta: {} },
expectedUrl: '/posts',
expectedUrl: '/posts?'.concat(qs.stringify({id: 'in.(1,2,3)'})),
expectedOptions: {
method: 'PATCH',
// TODO: The id's in the body should actually be numbers!
body: JSON.stringify([
{ title: 'hello, world!', id: '1' },
{ title: 'hello, world!', id: '2' },
{ title: 'hello, world!', id: '3' },
]),
body: JSON.stringify({ title: 'hello, world!' }),
headers: {
prefer: 'return=representation',
'content-type': 'application/json',
Expand Down Expand Up @@ -311,15 +306,10 @@ const cases_meta: Case[] = [
data: { title: 'hello, world!' },
meta: { schema: customSchemaMeta }
},
expectedUrl: '/posts',
expectedUrl: '/posts?'.concat(qs.stringify({id: 'in.(1,2,3)'})),
expectedOptions: {
method: 'PATCH',
// TODO: The id's in the body should actually be numbers!
body: JSON.stringify([
{ title: 'hello, world!', id: '1' },
{ title: 'hello, world!', id: '2' },
{ title: 'hello, world!', id: '3' },
]),
body: JSON.stringify({ title: 'hello, world!'}),
headers: {
prefer: 'return=representation',
'content-type': 'application/json',
Expand Down
16 changes: 6 additions & 10 deletions tests/dataProvider/basic.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { enc } from '../urlBuilder/helper';
import { makeTestFromCase, Case } from './helper';
import qs from 'qs';

const cases: Case[] = [
{
Expand Down Expand Up @@ -89,14 +90,14 @@ const cases: Case[] = [
resource: 'posts',
params: {
id: 1,
data: { title: 'hello, world!' },
data: { id: 1, title: 'hello, world!' },
previousData: { title: 'previous title' },
meta: {},
},
expectedUrl: '/posts?id=eq.1',
expectedOptions: {
method: 'PATCH',
body: JSON.stringify({ title: 'hello, world!' }),
body: JSON.stringify({title: 'hello, world!' }), // notice id is removed
headers: {
accept: 'application/vnd.pgrst.object+json',
prefer: 'return=representation',
Expand All @@ -105,19 +106,14 @@ const cases: Case[] = [
},
},
{
test: 'Update multiple resources',
test: 'Update multiple resource',
method: 'updateMany',
resource: 'posts',
params: { ids: [1, 2, 3], data: { title: 'hello, world!' }, meta: {} },
expectedUrl: '/posts',
expectedUrl: '/posts?'.concat(qs.stringify({id: 'in.(1,2,3)'})),
expectedOptions: {
method: 'PATCH',
// TODO: The id's in the body should actually be numbers!
body: JSON.stringify([
{ title: 'hello, world!', id: '1' },
{ title: 'hello, world!', id: '2' },
{ title: 'hello, world!', id: '3' },
]),
body: JSON.stringify({ title: 'hello, world!'}),
headers: {
prefer: 'return=representation',
'content-type': 'application/json',
Expand Down
12 changes: 6 additions & 6 deletions tests/dataProvider/helper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { fetchUtils } from 'ra-core';
import raPostgrestProvider, { IDataProviderConfig } from '../../src/index';
import { resourcePimaryKeys } from '../fixtures';
import { resourcePrimaryKeys } from '../fixtures';

type HTTPClientMock = typeof fetchUtils.fetchJson;
const BASE_URL = 'http://localhost:3000';
Expand All @@ -27,15 +27,15 @@ function createDataProviderMock(
apiUrl: BASE_URL,
httpClient: httpClient,
defaultListOp: 'eq',
primaryKeys: resourcePimaryKeys,
primaryKeys: resourcePrimaryKeys,
schema: customSchema
}

const dataPovider = raPostgrestProvider(
const dataProvider = raPostgrestProvider(
dataProviderConfig
);

return { httpClient, dataPovider };
return { httpClient, dataProvider };
}

export type Case = {
Expand Down Expand Up @@ -66,7 +66,7 @@ export const makeTestFromCase = ({
throws,
}: Case) => {
it(`${method} > ${test}`, async () => {
const { httpClient, dataPovider } = createDataProviderMock(
const { httpClient, dataProvider } = createDataProviderMock(
200,
'',
httpClientResponseBody,
Expand All @@ -77,7 +77,7 @@ export const makeTestFromCase = ({
let dataProviderResult;

try {
dataProviderResult = await dataPovider[method](resource, params);
dataProviderResult = await dataProvider[method](resource, params);
} catch (e) {
if (throws) {
expect(e.message).toMatch(throws);
Expand Down
2 changes: 1 addition & 1 deletion tests/dataProvider/update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('update specific', () => {
'content-type': 'application/json',
},
},
},
}
];

cases.forEach(makeTestFromCase);
Expand Down
Loading

0 comments on commit 464f6ec

Please sign in to comment.