@taruvi/sdk 1.3.7-beta.0 → 1.3.8-beta.0
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 +1 -1
- package/src/index.ts +1 -1
- package/src/lib/auth/types.ts +22 -10
- package/src/lib/database/DatabaseClient.ts +28 -0
- package/src/lib/database/types.ts +28 -8
- package/src/lib/functions/types.ts +2 -0
- package/src/lib/settings/SettingsClient.ts +8 -0
- package/src/lib/storage/types.ts +2 -2
- package/src/lib/users/UserClient.ts +9 -1
- package/src/lib/users/types.ts +18 -0
- package/src/lib-internal/routes/GraphRoutes.ts +1 -1
- package/src/lib-internal/routes/SettingsRoutes.ts +2 -1
- package/src/lib-internal/routes/UserRoutes.ts +1 -0
- package/src/types.ts +8 -0
- package/tests/unit/edge-cases/robustness.test.ts +1 -1
- package/tests/unit/graphs/GraphClient.test.ts +5 -5
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"
|
package/src/lib/auth/types.ts
CHANGED
|
@@ -13,17 +13,23 @@ export interface UserCreateRequest {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface UserCreateResponse {
|
|
16
|
-
id:
|
|
17
|
-
uuid: string
|
|
16
|
+
id: string
|
|
18
17
|
username: string
|
|
19
18
|
email: string
|
|
20
19
|
first_name: string
|
|
21
20
|
last_name: string
|
|
21
|
+
full_name: string
|
|
22
22
|
is_active: boolean
|
|
23
|
-
is_staff: boolean
|
|
24
23
|
is_superuser: boolean
|
|
25
24
|
is_deleted: boolean
|
|
26
25
|
date_joined: string
|
|
26
|
+
last_login: string
|
|
27
|
+
groups: UserGroup[]
|
|
28
|
+
user_permissions: UserPermission[]
|
|
29
|
+
attributes: Record<string, unknown>
|
|
30
|
+
missing_attributes: string[]
|
|
31
|
+
roles: UserRole[]
|
|
32
|
+
icon_url: string | null
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
export interface UserGroup {
|
|
@@ -47,23 +53,23 @@ export interface UserRole {
|
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
export interface UserDataResponse {
|
|
50
|
-
id:
|
|
56
|
+
id: string
|
|
51
57
|
username: string
|
|
52
58
|
email: string
|
|
53
59
|
first_name: string
|
|
54
60
|
last_name: string
|
|
55
61
|
full_name: string
|
|
56
62
|
is_active: boolean
|
|
57
|
-
is_staff: boolean
|
|
58
63
|
is_superuser: boolean
|
|
59
64
|
is_deleted: boolean
|
|
60
|
-
date_joined: string
|
|
61
|
-
last_login: string
|
|
65
|
+
date_joined: string
|
|
66
|
+
last_login: string
|
|
62
67
|
groups: UserGroup[]
|
|
63
68
|
user_permissions: UserPermission[]
|
|
64
69
|
attributes: Record<string, unknown>
|
|
65
70
|
missing_attributes: string[]
|
|
66
71
|
roles: UserRole[]
|
|
72
|
+
icon_url: string | null
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
export interface UserUpdateRequest {
|
|
@@ -76,17 +82,23 @@ export interface UserUpdateRequest {
|
|
|
76
82
|
}
|
|
77
83
|
|
|
78
84
|
export interface UserUpdateResponse {
|
|
79
|
-
id:
|
|
80
|
-
uuid: string
|
|
85
|
+
id: string
|
|
81
86
|
username: string
|
|
82
87
|
email: string
|
|
83
88
|
first_name: string
|
|
84
89
|
last_name: string
|
|
90
|
+
full_name: string
|
|
85
91
|
is_active: boolean
|
|
86
|
-
is_staff: boolean
|
|
87
92
|
is_superuser: boolean
|
|
88
93
|
is_deleted: boolean
|
|
89
94
|
date_joined: string
|
|
95
|
+
last_login: string
|
|
96
|
+
groups: UserGroup[]
|
|
97
|
+
user_permissions: UserPermission[]
|
|
98
|
+
attributes: Record<string, unknown>
|
|
99
|
+
missing_attributes: string[]
|
|
100
|
+
roles: UserRole[]
|
|
101
|
+
icon_url: string | null
|
|
90
102
|
}
|
|
91
103
|
|
|
92
104
|
export interface UserList {
|
|
@@ -66,6 +66,34 @@ export class Database<T = Record<string, unknown>> {
|
|
|
66
66
|
})
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
search(query: string): Database<T> {
|
|
70
|
+
return new Database<T>(this.client, { ...this.urlParams }, undefined, undefined, {
|
|
71
|
+
...this.queryParams,
|
|
72
|
+
search: query
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
aggregate(...expressions: string[]): Database<T> {
|
|
77
|
+
return new Database<T>(this.client, { ...this.urlParams }, undefined, undefined, {
|
|
78
|
+
...this.queryParams,
|
|
79
|
+
_aggregate: expressions.join(',')
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
groupBy(...fields: string[]): Database<T> {
|
|
84
|
+
return new Database<T>(this.client, { ...this.urlParams }, undefined, undefined, {
|
|
85
|
+
...this.queryParams,
|
|
86
|
+
_group_by: fields.join(',')
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
having(condition: string): Database<T> {
|
|
91
|
+
return new Database<T>(this.client, { ...this.urlParams }, undefined, undefined, {
|
|
92
|
+
...this.queryParams,
|
|
93
|
+
_having: condition
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
69
97
|
get(recordId: string): Database<T> {
|
|
70
98
|
return new Database<T>(this.client, { ...this.urlParams, recordId }, HttpMethod.GET)
|
|
71
99
|
}
|
|
@@ -4,23 +4,43 @@ import type { TaruviResponse } from "../../types.js"
|
|
|
4
4
|
|
|
5
5
|
export type DatabaseOperation = HttpMethod
|
|
6
6
|
|
|
7
|
-
// Filter operators matching
|
|
7
|
+
// Filter operators matching backend FilterParams.OPERATORS (32 operators)
|
|
8
8
|
export type FilterOperator =
|
|
9
|
+
// Comparison
|
|
9
10
|
| 'eq' // Equal
|
|
10
11
|
| 'ne' // Not equal
|
|
11
12
|
| 'gt' // Greater than
|
|
12
13
|
| 'gte' // Greater than or equal
|
|
13
14
|
| 'lt' // Less than
|
|
14
15
|
| 'lte' // Less than or equal
|
|
16
|
+
// IN operators
|
|
15
17
|
| 'in' // In array
|
|
16
18
|
| 'nin' // Not in array
|
|
17
|
-
| '
|
|
18
|
-
| '
|
|
19
|
-
|
|
20
|
-
| '
|
|
21
|
-
| '
|
|
22
|
-
| '
|
|
23
|
-
| '
|
|
19
|
+
| 'ina' // In array (case-insensitive)
|
|
20
|
+
| 'nina' // Not in array (case-insensitive)
|
|
21
|
+
// String contains
|
|
22
|
+
| 'contains' // Contains (case-sensitive)
|
|
23
|
+
| 'ncontains' // Not contains (case-sensitive)
|
|
24
|
+
| 'containss' // Contains (case-sensitive, strict)
|
|
25
|
+
| 'ncontainss' // Not contains (case-sensitive, strict)
|
|
26
|
+
| 'icontains' // Contains (case-insensitive)
|
|
27
|
+
| 'nicontains' // Not contains (case-insensitive)
|
|
28
|
+
// Starts with
|
|
29
|
+
| 'startswith' // Starts with (case-sensitive)
|
|
30
|
+
| 'nstartswith' // Not starts with (case-sensitive)
|
|
31
|
+
| 'startswiths' // Starts with (case-sensitive, strict)
|
|
32
|
+
| 'nstartswiths' // Not starts with (case-sensitive, strict)
|
|
33
|
+
// Ends with
|
|
34
|
+
| 'endswith' // Ends with (case-sensitive)
|
|
35
|
+
| 'nendswith' // Not ends with (case-sensitive)
|
|
36
|
+
| 'endswiths' // Ends with (case-sensitive, strict)
|
|
37
|
+
| 'nendswiths' // Not ends with (case-sensitive, strict)
|
|
38
|
+
// Range
|
|
39
|
+
| 'between' // Between two values
|
|
40
|
+
| 'nbetween' // Not between two values
|
|
41
|
+
// Null checks
|
|
42
|
+
| 'null' // Is null
|
|
43
|
+
| 'nnull' // Is not null
|
|
24
44
|
|
|
25
45
|
export type SortOrder = 'asc' | 'desc'
|
|
26
46
|
|
|
@@ -11,4 +11,12 @@ export class Settings {
|
|
|
11
11
|
async get<T = unknown>(): Promise<T> {
|
|
12
12
|
return await this.client.httpClient.get<T>(SettingsRoutes.metadata)
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
async getUserAttributes<T = unknown>(): Promise<T> {
|
|
16
|
+
return await this.client.httpClient.get<T>(SettingsRoutes.userAttributes)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async updateUserAttributes<T = unknown>(schema: Record<string, unknown>): Promise<T> {
|
|
20
|
+
return await this.client.httpClient.post<T>(SettingsRoutes.userAttributes, schema)
|
|
21
|
+
}
|
|
14
22
|
}
|
package/src/lib/storage/types.ts
CHANGED
|
@@ -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.preferences())
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async updatePreferences(body: UserPreferencesUpdate): Promise<UserPreferencesResponse> {
|
|
61
|
+
return await this.client.httpClient.put<UserPreferencesResponse>(UserRoutes.preferences(), 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,7 +6,7 @@ export const GraphRoutes = {
|
|
|
6
6
|
|
|
7
7
|
export const GraphEdgeRoutes = {
|
|
8
8
|
baseUrl: (appSlug: string) => `api/apps/${appSlug}`,
|
|
9
|
-
edges: (tableName: string): string => `/datatables/${tableName}/
|
|
9
|
+
edges: (tableName: string): string => `/datatables/${tableName}_edges/data`,
|
|
10
10
|
edgeId: (edgeId: string): string => `/${edgeId}`
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const UserRoutes = {
|
|
2
2
|
baseUrl: "api/users/",
|
|
3
3
|
getCurrentUser: () => `${UserRoutes.baseUrl}me/`,
|
|
4
|
+
preferences: () => `${UserRoutes.baseUrl}me/preferences/`,
|
|
4
5
|
getUser: (username: string) => `${UserRoutes.baseUrl}${username}/`,
|
|
5
6
|
updateUser: (username: string) => `${UserRoutes.baseUrl}${username}/`,
|
|
6
7
|
deleteUser: (username: string) => `${UserRoutes.baseUrl}${username}/`,
|
package/src/types.ts
CHANGED
|
@@ -85,6 +85,14 @@ export interface DatabaseFilters {
|
|
|
85
85
|
// Populate relations
|
|
86
86
|
populate?: string
|
|
87
87
|
|
|
88
|
+
// Search (translates to search_vector__search on backend)
|
|
89
|
+
search?: string
|
|
90
|
+
|
|
91
|
+
// Aggregates
|
|
92
|
+
_aggregate?: string
|
|
93
|
+
_group_by?: string
|
|
94
|
+
_having?: string
|
|
95
|
+
|
|
88
96
|
// Dynamic filters - allows any field with operators
|
|
89
97
|
[key: string]: string | number | boolean | undefined
|
|
90
98
|
}
|
|
@@ -254,6 +254,6 @@ describe('Builder immutability', () => {
|
|
|
254
254
|
await edge.execute()
|
|
255
255
|
|
|
256
256
|
expect(mockHttpClient.get.mock.calls[0][0]).toContain('/data/1/')
|
|
257
|
-
expect(mockHttpClient.post.mock.calls[0][0]).toContain('/
|
|
257
|
+
expect(mockHttpClient.post.mock.calls[0][0]).toContain('_edges/data/')
|
|
258
258
|
})
|
|
259
259
|
})
|
|
@@ -126,7 +126,7 @@ describe('Graph', () => {
|
|
|
126
126
|
it('list() calls GET on edges route', async () => {
|
|
127
127
|
mockHttpClient.get.mockResolvedValue({ edges: [], total: 0 })
|
|
128
128
|
await new Graph(mockClient).from('employees').list().execute()
|
|
129
|
-
expect(mockHttpClient.get).toHaveBeenCalledWith('api/apps/test-app/datatables/
|
|
129
|
+
expect(mockHttpClient.get).toHaveBeenCalledWith('api/apps/test-app/datatables/employees_edges/data/')
|
|
130
130
|
})
|
|
131
131
|
|
|
132
132
|
it('create() calls POST with array of edges', async () => {
|
|
@@ -137,7 +137,7 @@ describe('Graph', () => {
|
|
|
137
137
|
mockHttpClient.post.mockResolvedValue({ status: 'success', data: edges, total: 2 })
|
|
138
138
|
await new Graph(mockClient).from('employees').create(edges).execute()
|
|
139
139
|
expect(mockHttpClient.post).toHaveBeenCalledWith(
|
|
140
|
-
'api/apps/test-app/datatables/
|
|
140
|
+
'api/apps/test-app/datatables/employees_edges/data/',
|
|
141
141
|
edges
|
|
142
142
|
)
|
|
143
143
|
})
|
|
@@ -147,7 +147,7 @@ describe('Graph', () => {
|
|
|
147
147
|
mockHttpClient.post.mockResolvedValue({ status: 'success', data: edges, total: 1 })
|
|
148
148
|
await new Graph(mockClient).from('employees').create(edges).execute()
|
|
149
149
|
expect(mockHttpClient.post).toHaveBeenCalledWith(
|
|
150
|
-
'api/apps/test-app/datatables/
|
|
150
|
+
'api/apps/test-app/datatables/employees_edges/data/',
|
|
151
151
|
edges
|
|
152
152
|
)
|
|
153
153
|
})
|
|
@@ -157,7 +157,7 @@ describe('Graph', () => {
|
|
|
157
157
|
mockHttpClient.patch.mockResolvedValue({ id: 9, ...edge })
|
|
158
158
|
await new Graph(mockClient).from('employees').update('9', edge).execute()
|
|
159
159
|
expect(mockHttpClient.patch).toHaveBeenCalledWith(
|
|
160
|
-
'api/apps/test-app/datatables/
|
|
160
|
+
'api/apps/test-app/datatables/employees_edges/data/9/',
|
|
161
161
|
edge
|
|
162
162
|
)
|
|
163
163
|
})
|
|
@@ -166,7 +166,7 @@ describe('Graph', () => {
|
|
|
166
166
|
mockHttpClient.delete.mockResolvedValue({ deleted: 2 })
|
|
167
167
|
await new Graph(mockClient).from('employees').delete([9, 10]).execute()
|
|
168
168
|
expect(mockHttpClient.delete).toHaveBeenCalledWith(
|
|
169
|
-
'api/apps/test-app/datatables/
|
|
169
|
+
'api/apps/test-app/datatables/employees_edges/data/',
|
|
170
170
|
{ edge_ids: [9, 10] }
|
|
171
171
|
)
|
|
172
172
|
})
|