@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 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';