@svadmin/refine-adapter 0.9.3 → 0.10.1

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,88 @@
1
+ # @svadmin/refine-adapter
2
+
3
+ > Bridge any [@refinedev](https://github.com/refinedev/refine) data provider to svadmin
4
+
5
+ [![npm](https://img.shields.io/npm/v/@svadmin/refine-adapter?color=ff3e00&label=npm)](https://www.npmjs.com/package/@svadmin/refine-adapter)
6
+
7
+ ## Why?
8
+
9
+ [Refine](https://refine.dev/) has a rich ecosystem of battle-tested data providers for services like Supabase, Appwrite, Hasura, Strapi, Airtable, NestJS, and more. `@svadmin/refine-adapter` lets you use **any** of those providers inside svadmin — zero rewrite required.
10
+
11
+ Since Refine's `DataProvider` interface closely mirrors svadmin's `DataProvider`, the adapter is a thin bridge that binds method calls and forwards optional methods when present.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ bun add @svadmin/refine-adapter @svadmin/core
17
+ ```
18
+
19
+ If your app is powered by Vite and also uses `@svadmin/ui` or `@svadmin/supabase`, exclude svadmin packages from `optimizeDeps` to avoid dev-time pre-bundling issues:
20
+
21
+ ```ts
22
+ optimizeDeps: {
23
+ exclude: ['@svadmin/core', '@svadmin/ui', '@svadmin/supabase'],
24
+ }
25
+ ```
26
+
27
+ Then install the Refine data provider you want to use, e.g.:
28
+
29
+ ```bash
30
+ bun add @refinedev/supabase
31
+ bun add @refinedev/strapi-v4
32
+ bun add @refinedev/appwrite
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ ```typescript
38
+ import { createRefineAdapter } from '@svadmin/refine-adapter';
39
+ import { dataProvider as createRefineSupabase } from '@refinedev/supabase';
40
+ import { createClient } from '@supabase/supabase-js';
41
+
42
+ const supabaseClient = createClient(SUPABASE_URL, SUPABASE_KEY);
43
+ const refineProvider = createRefineSupabase(supabaseClient);
44
+
45
+ // Bridge it to svadmin
46
+ const dataProvider = createRefineAdapter(refineProvider);
47
+ ```
48
+
49
+ Then pass `dataProvider` to `<AdminApp>` or `setDataProvider()` as usual.
50
+
51
+ ## Supported Methods
52
+
53
+ | Method | Required | Description |
54
+ |--------|----------|-------------|
55
+ | `getList` | ✅ | List with pagination, sorting, filtering |
56
+ | `getOne` | ✅ | Get single record |
57
+ | `create` | ✅ | Create record |
58
+ | `update` | ✅ | Update record |
59
+ | `deleteOne` | ✅ | Delete record |
60
+ | `getApiUrl` | ✅ | Return API base URL |
61
+ | `getMany` | Optional | Bulk get |
62
+ | `createMany` | Optional | Bulk create |
63
+ | `updateMany` | Optional | Bulk update |
64
+ | `deleteMany` | Optional | Bulk delete |
65
+ | `custom` | Optional | Custom endpoint |
66
+
67
+ Optional methods are only wired if the underlying Refine provider implements them.
68
+
69
+ ## Which Svadmin Providers Use This?
70
+
71
+ The following `@svadmin/*` packages internally use `@svadmin/refine-adapter` to bridge their corresponding `@refinedev/*` provider:
72
+
73
+ | svadmin Package | Refine Package |
74
+ |-----------------|---------------|
75
+ | `@svadmin/supabase` | `@refinedev/supabase` |
76
+ | `@svadmin/appwrite` | `@refinedev/appwrite` |
77
+ | `@svadmin/strapi` | `@refinedev/strapi-v4` |
78
+ | `@svadmin/hasura` | `@refinedev/hasura` |
79
+ | `@svadmin/graphql` | `@refinedev/graphql` |
80
+ | `@svadmin/airtable` | `@refinedev/airtable` |
81
+ | `@svadmin/medusa` | `@refinedev/medusa` |
82
+ | `@svadmin/nestjs-query` | `@refinedev/nestjs-query` |
83
+ | `@svadmin/nestjsx-crud` | `@refinedev/nestjsx-crud` |
84
+ | `@svadmin/simple-rest` | `@refinedev/simple-rest` |
85
+
86
+ ## License
87
+
88
+ MIT
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "@svadmin/refine-adapter",
3
- "version": "0.9.3",
3
+ "version": "0.10.1",
4
4
  "description": "Universal Refine DataProvider adapter for svadmin",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "files": [
8
- "src/**/*"
8
+ "src/**/*.ts",
9
+ "!src/**/*.test.*",
10
+ "!src/**/*.spec.*",
11
+ "!src/**/vitest.config.*",
12
+ "!src/**/setupTest.*"
9
13
  ],
10
14
  "main": "src/index.ts",
11
15
  "types": "src/index.ts",
@@ -16,12 +20,17 @@
16
20
  }
17
21
  },
18
22
  "peerDependencies": {
19
- "@svadmin/core": "^0.21.0"
23
+ "@svadmin/core": "^0.34.2"
20
24
  },
21
25
  "license": "MIT",
22
26
  "repository": {
23
27
  "type": "git",
24
28
  "url": "https://github.com/zuohuadong/svadmin.git",
25
29
  "directory": "packages/refine-adapter"
30
+ },
31
+ "peerDependenciesMeta": {
32
+ "@svadmin/core": {
33
+ "optional": true
34
+ }
26
35
  }
27
36
  }
package/src/index.ts CHANGED
@@ -1,22 +1,77 @@
1
1
  import type { DataProvider as SvadminDataProvider } from '@svadmin/core';
2
2
 
3
+ type RequiredRefineDataProvider = Pick<
4
+ SvadminDataProvider,
5
+ 'getList' | 'getOne' | 'create' | 'update' | 'deleteOne'
6
+ >;
7
+
8
+ type OptionalRefineDataProvider = Partial<
9
+ Pick<SvadminDataProvider, 'getApiUrl' | 'getMany' | 'createMany' | 'updateMany' | 'deleteMany' | 'custom'>
10
+ >;
11
+
12
+ export type RefineDataProviderLike = RequiredRefineDataProvider & OptionalRefineDataProvider;
13
+
14
+ const requiredMethods = [
15
+ 'getList',
16
+ 'getOne',
17
+ 'create',
18
+ 'update',
19
+ 'deleteOne',
20
+ ] as const satisfies readonly (keyof RequiredRefineDataProvider)[];
21
+
22
+ const optionalMethods = [
23
+ 'getMany',
24
+ 'createMany',
25
+ 'updateMany',
26
+ 'deleteMany',
27
+ 'custom',
28
+ ] as const satisfies readonly (keyof OptionalRefineDataProvider)[];
29
+
30
+ function isObjectLike(value: unknown): value is Record<PropertyKey, unknown> {
31
+ return typeof value === 'object' && value !== null;
32
+ }
33
+
34
+ function assertRefineDataProvider(value: unknown): asserts value is RefineDataProviderLike {
35
+ if (!isObjectLike(value)) {
36
+ throw new Error('[svadmin] createRefineAdapter: expected a valid Refine DataProvider object, got ' + String(value));
37
+ }
38
+
39
+ for (const method of requiredMethods) {
40
+ if (typeof value[method] !== 'function') {
41
+ throw new Error(`[svadmin] createRefineAdapter: missing required Refine DataProvider method "${method}"`);
42
+ }
43
+ }
44
+ }
45
+
3
46
  /**
4
47
  * Adapter to consume an official @refinedev/* data provider in SvelteAdmin.
5
- * Refine's DataProvider interface directly matches the core interface
6
- * definition of @svadmin/core.
48
+ * Refine's DataProvider interface mostly matches the core interface
49
+ * definition of @svadmin/core, except for the current page property.
7
50
  */
8
- export function createRefineAdapter(refineProvider: any): SvadminDataProvider {
9
- return {
10
- getApiUrl: () => refineProvider.getApiUrl(),
11
- getList: refineProvider.getList,
12
- getOne: refineProvider.getOne,
13
- create: refineProvider.create,
14
- update: refineProvider.update,
15
- deleteOne: refineProvider.deleteOne,
16
- getMany: refineProvider.getMany,
17
- createMany: refineProvider.createMany,
18
- updateMany: refineProvider.updateMany,
19
- deleteMany: refineProvider.deleteMany,
20
- custom: refineProvider.custom,
21
- } as SvadminDataProvider;
51
+ export function createRefineAdapter(refineProvider: unknown): SvadminDataProvider {
52
+ assertRefineDataProvider(refineProvider);
53
+
54
+ const adapter: SvadminDataProvider = {
55
+ getApiUrl: () => refineProvider.getApiUrl?.() ?? '',
56
+ getList(params) {
57
+ const pagination = params.pagination?.current === undefined
58
+ ? params.pagination
59
+ : { ...params.pagination, currentPage: params.pagination.current };
60
+ return refineProvider.getList({ ...params, pagination });
61
+ },
62
+ getOne: refineProvider.getOne.bind(refineProvider),
63
+ create: refineProvider.create.bind(refineProvider),
64
+ update: refineProvider.update.bind(refineProvider),
65
+ deleteOne: refineProvider.deleteOne.bind(refineProvider),
66
+ };
67
+
68
+ // Only attach optional methods if they actually exist
69
+ for (const method of optionalMethods) {
70
+ const handler = refineProvider[method];
71
+ if (typeof handler === 'function') {
72
+ adapter[method] = handler.bind(refineProvider) as never;
73
+ }
74
+ }
75
+
76
+ return adapter;
22
77
  }
@@ -0,0 +1,53 @@
1
+ declare module '@refinedev/airtable' {
2
+ export const dataProvider: (...args: unknown[]) => unknown;
3
+ const defaultExport: (...args: unknown[]) => unknown;
4
+ export default defaultExport;
5
+ }
6
+
7
+ declare module '@refinedev/appwrite' {
8
+ export const dataProvider: (...args: unknown[]) => unknown;
9
+ const defaultExport: (...args: unknown[]) => unknown;
10
+ export default defaultExport;
11
+ }
12
+
13
+ declare module '@refinedev/graphql' {
14
+ export const dataProvider: (...args: unknown[]) => unknown;
15
+ const defaultExport: (...args: unknown[]) => unknown;
16
+ export default defaultExport;
17
+ }
18
+
19
+ declare module '@refinedev/hasura' {
20
+ export const dataProvider: (...args: unknown[]) => unknown;
21
+ const defaultExport: (...args: unknown[]) => unknown;
22
+ export default defaultExport;
23
+ }
24
+
25
+ declare module '@refinedev/medusa' {
26
+ export const dataProvider: (...args: unknown[]) => unknown;
27
+ const defaultExport: (...args: unknown[]) => unknown;
28
+ export default defaultExport;
29
+ }
30
+
31
+ declare module '@refinedev/nestjs-query' {
32
+ export const dataProvider: (...args: unknown[]) => unknown;
33
+ const defaultExport: (...args: unknown[]) => unknown;
34
+ export default defaultExport;
35
+ }
36
+
37
+ declare module '@refinedev/nestjsx-crud' {
38
+ export const dataProvider: (...args: unknown[]) => unknown;
39
+ const defaultExport: (...args: unknown[]) => unknown;
40
+ export default defaultExport;
41
+ }
42
+
43
+ declare module '@refinedev/strapi-v4' {
44
+ export const dataProvider: (...args: unknown[]) => unknown;
45
+ const defaultExport: (...args: unknown[]) => unknown;
46
+ export default defaultExport;
47
+ }
48
+
49
+ declare module '@refinedev/supabase' {
50
+ export const dataProvider: (...args: unknown[]) => unknown;
51
+ const defaultExport: (...args: unknown[]) => unknown;
52
+ export default defaultExport;
53
+ }