@svadmin/pocketbase 0.9.6 → 0.9.8

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/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "@svadmin/pocketbase",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
4
4
  "description": "PocketBase adapters — DataProvider, AuthProvider, LiveProvider 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,7 +20,7 @@
16
20
  }
17
21
  },
18
22
  "peerDependencies": {
19
- "@svadmin/core": "^0.23.3",
23
+ "@svadmin/core": "^0.27.1",
20
24
  "pocketbase": ">=0.21.0"
21
25
  },
22
26
  "keywords": [
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  // @svadmin/pocketbase — PocketBase DataProvider
2
3
  // Maps svadmin CRUD operations to PocketBase SDK
3
4
 
@@ -1,212 +0,0 @@
1
- // @svadmin/pocketbase — Unit Tests
2
- import { describe, test, expect, mock } from 'bun:test';
3
- import { createPocketBaseDataProvider } from './data-provider';
4
- import { createPocketBaseAuthProvider } from './auth-provider';
5
- import { createPocketBaseLiveProvider } from './live-provider';
6
-
7
- // ─── Mock PocketBase Client ─────────────────────────────────
8
-
9
- function createMockPB() {
10
- const mockCollection = {
11
- getList: mock(async () => ({
12
- items: [{ id: '1', name: 'Test' }, { id: '2', name: 'Test2' }],
13
- totalItems: 2,
14
- })),
15
- getOne: mock(async (id: string) => ({ id, name: 'Test' })),
16
- getFullList: mock(async () => [{ id: '1' }, { id: '2' }]),
17
- create: mock(async (data: Record<string, unknown>) => ({ id: 'new-1', ...data })),
18
- update: mock(async (id: string, data: Record<string, unknown>) => ({ id, ...data })),
19
- delete: mock(async () => true),
20
- subscribe: mock(async () => {}),
21
- unsubscribe: mock(async () => {}),
22
- authWithPassword: mock(async () => ({ record: { id: 'user-1' }, token: 'tok' })),
23
- requestPasswordReset: mock(async () => true),
24
- confirmPasswordReset: mock(async () => true),
25
- };
26
-
27
- return {
28
- pb: {
29
- collection: mock(() => mockCollection),
30
- buildUrl: mock((path: string) => `http://localhost:8090${path}`),
31
- authStore: {
32
- isValid: true,
33
- model: { id: 'user-1', name: 'Admin', email: 'admin@test.com' },
34
- clear: mock(() => {}),
35
- token: 'test-token',
36
- },
37
- },
38
- mockCollection,
39
- };
40
- }
41
-
42
- // ─── DataProvider Tests ─────────────────────────────────────
43
-
44
- describe('PocketBase DataProvider', () => {
45
- test('getList returns data with total', async () => {
46
- const { pb } = createMockPB();
47
- const dp = createPocketBaseDataProvider({ pb });
48
- const result = await dp.getList({ resource: 'posts' });
49
- expect(result.data).toHaveLength(2);
50
- expect(result.total).toBe(2);
51
- });
52
-
53
- test('getList passes pagination', async () => {
54
- const { pb, mockCollection } = createMockPB();
55
- const dp = createPocketBaseDataProvider({ pb });
56
- await dp.getList({ resource: 'posts', pagination: { current: 3, pageSize: 20 } });
57
- expect(mockCollection.getList).toHaveBeenCalledWith(3, 20, expect.anything());
58
- });
59
-
60
- test('getList passes sorters', async () => {
61
- const { pb, mockCollection } = createMockPB();
62
- const dp = createPocketBaseDataProvider({ pb });
63
- await dp.getList({ resource: 'posts', sorters: [{ field: 'name', order: 'desc' }] });
64
- const opts = (mockCollection.getList.mock.calls as any)[0][2] as { sort?: string };
65
- expect(opts.sort).toBe('-name');
66
- });
67
-
68
- test('getList passes filters', async () => {
69
- const { pb, mockCollection } = createMockPB();
70
- const dp = createPocketBaseDataProvider({ pb });
71
- await dp.getList({ resource: 'posts', filters: [{ field: 'status', operator: 'eq', value: 'active' }] });
72
- const opts = (mockCollection.getList.mock.calls as any)[0][2] as { filter?: string };
73
- expect(opts.filter).toContain("status = 'active'");
74
- });
75
-
76
- test('getOne returns single record', async () => {
77
- const { pb } = createMockPB();
78
- const dp = createPocketBaseDataProvider({ pb });
79
- const result = await dp.getOne({ resource: 'posts', id: '1' });
80
- expect(result.data).toHaveProperty('id', '1');
81
- });
82
-
83
- test('create returns new record', async () => {
84
- const { pb } = createMockPB();
85
- const dp = createPocketBaseDataProvider({ pb });
86
- const result = await dp.create({ resource: 'posts', variables: { name: 'New' } });
87
- expect(result.data).toHaveProperty('name', 'New');
88
- });
89
-
90
- test('update returns updated record', async () => {
91
- const { pb } = createMockPB();
92
- const dp = createPocketBaseDataProvider({ pb });
93
- const result = await dp.update({ resource: 'posts', id: '1', variables: { name: 'Updated' } });
94
- expect(result.data).toHaveProperty('name', 'Updated');
95
- });
96
-
97
- test('deleteOne calls delete', async () => {
98
- const { pb, mockCollection } = createMockPB();
99
- const dp = createPocketBaseDataProvider({ pb });
100
- await dp.deleteOne({ resource: 'posts', id: '1' });
101
- expect(mockCollection.delete).toHaveBeenCalledWith('1');
102
- });
103
-
104
- test('getMany fetches all ids', async () => {
105
- const { pb, mockCollection } = createMockPB();
106
- const dp = createPocketBaseDataProvider({ pb });
107
- const result = await dp.getMany!({ resource: 'posts', ids: ['1', '2'] });
108
- expect(result.data).toHaveLength(2);
109
- const filterArg = (mockCollection.getFullList.mock.calls as any)[0][0] as { filter?: string };
110
- expect(filterArg.filter).toContain("id = '1'");
111
- });
112
-
113
- test('deleteMany deletes each', async () => {
114
- const { pb, mockCollection } = createMockPB();
115
- const dp = createPocketBaseDataProvider({ pb });
116
- await dp.deleteMany!({ resource: 'posts', ids: ['1', '2'] });
117
- expect(mockCollection.delete).toHaveBeenCalledTimes(2);
118
- });
119
-
120
- test('getApiUrl returns correct url', () => {
121
- const { pb } = createMockPB();
122
- const dp = createPocketBaseDataProvider({ pb });
123
- expect(dp.getApiUrl()).toBe('http://localhost:8090/api');
124
- });
125
- });
126
-
127
- // ─── AuthProvider Tests ─────────────────────────────────────
128
-
129
- describe('PocketBase AuthProvider', () => {
130
- test('login success', async () => {
131
- const { pb } = createMockPB();
132
- const auth = createPocketBaseAuthProvider({ pb });
133
- const result = await auth.login({ email: 'admin@test.com', password: 'pass' });
134
- expect(result.success).toBe(true);
135
- expect(result.redirectTo).toBe('/');
136
- });
137
-
138
- test('login failure', async () => {
139
- const { pb, mockCollection } = createMockPB();
140
- mockCollection.authWithPassword = mock(async () => { throw new Error('Invalid credentials'); });
141
- const auth = createPocketBaseAuthProvider({ pb });
142
- const result = await auth.login({ email: 'bad', password: 'bad' });
143
- expect(result.success).toBe(false);
144
- expect(result.error?.message).toBe('Invalid credentials');
145
- });
146
-
147
- test('logout clears auth store', async () => {
148
- const { pb } = createMockPB();
149
- const auth = createPocketBaseAuthProvider({ pb });
150
- const result = await auth.logout();
151
- expect(result.success).toBe(true);
152
- expect(pb.authStore.clear).toHaveBeenCalledTimes(1);
153
- });
154
-
155
- test('check returns authenticated when valid', async () => {
156
- const { pb } = createMockPB();
157
- const auth = createPocketBaseAuthProvider({ pb });
158
- const result = await auth.check();
159
- expect(result.authenticated).toBe(true);
160
- });
161
-
162
- test('check returns not authenticated when invalid', async () => {
163
- const { pb } = createMockPB();
164
- pb.authStore.isValid = false;
165
- const auth = createPocketBaseAuthProvider({ pb });
166
- const result = await auth.check();
167
- expect(result.authenticated).toBe(false);
168
- });
169
-
170
- test('getIdentity returns user', async () => {
171
- const { pb } = createMockPB();
172
- const auth = createPocketBaseAuthProvider({ pb });
173
- const identity = await auth.getIdentity();
174
- expect(identity).not.toBeNull();
175
- expect(identity!.name).toBe('Admin');
176
- });
177
-
178
- test('getIdentity returns null when no model', async () => {
179
- const { pb } = createMockPB();
180
- pb.authStore.model = null as unknown as typeof pb.authStore.model;
181
- const auth = createPocketBaseAuthProvider({ pb });
182
- const identity = await auth.getIdentity();
183
- expect(identity).toBeNull();
184
- });
185
-
186
- test('register success', async () => {
187
- const { pb } = createMockPB();
188
- const auth = createPocketBaseAuthProvider({ pb });
189
- const result = await auth.register!({ email: 'new@test.com', password: 'pass', passwordConfirm: 'pass' });
190
- expect(result.success).toBe(true);
191
- });
192
- });
193
-
194
- // ─── LiveProvider Tests ─────────────────────────────────────
195
-
196
- describe('PocketBase LiveProvider', () => {
197
- test('subscribe calls pb.collection().subscribe', () => {
198
- const { pb, mockCollection } = createMockPB();
199
- const lp = createPocketBaseLiveProvider({ pb });
200
- const cb = mock(() => {});
201
- lp.subscribe({ resource: 'posts', callback: cb });
202
- expect(mockCollection.subscribe).toHaveBeenCalledWith('*', expect.any(Function));
203
- });
204
-
205
- test('unsubscribe calls pb.collection().unsubscribe', () => {
206
- const { pb, mockCollection } = createMockPB();
207
- const lp = createPocketBaseLiveProvider({ pb });
208
- const unsub = lp.subscribe({ resource: 'posts', callback: () => {} });
209
- unsub();
210
- expect(mockCollection.unsubscribe).toHaveBeenCalledWith('*', expect.any(Function));
211
- });
212
- });