@svadmin/graphql 0.0.6
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/README.md +89 -0
- package/package.json +25 -0
- package/src/data-provider.ts +92 -0
- package/src/index.ts +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @svadmin/graphql
|
|
2
|
+
|
|
3
|
+
Generic GraphQL DataProvider for `svadmin`.
|
|
4
|
+
|
|
5
|
+
Because GraphQL APIs do not share a universal convention for CRUD operations (unlike REST), this generic provider requires you to pass your GraphQL queries and mutations via the `meta.query` property in svadmin hooks.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun add @svadmin/graphql graphql-request graphql
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
Initialize the provider with a `GraphQLClient`:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { AdminApp } from '@svadmin/ui';
|
|
19
|
+
import { createGraphQLDataProvider } from '@svadmin/graphql';
|
|
20
|
+
import { GraphQLClient } from 'graphql-request';
|
|
21
|
+
|
|
22
|
+
const client = new GraphQLClient('https://your-graphql-endpoint/graphql', {
|
|
23
|
+
headers: {
|
|
24
|
+
Authorization: `Bearer YOUR_TOKEN`,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const dataProvider = createGraphQLDataProvider({ client });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Using Hooks with GraphQL
|
|
32
|
+
|
|
33
|
+
Pass your `gql` queries into the `meta` prop of your hooks.
|
|
34
|
+
|
|
35
|
+
### Fetching a List (`useList` / `useTable`)
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { useTable } from '@svadmin/core';
|
|
39
|
+
import { gql } from 'graphql-request';
|
|
40
|
+
|
|
41
|
+
const POSTS_QUERY = gql`
|
|
42
|
+
query GetPosts($limit: Int, $offset: Int) {
|
|
43
|
+
posts(limit: $limit, offset: $offset) {
|
|
44
|
+
id
|
|
45
|
+
title
|
|
46
|
+
content
|
|
47
|
+
}
|
|
48
|
+
posts_aggregate {
|
|
49
|
+
aggregate {
|
|
50
|
+
count
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
// In your Svelte component
|
|
57
|
+
const table = useTable({
|
|
58
|
+
resource: 'posts',
|
|
59
|
+
meta: {
|
|
60
|
+
query: POSTS_QUERY
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
*(Note: If your API returns data in a deeply nested structure like `posts_aggregate.aggregate.count`, you may need to wrap this provider or map the response in your data hook overrides).*
|
|
66
|
+
|
|
67
|
+
### Creating a Record (`useCreate` / `useForm`)
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { useForm } from '@svadmin/core';
|
|
71
|
+
import { gql } from 'graphql-request';
|
|
72
|
+
|
|
73
|
+
const CREATE_POST_MUTATION = gql`
|
|
74
|
+
mutation CreatePost($title: String!, $content: String!) {
|
|
75
|
+
insert_posts_one(object: {title: $title, content: $content}) {
|
|
76
|
+
id
|
|
77
|
+
title
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
const form = useForm({
|
|
83
|
+
resource: 'posts',
|
|
84
|
+
action: 'create',
|
|
85
|
+
meta: {
|
|
86
|
+
query: CREATE_POST_MUTATION
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@svadmin/graphql",
|
|
3
|
+
"version": "0.0.6",
|
|
4
|
+
"description": "GraphQL DataProvider for svadmin",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"files": [
|
|
8
|
+
"src/**/*"
|
|
9
|
+
],
|
|
10
|
+
"main": "src/index.ts",
|
|
11
|
+
"types": "src/index.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./src/index.ts",
|
|
15
|
+
"default": "./src/index.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@svadmin/core": "0.0.5"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"graphql-request": "^7.1.0"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT"
|
|
25
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { DataProvider } from '@svadmin/core';
|
|
2
|
+
import { GraphQLClient } from 'graphql-request';
|
|
3
|
+
|
|
4
|
+
export interface GraphQLDataProviderOptions {
|
|
5
|
+
client: GraphQLClient;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates a generic GraphQL DataProvider.
|
|
10
|
+
* Requires queries to be passed in hooks via the `meta.query` property.
|
|
11
|
+
*/
|
|
12
|
+
export function createGraphQLDataProvider(options: GraphQLDataProviderOptions): DataProvider {
|
|
13
|
+
const { client } = options;
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
getApiUrl: () => 'graphql',
|
|
17
|
+
|
|
18
|
+
getList: async ({ resource, pagination, sorters, filters, meta }) => {
|
|
19
|
+
if (!meta?.query) {
|
|
20
|
+
throw new Error(`[svadmin/graphql] getList requires 'meta.query' providing the GraphQL query for resource '${resource}'`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const metaVars = (meta.variables as Record<string, unknown>) || {};
|
|
24
|
+
const variables = {
|
|
25
|
+
...metaVars,
|
|
26
|
+
limit: pagination?.pageSize,
|
|
27
|
+
offset: pagination && pagination.current && pagination.pageSize ? (pagination.current - 1) * pagination.pageSize : undefined,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const response = await client.request<{ data: any[], total?: number }>(meta.query as any, variables);
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
data: response.data || [],
|
|
34
|
+
total: response.total || 0,
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
getOne: async ({ resource, id, meta }) => {
|
|
39
|
+
if (!meta?.query) {
|
|
40
|
+
throw new Error(`[svadmin/graphql] getOne requires 'meta.query' providing the GraphQL query for resource '${resource}'`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const metaVars = (meta.variables as Record<string, unknown>) || {};
|
|
44
|
+
const variables = { id, ...metaVars };
|
|
45
|
+
const response = await client.request<{ data: any }>(meta.query as any, variables);
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
data: response.data,
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
create: async ({ resource, variables, meta }) => {
|
|
53
|
+
if (!meta?.query) {
|
|
54
|
+
throw new Error(`[svadmin/graphql] create requires 'meta.query' providing the GraphQL mutation`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const metaVars = (meta.variables as Record<string, unknown>) || {};
|
|
58
|
+
const response = await client.request<{ data: any }>(meta.query as any, { ...variables, ...metaVars });
|
|
59
|
+
return { data: response.data };
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
update: async ({ resource, id, variables, meta }) => {
|
|
63
|
+
if (!meta?.query) {
|
|
64
|
+
throw new Error(`[svadmin/graphql] update requires 'meta.query' providing the GraphQL mutation`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const metaVars = (meta.variables as Record<string, unknown>) || {};
|
|
68
|
+
const mutationVars = { id, ...variables, ...metaVars };
|
|
69
|
+
const response = await client.request<{ data: any }>(meta.query as any, mutationVars);
|
|
70
|
+
return { data: response.data };
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
deleteOne: async ({ resource, id, meta }) => {
|
|
74
|
+
if (!meta?.query) {
|
|
75
|
+
throw new Error(`[svadmin/graphql] deleteOne requires 'meta.query' providing the GraphQL mutation`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const metaVars = (meta.variables as Record<string, unknown>) || {};
|
|
79
|
+
const variables = { id, ...metaVars };
|
|
80
|
+
const response = await client.request<{ data: any }>(meta.query as any, variables);
|
|
81
|
+
return { data: response.data };
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
custom: async ({ url, method, filters, sorters, payload, headers, meta }) => {
|
|
85
|
+
if (!meta?.query) {
|
|
86
|
+
throw new Error(`[svadmin/graphql] custom requires 'meta.query' providing the GraphQL query/mutation`);
|
|
87
|
+
}
|
|
88
|
+
const response = await client.request<any>(meta.query as any, payload as any, headers as any);
|
|
89
|
+
return { data: response };
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createGraphQLDataProvider } from './data-provider';
|