@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taruvi/sdk",
3
- "version": "1.3.7-beta.0",
3
+ "version": "1.3.8-beta.0",
4
4
  "description": "Taruvi SDK",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
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"
@@ -13,17 +13,23 @@ export interface UserCreateRequest {
13
13
  }
14
14
 
15
15
  export interface UserCreateResponse {
16
- id: number
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: number
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 // ISO 8601 date-time string
61
- last_login: string // ISO 8601 date-time 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: number
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 Python SDK
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
- | 'contains' // String contains (case-sensitive)
18
- | 'icontains' // String contains (case-insensitive)
19
- | 'startswith' // String starts with (case-sensitive)
20
- | 'istartswith' // String starts with (case-insensitive)
21
- | 'endswith' // String ends with (case-sensitive)
22
- | 'iendswith' // String ends with (case-insensitive)
23
- | 'isnull' // Is null
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
 
@@ -9,7 +9,9 @@ export interface FunctionInvocation {
9
9
  function: number
10
10
  function_name: string
11
11
  function_slug: string
12
+ user_id: string | null
12
13
  user_username: string
14
+ user_email: string
13
15
  task_status: string
14
16
  trigger_type: string
15
17
  created_at: string
@@ -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
  }
@@ -43,8 +43,8 @@ export interface StorageObject {
43
43
  visibility?: string
44
44
  created_at: string
45
45
  updated_at: string
46
- created_by?: number
47
- modified_by?: number
46
+ created_by?: string
47
+ modified_by?: string
48
48
  }
49
49
 
50
50
  // Response types - uses standard wrapper
@@ -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
  }
@@ -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}/edges`,
9
+ edges: (tableName: string): string => `/datatables/${tableName}_edges/data`,
10
10
  edgeId: (edgeId: string): string => `/${edgeId}`
11
11
  }
12
12
 
@@ -1,3 +1,4 @@
1
1
  export const SettingsRoutes = {
2
- metadata: "api/settings/metadata/"
2
+ metadata: "api/settings/metadata/",
3
+ userAttributes: "api/settings/user-attributes/"
3
4
  }
@@ -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('/edges/')
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/employees/edges/')
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/employees/edges/',
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/employees/edges/',
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/employees/edges/9/',
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/employees/edges/',
169
+ 'api/apps/test-app/datatables/employees_edges/data/',
170
170
  { edge_ids: [9, 10] }
171
171
  )
172
172
  })