@taruvi/sdk 1.3.7-beta.0 → 1.3.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/.github/{workflows → worflows}/publish.yml +2 -2
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/lib/users/UserClient.ts +9 -1
- package/src/lib/users/types.ts +18 -0
- package/src/lib-internal/routes/UserRoutes.ts +1 -0
- package/tests/unit/database/DatabaseClient.test.ts +5 -5
- package/tests/unit/edge-cases/robustness.test.ts +1 -1
- package/tests/unit/graphs/GraphClient.test.ts +14 -14
- package/tests/unit/storage/StorageClient.test.ts +1 -1
|
@@ -50,8 +50,8 @@ jobs:
|
|
|
50
50
|
git tag "v${{ steps.version_check.outputs.current_version }}"
|
|
51
51
|
git push origin "v${{ steps.version_check.outputs.current_version }}"
|
|
52
52
|
|
|
53
|
-
- name: Publish (
|
|
53
|
+
- name: Publish (main)
|
|
54
54
|
if: steps.version_check.outputs.changed == 'true'
|
|
55
|
-
run: npm publish --access public
|
|
55
|
+
run: npm publish --access public
|
|
56
56
|
env:
|
|
57
57
|
NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -24,7 +24,7 @@ export type { TaruviConfig, TaruviResponse, PaginationInfo, StorageFilters, Data
|
|
|
24
24
|
export type { AuthTokens } from "./lib-internal/token/TokenClient.js"
|
|
25
25
|
|
|
26
26
|
// User types
|
|
27
|
-
export type { UserCreateRequest, UserData, UserUpdateRequest, UserListFilters, UserApp, UserResponse, UserListResponse, UserAppsResponse, AssignRolesRequest, RevokeRolesRequest, RolesResponse, UserGroup, UserPermission, UserRole } from "./lib/users/types.js"
|
|
27
|
+
export type { UserCreateRequest, UserData, UserUpdateRequest, UserListFilters, UserApp, UserResponse, UserListResponse, UserAppsResponse, AssignRolesRequest, RevokeRolesRequest, RolesResponse, UserGroup, UserPermission, UserRole, UserPreferences, UserPreferencesUpdate, UserPreferencesResponse } from "./lib/users/types.js"
|
|
28
28
|
|
|
29
29
|
// Policy types
|
|
30
30
|
export type { Principal, Resource, Resources, PolicyCheckResult, PolicyCheckBatchResult, ResourceCheckResponse } from "./lib/policy/types.js"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Client } from "../../client.js";
|
|
2
|
-
import type { UserCreateRequest, UserResponse, UserListResponse, UserListFilters, UserUpdateRequest, UserAppsResponse, AssignRolesRequest, RevokeRolesRequest, RolesResponse } from "./types.js";
|
|
2
|
+
import type { UserCreateRequest, UserResponse, UserListResponse, UserListFilters, UserUpdateRequest, UserAppsResponse, AssignRolesRequest, RevokeRolesRequest, RolesResponse, UserPreferencesResponse, UserPreferencesUpdate } from "./types.js";
|
|
3
3
|
import { UserRoutes } from "../../lib-internal/routes/UserRoutes.js";
|
|
4
4
|
import { buildQueryString } from "../../utils/utils.js";
|
|
5
5
|
|
|
@@ -52,4 +52,12 @@ export class User {
|
|
|
52
52
|
request
|
|
53
53
|
)
|
|
54
54
|
}
|
|
55
|
+
|
|
56
|
+
async getPreferences(): Promise<UserPreferencesResponse> {
|
|
57
|
+
return await this.client.httpClient.get<UserPreferencesResponse>(UserRoutes.getPreferences())
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async updatePreferences(body: UserPreferencesUpdate): Promise<UserPreferencesResponse> {
|
|
61
|
+
return await this.client.httpClient.put<UserPreferencesResponse>(UserRoutes.getPreferences(), body)
|
|
62
|
+
}
|
|
55
63
|
}
|
package/src/lib/users/types.ts
CHANGED
|
@@ -88,6 +88,24 @@ export type UserResponse = TaruviResponse<UserData>
|
|
|
88
88
|
export type UserListResponse = TaruviResponse<UserData[]>
|
|
89
89
|
export type UserAppsResponse = TaruviResponse<UserApp[]>
|
|
90
90
|
|
|
91
|
+
export interface UserPreferences {
|
|
92
|
+
date_format: string
|
|
93
|
+
time_format: string
|
|
94
|
+
timezone: string
|
|
95
|
+
theme: string
|
|
96
|
+
widget_config: Record<string, unknown>
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface UserPreferencesUpdate {
|
|
100
|
+
date_format?: string
|
|
101
|
+
time_format?: string
|
|
102
|
+
timezone?: string
|
|
103
|
+
theme?: string
|
|
104
|
+
widget_config?: Record<string, unknown>
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export type UserPreferencesResponse = TaruviResponse<UserPreferences>
|
|
108
|
+
|
|
91
109
|
export interface AssignRolesRequest {
|
|
92
110
|
roles: string[]
|
|
93
111
|
usernames: string[]
|
|
@@ -6,6 +6,7 @@ export const UserRoutes = {
|
|
|
6
6
|
deleteUser: (username: string) => `${UserRoutes.baseUrl}${username}/`,
|
|
7
7
|
listUser: (filter: string) => `${UserRoutes.baseUrl}${filter}`,
|
|
8
8
|
getUserApps: (username: string) => `${UserRoutes.baseUrl}${username}/apps/`,
|
|
9
|
+
getPreferences: () => `${UserRoutes.baseUrl}me/preferences/`,
|
|
9
10
|
assignRoles: () => `api/assign/roles/`,
|
|
10
11
|
revokeRoles: () => `api/revoke/roles/`
|
|
11
12
|
} as const
|
|
@@ -182,19 +182,19 @@ describe('Database', () => {
|
|
|
182
182
|
|
|
183
183
|
describe('first()', () => {
|
|
184
184
|
it('returns first item from array', async () => {
|
|
185
|
-
mockHttpClient.get.mockResolvedValue(
|
|
185
|
+
mockHttpClient.get.mockResolvedValue([{ id: '1' }, { id: '2' }])
|
|
186
186
|
const result = await new Database(mockClient).from('accounts').first()
|
|
187
187
|
expect(result).toEqual({ id: '1' })
|
|
188
188
|
})
|
|
189
189
|
|
|
190
190
|
it('returns null for empty array', async () => {
|
|
191
|
-
mockHttpClient.get.mockResolvedValue(
|
|
191
|
+
mockHttpClient.get.mockResolvedValue([])
|
|
192
192
|
const result = await new Database(mockClient).from('accounts').first()
|
|
193
193
|
expect(result).toBeNull()
|
|
194
194
|
})
|
|
195
195
|
|
|
196
196
|
it('returns single item if not array', async () => {
|
|
197
|
-
mockHttpClient.get.mockResolvedValue({
|
|
197
|
+
mockHttpClient.get.mockResolvedValue({ id: '1' })
|
|
198
198
|
const result = await new Database(mockClient).from('accounts').get('1').first()
|
|
199
199
|
expect(result).toEqual({ id: '1' })
|
|
200
200
|
})
|
|
@@ -202,13 +202,13 @@ describe('Database', () => {
|
|
|
202
202
|
|
|
203
203
|
describe('count()', () => {
|
|
204
204
|
it('returns array length', async () => {
|
|
205
|
-
mockHttpClient.get.mockResolvedValue(
|
|
205
|
+
mockHttpClient.get.mockResolvedValue([{ id: '1' }, { id: '2' }, { id: '3' }])
|
|
206
206
|
const result = await new Database(mockClient).from('accounts').count()
|
|
207
207
|
expect(result).toBe(3)
|
|
208
208
|
})
|
|
209
209
|
|
|
210
210
|
it('returns 0 for non-array', async () => {
|
|
211
|
-
mockHttpClient.get.mockResolvedValue({
|
|
211
|
+
mockHttpClient.get.mockResolvedValue({ id: '1' })
|
|
212
212
|
const result = await new Database(mockClient).from('accounts').get('1').count()
|
|
213
213
|
expect(result).toBe(0)
|
|
214
214
|
})
|
|
@@ -248,7 +248,7 @@ describe('Builder immutability', () => {
|
|
|
248
248
|
mockHttpClient.post.mockResolvedValue({})
|
|
249
249
|
const base = new Graph(mockClient).from('employees')
|
|
250
250
|
const traversal = base.get('1').include('descendants')
|
|
251
|
-
const edge = base.
|
|
251
|
+
const edge = base.createEdge([{ from: 1, to: 2, type: 'manager' }])
|
|
252
252
|
|
|
253
253
|
await traversal.execute()
|
|
254
254
|
await edge.execute()
|
|
@@ -123,48 +123,48 @@ describe('Graph', () => {
|
|
|
123
123
|
})
|
|
124
124
|
|
|
125
125
|
describe('edge CRUD', () => {
|
|
126
|
-
it('
|
|
126
|
+
it('listEdges() calls GET on edges route', async () => {
|
|
127
127
|
mockHttpClient.get.mockResolvedValue({ edges: [], total: 0 })
|
|
128
|
-
await new Graph(mockClient).from('employees').
|
|
128
|
+
await new Graph(mockClient).from('employees').listEdges().execute()
|
|
129
129
|
expect(mockHttpClient.get).toHaveBeenCalledWith('api/apps/test-app/datatables/employees/edges/')
|
|
130
130
|
})
|
|
131
131
|
|
|
132
|
-
it('
|
|
132
|
+
it('createEdge() calls POST with array of edges', async () => {
|
|
133
133
|
const edges = [
|
|
134
134
|
{ from: 5, to: 2, type: 'manager' },
|
|
135
135
|
{ from: 5, to: 3, type: 'dotted_line', metadata: { project: 'AI' } }
|
|
136
136
|
]
|
|
137
137
|
mockHttpClient.post.mockResolvedValue({ status: 'success', data: edges, total: 2 })
|
|
138
|
-
await new Graph(mockClient).from('employees').
|
|
138
|
+
await new Graph(mockClient).from('employees').createEdge(edges).execute()
|
|
139
139
|
expect(mockHttpClient.post).toHaveBeenCalledWith(
|
|
140
140
|
'api/apps/test-app/datatables/employees/edges/',
|
|
141
141
|
edges
|
|
142
142
|
)
|
|
143
143
|
})
|
|
144
144
|
|
|
145
|
-
it('
|
|
145
|
+
it('createEdge() with metadata', async () => {
|
|
146
146
|
const edges = [{ from: 5, to: 3, type: 'dotted_line', metadata: { percentage: 30 } }]
|
|
147
147
|
mockHttpClient.post.mockResolvedValue({ status: 'success', data: edges, total: 1 })
|
|
148
|
-
await new Graph(mockClient).from('employees').
|
|
148
|
+
await new Graph(mockClient).from('employees').createEdge(edges).execute()
|
|
149
149
|
expect(mockHttpClient.post).toHaveBeenCalledWith(
|
|
150
150
|
'api/apps/test-app/datatables/employees/edges/',
|
|
151
151
|
edges
|
|
152
152
|
)
|
|
153
153
|
})
|
|
154
154
|
|
|
155
|
-
it('
|
|
155
|
+
it('updateEdge() calls PATCH with edge ID in URL', async () => {
|
|
156
156
|
const edge = { from: 5, to: 3, type: 'dotted_line' }
|
|
157
157
|
mockHttpClient.patch.mockResolvedValue({ id: 9, ...edge })
|
|
158
|
-
await new Graph(mockClient).from('employees').
|
|
158
|
+
await new Graph(mockClient).from('employees').updateEdge('9', edge).execute()
|
|
159
159
|
expect(mockHttpClient.patch).toHaveBeenCalledWith(
|
|
160
160
|
'api/apps/test-app/datatables/employees/edges/9/',
|
|
161
161
|
edge
|
|
162
162
|
)
|
|
163
163
|
})
|
|
164
164
|
|
|
165
|
-
it('
|
|
165
|
+
it('deleteEdge() calls DELETE with edge_ids object', async () => {
|
|
166
166
|
mockHttpClient.delete.mockResolvedValue({ deleted: 2 })
|
|
167
|
-
await new Graph(mockClient).from('employees').
|
|
167
|
+
await new Graph(mockClient).from('employees').deleteEdge([9, 10]).execute()
|
|
168
168
|
expect(mockHttpClient.delete).toHaveBeenCalledWith(
|
|
169
169
|
'api/apps/test-app/datatables/employees/edges/',
|
|
170
170
|
{ edge_ids: [9, 10] }
|
|
@@ -290,7 +290,7 @@ describe('Graph', () => {
|
|
|
290
290
|
total: 2
|
|
291
291
|
}
|
|
292
292
|
mockHttpClient.get.mockResolvedValue(mockResponse)
|
|
293
|
-
const result = await new Graph(mockClient).from('employees').
|
|
293
|
+
const result = await new Graph(mockClient).from('employees').listEdges().execute()
|
|
294
294
|
expect((result as any).edges).toHaveLength(2)
|
|
295
295
|
expect((result as any).edges[0].type).toBe('manager')
|
|
296
296
|
expect((result as any).total).toBe(2)
|
|
@@ -306,7 +306,7 @@ describe('Graph', () => {
|
|
|
306
306
|
total: 1
|
|
307
307
|
}
|
|
308
308
|
mockHttpClient.post.mockResolvedValue(mockResponse)
|
|
309
|
-
const result = await new Graph(mockClient).from('employees').
|
|
309
|
+
const result = await new Graph(mockClient).from('employees').createEdge([{ from: 5, to: 2, type: 'manager' }]).execute() as TaruviResponse<EdgeResponse[]>
|
|
310
310
|
expect(result.data).toHaveLength(1)
|
|
311
311
|
expect(result.data[0].id).toBe(10)
|
|
312
312
|
})
|
|
@@ -314,7 +314,7 @@ describe('Graph', () => {
|
|
|
314
314
|
it('returns updated edge matching EdgeResponse type', async () => {
|
|
315
315
|
const mockResponse: EdgeResponse = { id: 9, from: 5, to: 3, type: 'dotted_line', metadata: {} }
|
|
316
316
|
mockHttpClient.patch.mockResolvedValue(mockResponse)
|
|
317
|
-
const result = await new Graph(mockClient).from('employees').
|
|
317
|
+
const result = await new Graph(mockClient).from('employees').updateEdge('9', { from: 5, to: 3, type: 'dotted_line' }).execute() as EdgeResponse
|
|
318
318
|
expect(result.id).toBe(9)
|
|
319
319
|
expect(result.type).toBe('dotted_line')
|
|
320
320
|
})
|
|
@@ -322,7 +322,7 @@ describe('Graph', () => {
|
|
|
322
322
|
it('returns delete count response', async () => {
|
|
323
323
|
const mockResponse = { deleted: 3 }
|
|
324
324
|
mockHttpClient.delete.mockResolvedValue(mockResponse)
|
|
325
|
-
const result = await new Graph(mockClient).from('employees').
|
|
325
|
+
const result = await new Graph(mockClient).from('employees').deleteEdge([1, 2, 3]).execute()
|
|
326
326
|
expect((result as any).deleted).toBe(3)
|
|
327
327
|
})
|
|
328
328
|
})
|
|
@@ -148,7 +148,7 @@ describe('Storage', () => {
|
|
|
148
148
|
mockHttpClient.get.mockResolvedValue(new Blob())
|
|
149
149
|
await new Storage(mockClient).from('documents').download('folder/file name.pdf').execute()
|
|
150
150
|
expect(mockHttpClient.get).toHaveBeenCalledWith(
|
|
151
|
-
'api/apps/test-app/storage/buckets/documents/objects/folder%2Ffile%20name.pdf
|
|
151
|
+
'api/apps/test-app/storage/buckets/documents/objects/folder%2Ffile%20name.pdf/'
|
|
152
152
|
)
|
|
153
153
|
})
|
|
154
154
|
|