@taruvi/sdk 1.3.3 → 1.3.4

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.
Files changed (249) hide show
  1. package/.claude/settings.local.json +19 -0
  2. package/.kiro/settings/lsp.json +198 -0
  3. package/MODULE_NAMING_CHANGES.md +81 -0
  4. package/PARAMETER_NAMING_CHANGES.md +106 -0
  5. package/README.md +4 -4
  6. package/USAGE_EXAMPLE.md +86 -0
  7. package/package.json +10 -9
  8. package/{dist/client.js → src/client.ts} +59 -39
  9. package/src/index.ts +54 -0
  10. package/src/lib/analytics/AnalyticsClient.ts +24 -0
  11. package/src/lib/analytics/types.ts +8 -0
  12. package/src/lib/app/AppClient.ts +54 -0
  13. package/src/lib/app/types.ts +50 -0
  14. package/{dist/lib/auth/AuthClient.js → src/lib/auth/AuthClient.ts} +106 -70
  15. package/src/lib/auth/types.ts +111 -0
  16. package/src/lib/database/DatabaseClient.ts +148 -0
  17. package/src/lib/database/types.ts +46 -0
  18. package/src/lib/functions/FunctionsClient.ts +27 -0
  19. package/src/lib/functions/types.ts +25 -0
  20. package/src/lib/graphs/GraphClient.ts +106 -0
  21. package/src/lib/graphs/types.ts +33 -0
  22. package/src/lib/policy/PolicyClient.ts +79 -0
  23. package/src/lib/policy/types.ts +40 -0
  24. package/src/lib/secrets/SecretsClient.ts +75 -0
  25. package/src/lib/secrets/types.ts +59 -0
  26. package/src/lib/settings/SettingsClient.ts +14 -0
  27. package/src/lib/settings/types.ts +9 -0
  28. package/src/lib/storage/StorageClient.ts +123 -0
  29. package/src/lib/storage/types.ts +86 -0
  30. package/src/lib/users/UserClient.ts +55 -0
  31. package/src/lib/users/types.ts +104 -0
  32. package/src/lib-internal/errors/ErrorClient.ts +102 -0
  33. package/src/lib-internal/errors/index.ts +3 -0
  34. package/src/lib-internal/errors/types.ts +28 -0
  35. package/src/lib-internal/http/HttpClient.ts +129 -0
  36. package/{dist/lib-internal/http/types.js → src/lib-internal/http/types.ts} +3 -2
  37. package/src/lib-internal/routes/AnalyticsRoutes.ts +3 -0
  38. package/src/lib-internal/routes/AppRoutes.ts +9 -0
  39. package/src/lib-internal/routes/AuthRoutes.ts +0 -0
  40. package/src/lib-internal/routes/DatabaseRoutes.ts +9 -0
  41. package/src/lib-internal/routes/FunctionRoutes.ts +3 -0
  42. package/src/lib-internal/routes/GraphRoutes.ts +14 -0
  43. package/src/lib-internal/routes/PolicyRoutes.ts +4 -0
  44. package/src/lib-internal/routes/SecretsRoutes.ts +5 -0
  45. package/{dist/lib-internal/routes/SettingsRoutes.js → src/lib-internal/routes/SettingsRoutes.ts} +1 -2
  46. package/src/lib-internal/routes/StorageRoutes.ts +15 -0
  47. package/src/lib-internal/routes/UserRoutes.ts +11 -0
  48. package/src/lib-internal/routes/index.ts +0 -0
  49. package/{dist/lib-internal/token/TokenClient.js → src/lib-internal/token/TokenClient.ts} +144 -99
  50. package/src/lib-internal/token/types.ts +0 -0
  51. package/src/types.ts +90 -0
  52. package/{dist/utils/enums.js → src/utils/enums.ts} +10 -4
  53. package/src/utils/utils.ts +37 -0
  54. package/tests/fixtures/mockClient.ts +19 -0
  55. package/tests/mocks/db.json +1 -0
  56. package/tests/unit/analytics/AnalyticsClient.test.ts +84 -0
  57. package/tests/unit/app/AppClient.test.ts +114 -0
  58. package/tests/unit/auth/AuthClient.test.ts +131 -0
  59. package/tests/unit/client/Client.test.ts +70 -0
  60. package/tests/unit/database/DatabaseClient.test.ts +304 -0
  61. package/tests/unit/edge-cases/robustness.test.ts +259 -0
  62. package/tests/unit/errors/errors.test.ts +209 -0
  63. package/tests/unit/functions/FunctionsClient.test.ts +99 -0
  64. package/tests/unit/graphs/GraphClient.test.ts +329 -0
  65. package/tests/unit/policy/PolicyClient.test.ts +184 -0
  66. package/tests/unit/secrets/SecretsClient.test.ts +146 -0
  67. package/tests/unit/settings/SettingsClient.test.ts +50 -0
  68. package/tests/unit/storage/StorageClient.test.ts +251 -0
  69. package/tests/unit/users/UserClient.test.ts +150 -0
  70. package/tsconfig.json +43 -0
  71. package/vitest.config.ts +7 -0
  72. package/dist/client.d.ts +0 -29
  73. package/dist/client.d.ts.map +0 -1
  74. package/dist/client.js.map +0 -1
  75. package/dist/index.d.ts +0 -25
  76. package/dist/index.d.ts.map +0 -1
  77. package/dist/index.js +0 -15
  78. package/dist/index.js.map +0 -1
  79. package/dist/lib/Analytics/AnalyticsClient.d.ts +0 -9
  80. package/dist/lib/Analytics/AnalyticsClient.d.ts.map +0 -1
  81. package/dist/lib/Analytics/AnalyticsClient.js +0 -17
  82. package/dist/lib/Analytics/AnalyticsClient.js.map +0 -1
  83. package/dist/lib/Analytics/types.d.ts +0 -7
  84. package/dist/lib/Analytics/types.d.ts.map +0 -1
  85. package/dist/lib/Analytics/types.js +0 -2
  86. package/dist/lib/Analytics/types.js.map +0 -1
  87. package/dist/lib/App/AppClient.d.ts +0 -15
  88. package/dist/lib/App/AppClient.d.ts.map +0 -1
  89. package/dist/lib/App/AppClient.js +0 -41
  90. package/dist/lib/App/AppClient.js.map +0 -1
  91. package/dist/lib/App/types.d.ts +0 -36
  92. package/dist/lib/App/types.d.ts.map +0 -1
  93. package/dist/lib/App/types.js +0 -2
  94. package/dist/lib/App/types.js.map +0 -1
  95. package/dist/lib/Database/DatabaseClient.d.ts +0 -28
  96. package/dist/lib/Database/DatabaseClient.d.ts.map +0 -1
  97. package/dist/lib/Database/DatabaseClient.js +0 -116
  98. package/dist/lib/Database/DatabaseClient.js.map +0 -1
  99. package/dist/lib/Database/types.d.ts +0 -24
  100. package/dist/lib/Database/types.d.ts.map +0 -1
  101. package/dist/lib/Database/types.js +0 -2
  102. package/dist/lib/Database/types.js.map +0 -1
  103. package/dist/lib/Function/FunctionsClient.d.ts +0 -9
  104. package/dist/lib/Function/FunctionsClient.d.ts.map +0 -1
  105. package/dist/lib/Function/FunctionsClient.js +0 -20
  106. package/dist/lib/Function/FunctionsClient.js.map +0 -1
  107. package/dist/lib/Function/types.d.ts +0 -16
  108. package/dist/lib/Function/types.d.ts.map +0 -1
  109. package/dist/lib/Function/types.js +0 -2
  110. package/dist/lib/Function/types.js.map +0 -1
  111. package/dist/lib/Graphs/GraphClient.d.ts +0 -26
  112. package/dist/lib/Graphs/GraphClient.d.ts.map +0 -1
  113. package/dist/lib/Graphs/GraphClient.js +0 -86
  114. package/dist/lib/Graphs/GraphClient.js.map +0 -1
  115. package/dist/lib/Graphs/types.d.ts +0 -23
  116. package/dist/lib/Graphs/types.d.ts.map +0 -1
  117. package/dist/lib/Graphs/types.js +0 -2
  118. package/dist/lib/Graphs/types.js.map +0 -1
  119. package/dist/lib/Policy/PolicyClient.d.ts +0 -9
  120. package/dist/lib/Policy/PolicyClient.d.ts.map +0 -1
  121. package/dist/lib/Policy/PolicyClient.js +0 -24
  122. package/dist/lib/Policy/PolicyClient.js.map +0 -1
  123. package/dist/lib/Policy/types.d.ts +0 -22
  124. package/dist/lib/Policy/types.d.ts.map +0 -1
  125. package/dist/lib/Policy/types.js +0 -2
  126. package/dist/lib/Policy/types.js.map +0 -1
  127. package/dist/lib/Secrets/SecretsClient.d.ts +0 -14
  128. package/dist/lib/Secrets/SecretsClient.d.ts.map +0 -1
  129. package/dist/lib/Secrets/SecretsClient.js +0 -32
  130. package/dist/lib/Secrets/SecretsClient.js.map +0 -1
  131. package/dist/lib/Secrets/types.d.ts +0 -13
  132. package/dist/lib/Secrets/types.d.ts.map +0 -1
  133. package/dist/lib/Secrets/types.js +0 -2
  134. package/dist/lib/Secrets/types.js.map +0 -1
  135. package/dist/lib/Settings/SettingsClient.d.ts +0 -7
  136. package/dist/lib/Settings/SettingsClient.d.ts.map +0 -1
  137. package/dist/lib/Settings/SettingsClient.js +0 -11
  138. package/dist/lib/Settings/SettingsClient.js.map +0 -1
  139. package/dist/lib/Settings/types.d.ts +0 -4
  140. package/dist/lib/Settings/types.d.ts.map +0 -1
  141. package/dist/lib/Settings/types.js +0 -2
  142. package/dist/lib/Settings/types.js.map +0 -1
  143. package/dist/lib/Storage/StorageClient.d.ts +0 -26
  144. package/dist/lib/Storage/StorageClient.d.ts.map +0 -1
  145. package/dist/lib/Storage/StorageClient.js +0 -78
  146. package/dist/lib/Storage/StorageClient.js.map +0 -1
  147. package/dist/lib/Storage/types.d.ts +0 -35
  148. package/dist/lib/Storage/types.d.ts.map +0 -1
  149. package/dist/lib/Storage/types.js +0 -2
  150. package/dist/lib/Storage/types.js.map +0 -1
  151. package/dist/lib/auth/AuthClient.d.ts +0 -66
  152. package/dist/lib/auth/AuthClient.d.ts.map +0 -1
  153. package/dist/lib/auth/AuthClient.js.map +0 -1
  154. package/dist/lib/auth/types.d.ts +0 -9
  155. package/dist/lib/auth/types.d.ts.map +0 -1
  156. package/dist/lib/auth/types.js +0 -2
  157. package/dist/lib/auth/types.js.map +0 -1
  158. package/dist/lib/user/UserClient.d.ts +0 -16
  159. package/dist/lib/user/UserClient.d.ts.map +0 -1
  160. package/dist/lib/user/UserClient.js +0 -41
  161. package/dist/lib/user/UserClient.js.map +0 -1
  162. package/dist/lib/user/types.d.ts +0 -100
  163. package/dist/lib/user/types.d.ts.map +0 -1
  164. package/dist/lib/user/types.js +0 -2
  165. package/dist/lib/user/types.js.map +0 -1
  166. package/dist/lib-internal/errors/ErrorClient.d.ts +0 -4
  167. package/dist/lib-internal/errors/ErrorClient.d.ts.map +0 -1
  168. package/dist/lib-internal/errors/ErrorClient.js +0 -6
  169. package/dist/lib-internal/errors/ErrorClient.js.map +0 -1
  170. package/dist/lib-internal/errors/index.d.ts +0 -8
  171. package/dist/lib-internal/errors/index.d.ts.map +0 -1
  172. package/dist/lib-internal/errors/index.js +0 -23
  173. package/dist/lib-internal/errors/index.js.map +0 -1
  174. package/dist/lib-internal/errors/types.d.ts +0 -83
  175. package/dist/lib-internal/errors/types.d.ts.map +0 -1
  176. package/dist/lib-internal/errors/types.js +0 -65
  177. package/dist/lib-internal/errors/types.js.map +0 -1
  178. package/dist/lib-internal/http/HttpClient.d.ts +0 -22
  179. package/dist/lib-internal/http/HttpClient.d.ts.map +0 -1
  180. package/dist/lib-internal/http/HttpClient.js +0 -65
  181. package/dist/lib-internal/http/HttpClient.js.map +0 -1
  182. package/dist/lib-internal/http/types.d.ts +0 -12
  183. package/dist/lib-internal/http/types.d.ts.map +0 -1
  184. package/dist/lib-internal/http/types.js.map +0 -1
  185. package/dist/lib-internal/routes/AnalyticsRoutes.d.ts +0 -4
  186. package/dist/lib-internal/routes/AnalyticsRoutes.d.ts.map +0 -1
  187. package/dist/lib-internal/routes/AnalyticsRoutes.js +0 -4
  188. package/dist/lib-internal/routes/AnalyticsRoutes.js.map +0 -1
  189. package/dist/lib-internal/routes/AppRoutes.d.ts +0 -10
  190. package/dist/lib-internal/routes/AppRoutes.d.ts.map +0 -1
  191. package/dist/lib-internal/routes/AppRoutes.js +0 -6
  192. package/dist/lib-internal/routes/AppRoutes.js.map +0 -1
  193. package/dist/lib-internal/routes/AuthRoutes.d.ts +0 -2
  194. package/dist/lib-internal/routes/AuthRoutes.d.ts.map +0 -1
  195. package/dist/lib-internal/routes/AuthRoutes.js +0 -2
  196. package/dist/lib-internal/routes/AuthRoutes.js.map +0 -1
  197. package/dist/lib-internal/routes/DatabaseRoutes.d.ts +0 -10
  198. package/dist/lib-internal/routes/DatabaseRoutes.d.ts.map +0 -1
  199. package/dist/lib-internal/routes/DatabaseRoutes.js +0 -6
  200. package/dist/lib-internal/routes/DatabaseRoutes.js.map +0 -1
  201. package/dist/lib-internal/routes/FunctionRoutes.d.ts +0 -4
  202. package/dist/lib-internal/routes/FunctionRoutes.d.ts.map +0 -1
  203. package/dist/lib-internal/routes/FunctionRoutes.js +0 -4
  204. package/dist/lib-internal/routes/FunctionRoutes.js.map +0 -1
  205. package/dist/lib-internal/routes/GraphRoutes.d.ts +0 -14
  206. package/dist/lib-internal/routes/GraphRoutes.d.ts.map +0 -1
  207. package/dist/lib-internal/routes/GraphRoutes.js +0 -11
  208. package/dist/lib-internal/routes/GraphRoutes.js.map +0 -1
  209. package/dist/lib-internal/routes/PolicyRoutes.d.ts +0 -5
  210. package/dist/lib-internal/routes/PolicyRoutes.d.ts.map +0 -1
  211. package/dist/lib-internal/routes/PolicyRoutes.js +0 -5
  212. package/dist/lib-internal/routes/PolicyRoutes.js.map +0 -1
  213. package/dist/lib-internal/routes/SecretsRoutes.d.ts +0 -6
  214. package/dist/lib-internal/routes/SecretsRoutes.d.ts.map +0 -1
  215. package/dist/lib-internal/routes/SecretsRoutes.js +0 -6
  216. package/dist/lib-internal/routes/SecretsRoutes.js.map +0 -1
  217. package/dist/lib-internal/routes/SettingsRoutes.d.ts +0 -4
  218. package/dist/lib-internal/routes/SettingsRoutes.d.ts.map +0 -1
  219. package/dist/lib-internal/routes/SettingsRoutes.js.map +0 -1
  220. package/dist/lib-internal/routes/StorageRoutes.d.ts +0 -11
  221. package/dist/lib-internal/routes/StorageRoutes.d.ts.map +0 -1
  222. package/dist/lib-internal/routes/StorageRoutes.js +0 -8
  223. package/dist/lib-internal/routes/StorageRoutes.js.map +0 -1
  224. package/dist/lib-internal/routes/UserRoutes.d.ts +0 -11
  225. package/dist/lib-internal/routes/UserRoutes.d.ts.map +0 -1
  226. package/dist/lib-internal/routes/UserRoutes.js +0 -11
  227. package/dist/lib-internal/routes/UserRoutes.js.map +0 -1
  228. package/dist/lib-internal/routes/index.d.ts +0 -2
  229. package/dist/lib-internal/routes/index.d.ts.map +0 -1
  230. package/dist/lib-internal/routes/index.js +0 -2
  231. package/dist/lib-internal/routes/index.js.map +0 -1
  232. package/dist/lib-internal/token/TokenClient.d.ts +0 -71
  233. package/dist/lib-internal/token/TokenClient.d.ts.map +0 -1
  234. package/dist/lib-internal/token/TokenClient.js.map +0 -1
  235. package/dist/lib-internal/token/types.d.ts +0 -2
  236. package/dist/lib-internal/token/types.d.ts.map +0 -1
  237. package/dist/lib-internal/token/types.js +0 -2
  238. package/dist/lib-internal/token/types.js.map +0 -1
  239. package/dist/types.d.ts +0 -49
  240. package/dist/types.d.ts.map +0 -1
  241. package/dist/types.js +0 -2
  242. package/dist/types.js.map +0 -1
  243. package/dist/utils/enums.d.ts +0 -20
  244. package/dist/utils/enums.d.ts.map +0 -1
  245. package/dist/utils/enums.js.map +0 -1
  246. package/dist/utils/utils.d.ts +0 -5
  247. package/dist/utils/utils.d.ts.map +0 -1
  248. package/dist/utils/utils.js +0 -32
  249. package/dist/utils/utils.js.map +0 -1
@@ -0,0 +1,111 @@
1
+ export interface UserCreateRequest {
2
+ // Required fields
3
+ username: string
4
+ email: string
5
+ first_name: string
6
+ last_name: string
7
+ password: string
8
+ confirm_password: string
9
+ // Optional fields
10
+ is_active?: boolean
11
+ is_staff?: boolean
12
+ attributes?: string
13
+ }
14
+
15
+ export interface UserCreateResponse {
16
+ id: number
17
+ uuid: string
18
+ username: string
19
+ email: string
20
+ first_name: string
21
+ last_name: string
22
+ is_active: boolean
23
+ is_staff: boolean
24
+ is_superuser: boolean
25
+ is_deleted: boolean
26
+ date_joined: string
27
+ }
28
+
29
+ export interface UserGroup {
30
+ id: number
31
+ name: string
32
+ }
33
+
34
+ export interface UserPermission {
35
+ id: number
36
+ name: string
37
+ codename: string
38
+ content_type: string // "app_label.model"
39
+ }
40
+
41
+ export interface UserRole {
42
+ name: string
43
+ slug: string
44
+ type: "app_role"
45
+ app_slug: string
46
+ source: "direct" | "site_role" | "inherited"
47
+ }
48
+
49
+ export interface UserDataResponse {
50
+ id: number
51
+ username: string
52
+ email: string
53
+ first_name: string
54
+ last_name: string
55
+ full_name: string
56
+ is_active: boolean
57
+ is_staff: boolean
58
+ is_superuser: boolean
59
+ is_deleted: boolean
60
+ date_joined: string // ISO 8601 date-time string
61
+ last_login: string // ISO 8601 date-time string
62
+ groups: UserGroup[]
63
+ user_permissions: UserPermission[]
64
+ attributes: Record<string, unknown>
65
+ missing_attributes: string[]
66
+ roles: UserRole[]
67
+ }
68
+
69
+ export interface UserUpdateRequest {
70
+ username?: string
71
+ email?: string
72
+ first_name?: string
73
+ last_name?: string
74
+ is_active?: boolean
75
+ is_staff?: boolean
76
+ }
77
+
78
+ export interface UserUpdateResponse {
79
+ id: number
80
+ uuid: string
81
+ username: string
82
+ email: string
83
+ first_name: string
84
+ last_name: string
85
+ is_active: boolean
86
+ is_staff: boolean
87
+ is_superuser: boolean
88
+ is_deleted: boolean
89
+ date_joined: string
90
+ }
91
+
92
+ export interface UserList {
93
+ search: string
94
+ is_active: boolean
95
+ is_staff: boolean
96
+ is_superuser: boolean
97
+ is_deleted: boolean
98
+ ordering: string
99
+ page: Number
100
+ page_size: Number
101
+ }
102
+
103
+ export interface UserApp {
104
+ name: string
105
+ slug: string
106
+ icon: string
107
+ url: string
108
+ display_name: string
109
+ }
110
+
111
+ export type UserAppsResponse = UserApp[]
@@ -0,0 +1,148 @@
1
+ import type { Client } from "../../client.js";
2
+ import { DatabaseRoutes, type DatabaseRouteKey } from "../../lib-internal/routes/DatabaseRoutes.js";
3
+ import { HttpMethod } from "../../lib-internal/http/types.js";
4
+ import type { TaruviConfig, DatabaseFilters, TaruviResponse } from "../../types.js";
5
+ import type { UrlParams, FilterOperator, SortOrder } from "./types.js";
6
+ import { buildQueryString } from "../../utils/utils.js";
7
+
8
+ // Used to access app data
9
+ export class Database<T = Record<string, unknown>> {
10
+ private client: Client
11
+ private urlParams: UrlParams
12
+ private config: TaruviConfig
13
+ private operation: HttpMethod | undefined
14
+ private body: object | undefined
15
+ private queryParams: DatabaseFilters | undefined
16
+
17
+ constructor(client: Client, urlParams: UrlParams = {}, operation?: HttpMethod | undefined, body?: object | undefined, queryParams?: DatabaseFilters) {
18
+ this.client = client
19
+ this.urlParams = urlParams
20
+ this.operation = operation
21
+ this.body = body
22
+ this.config = this.client.getConfig()
23
+ this.queryParams = queryParams
24
+ }
25
+
26
+ from<U = Record<string, unknown>>(dataTables: string): Database<U> {
27
+ return new Database<U>(this.client, { ...this.urlParams, dataTables }, undefined, undefined)
28
+ }
29
+
30
+ filter(field: string, operator: FilterOperator, value: string | number | boolean | (string | number)[]): Database<T> {
31
+ const filterKey = operator === 'eq' ? field : `${field}__${operator}`
32
+ // For 'in' and 'nin' operators, join array values with comma
33
+ const filterValue = Array.isArray(value) ? value.join(',') : value
34
+ return new Database<T>(this.client, { ...this.urlParams }, undefined, undefined, {
35
+ ...this.queryParams,
36
+ [filterKey]: filterValue
37
+ })
38
+ }
39
+
40
+ sort(field: string, order: SortOrder = 'asc'): Database<T> {
41
+ const ordering = order === 'desc' ? `-${field}` : field
42
+ return new Database<T>(this.client, { ...this.urlParams }, undefined, undefined, {
43
+ ...this.queryParams,
44
+ ordering
45
+ })
46
+ }
47
+
48
+ pageSize(size: number): Database<T> {
49
+ return new Database<T>(this.client, { ...this.urlParams }, undefined, undefined, {
50
+ ...this.queryParams,
51
+ page_size: size
52
+ })
53
+ }
54
+
55
+ page(num: number): Database<T> {
56
+ return new Database<T>(this.client, { ...this.urlParams }, undefined, undefined, {
57
+ ...this.queryParams,
58
+ page: num
59
+ })
60
+ }
61
+
62
+ populate(populate: string[]): Database<T> {
63
+ return new Database<T>(this.client, { ...this.urlParams }, undefined, undefined, {
64
+ ...this.queryParams,
65
+ populate: populate.join(',')
66
+ })
67
+ }
68
+
69
+ get(recordId: string): Database<T> {
70
+ return new Database<T>(this.client, { ...this.urlParams, recordId }, HttpMethod.GET)
71
+ }
72
+
73
+ create(body: Partial<T> | Partial<T>[]): Database<T> {
74
+ return new Database<T>(this.client, { ...this.urlParams }, HttpMethod.POST, body as object)
75
+ }
76
+
77
+ update(body: Partial<T> | Partial<T>[]): Database<T> {
78
+ return new Database<T>(this.client, { ...this.urlParams }, HttpMethod.PATCH, body as object)
79
+ }
80
+
81
+ delete(recordId: string): Database<T> {
82
+ return new Database<T>(this.client, { ...this.urlParams, recordId }, HttpMethod.DELETE)
83
+ }
84
+
85
+ async first(): Promise<T | null> {
86
+ const response = await this.execute()
87
+ const data = response.data
88
+ if (Array.isArray(data)) {
89
+ return data[0] ?? null
90
+ }
91
+ return data ?? null
92
+ }
93
+
94
+ async count(): Promise<number> {
95
+ const response = await this.execute()
96
+ if (response.total !== undefined) {
97
+ return response.total
98
+ }
99
+ return Array.isArray(response.data) ? response.data.length : 0
100
+ }
101
+
102
+ private buildRoute(): string {
103
+ return (
104
+ DatabaseRoutes.baseUrl(this.config.appSlug) +
105
+ (Object.keys(this.urlParams) as DatabaseRouteKey[]).reduce((acc, key) => {
106
+ const value = this.urlParams[key]
107
+ const routeBuilder = DatabaseRoutes[key]
108
+
109
+ if (value && routeBuilder) {
110
+ acc += routeBuilder(value)
111
+ }
112
+
113
+ return acc
114
+ }, "") +
115
+ "/" +
116
+ buildQueryString(this.queryParams)
117
+ )
118
+ }
119
+
120
+ async execute(): Promise<TaruviResponse<T | T[]>> {
121
+ if (!this.urlParams.dataTables) {
122
+ throw new Error('Table name is required. Call .from(tableName) first.')
123
+ }
124
+
125
+ // Build the API URL
126
+ const url = this.buildRoute()
127
+
128
+ const operation = this.operation || HttpMethod.GET
129
+
130
+ switch (operation) {
131
+ case HttpMethod.POST:
132
+ return await this.client.httpClient.post(url, this.body)
133
+
134
+ case HttpMethod.PATCH:
135
+ if (!this.urlParams.recordId) {
136
+ throw new Error('PATCH operation requires a record ID.')
137
+ }
138
+ return await this.client.httpClient.patch(url, this.body)
139
+
140
+ case HttpMethod.DELETE:
141
+ return await this.client.httpClient.delete(url)
142
+
143
+ case HttpMethod.GET:
144
+ default:
145
+ return await this.client.httpClient.get(url)
146
+ }
147
+ }
148
+ }
@@ -0,0 +1,46 @@
1
+ import type { Client } from "../../client.js"
2
+ import { HttpMethod } from "../../lib-internal/http/types.js"
3
+ import type { TaruviResponse } from "../../types.js"
4
+
5
+ export type DatabaseOperation = HttpMethod
6
+
7
+ // Filter operators matching Python SDK
8
+ export type FilterOperator =
9
+ | 'eq' // Equal
10
+ | 'ne' // Not equal
11
+ | 'gt' // Greater than
12
+ | 'gte' // Greater than or equal
13
+ | 'lt' // Less than
14
+ | 'lte' // Less than or equal
15
+ | 'in' // In array
16
+ | '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
24
+
25
+ export type SortOrder = 'asc' | 'desc'
26
+
27
+ // Internal types
28
+ export interface UrlParams {
29
+ appSlug?: string
30
+ dataTables?: string
31
+ recordId?: string
32
+ }
33
+
34
+ export interface DatabaseClientInterface {
35
+ client: Client
36
+ urlParams?: UrlParams
37
+ }
38
+
39
+ // Request types
40
+ export interface DatabaseRequest {
41
+ [key: string]: unknown
42
+ }
43
+
44
+ // Response types - uses standard wrapper
45
+ export type DatabaseResponse<T = unknown> = TaruviResponse<T[]>
46
+ export type DatabaseSingleResponse<T = unknown> = TaruviResponse<T>
@@ -0,0 +1,27 @@
1
+ import type { Client } from "../../client.js";
2
+ import type { TaruviConfig } from "../../types.js";
3
+ import type { FunctionRequest, FunctionResponse } from "./types.js";
4
+ import { FunctionRoutes } from "../../lib-internal/routes/FunctionRoutes.js";
5
+
6
+ export class Functions {
7
+ private client: Client
8
+ private config: TaruviConfig
9
+
10
+ constructor(client: Client) {
11
+ this.client = client
12
+ this.config = this.client.getConfig()
13
+ }
14
+
15
+ async execute<T = unknown>(functionSlug: string, options: FunctionRequest = {}): Promise<FunctionResponse<T>> {
16
+ const url = `${FunctionRoutes.baseUrl(this.config.appSlug, functionSlug)}/execute/`
17
+
18
+ const body = {
19
+ async: options.async ?? false,
20
+ params: {
21
+ ...options.params
22
+ }
23
+ }
24
+
25
+ return await this.client.httpClient.post<FunctionResponse<T>>(url, body)
26
+ }
27
+ }
@@ -0,0 +1,25 @@
1
+ export interface FunctionRequest {
2
+ async?: boolean
3
+ params?: Record<string, unknown>
4
+ }
5
+
6
+ export interface FunctionInvocation {
7
+ id: number
8
+ celery_task_id: string
9
+ function: number
10
+ function_name: string
11
+ function_slug: string
12
+ user_username: string
13
+ task_status: string
14
+ trigger_type: string
15
+ created_at: string
16
+ updated_at?: string
17
+ }
18
+
19
+ // Response type - matches backend AppDataResponse with invocation
20
+ export interface FunctionResponse<T = unknown> {
21
+ status: "success" | "error"
22
+ message: string
23
+ data: T | null
24
+ invocation: FunctionInvocation
25
+ }
@@ -0,0 +1,106 @@
1
+ import type { Client } from "../../client.js"
2
+ import type { TaruviConfig } from "../../types.js"
3
+ import type { GraphInclude, GraphFormat, GraphQueryParams, GraphUrlParams, EdgeRequest, EdgeDeleteRequest } from "./types.js"
4
+ import { GraphRoutes, GraphEdgeRoutes, type GraphRouteKey } from "../../lib-internal/routes/GraphRoutes.js"
5
+ import { buildQueryString } from "../../utils/utils.js"
6
+ import { HttpMethod } from "../../lib-internal/http/types.js"
7
+
8
+ export class Graph<T = Record<string, unknown>> {
9
+ private client: Client
10
+ private config: TaruviConfig
11
+ private urlParams: GraphUrlParams
12
+ private queryParams: GraphQueryParams
13
+ private operation: HttpMethod | undefined
14
+ private body: object | undefined
15
+ private edgeRoute: string | undefined
16
+
17
+ constructor(client: Client, urlParams: GraphUrlParams = {}, queryParams: GraphQueryParams = {}, operation?: HttpMethod, body?: object, edgeRoute?: string) {
18
+ this.client = client
19
+ this.config = this.client.getConfig()
20
+ this.urlParams = urlParams
21
+ this.queryParams = queryParams
22
+ this.operation = operation
23
+ this.body = body
24
+ this.edgeRoute = edgeRoute
25
+ }
26
+
27
+ from<U = Record<string, unknown>>(dataTables: string): Graph<U> {
28
+ return new Graph<U>(this.client, { ...this.urlParams, dataTables }, { ...this.queryParams })
29
+ }
30
+
31
+ get(recordId: string): Graph<T> {
32
+ return new Graph<T>(this.client, { ...this.urlParams, recordId }, { ...this.queryParams })
33
+ }
34
+
35
+ include(direction: GraphInclude): Graph<T> {
36
+ return new Graph<T>(this.client, { ...this.urlParams }, { ...this.queryParams, include: direction })
37
+ }
38
+
39
+ depth(n: number): Graph<T> {
40
+ return new Graph<T>(this.client, { ...this.urlParams }, { ...this.queryParams, depth: n })
41
+ }
42
+
43
+ format(fmt: GraphFormat): Graph<T> {
44
+ return new Graph<T>(this.client, { ...this.urlParams }, { ...this.queryParams, format: fmt })
45
+ }
46
+
47
+ types(types: string[]): Graph<T> {
48
+ return new Graph<T>(this.client, { ...this.urlParams }, { ...this.queryParams, relationship_type: types })
49
+ }
50
+
51
+ list(): Graph<T> {
52
+ const route = GraphEdgeRoutes.baseUrl(this.config.appSlug) + GraphEdgeRoutes.edges(this.urlParams.dataTables!) + "/"
53
+ return new Graph<T>(this.client, { ...this.urlParams }, {}, HttpMethod.GET, undefined, route)
54
+ }
55
+
56
+ create(edges: EdgeRequest[]): Graph<T> {
57
+ const route = GraphEdgeRoutes.baseUrl(this.config.appSlug) + GraphEdgeRoutes.edges(this.urlParams.dataTables!) + "/"
58
+ return new Graph<T>(this.client, { ...this.urlParams }, {}, HttpMethod.POST, edges as unknown as object, route)
59
+ }
60
+
61
+ update(edgeId: string, edge: EdgeRequest): Graph<T> {
62
+ const route = GraphEdgeRoutes.baseUrl(this.config.appSlug) + GraphEdgeRoutes.edges(this.urlParams.dataTables!) + GraphEdgeRoutes.edgeId(edgeId) + "/"
63
+ return new Graph<T>(this.client, { ...this.urlParams }, {}, HttpMethod.PATCH, edge, route)
64
+ }
65
+
66
+ delete(edgeIds: number[]): Graph<T> {
67
+ const route = GraphEdgeRoutes.baseUrl(this.config.appSlug) + GraphEdgeRoutes.edges(this.urlParams.dataTables!) + "/"
68
+ const body: EdgeDeleteRequest = { edge_ids: edgeIds }
69
+ return new Graph<T>(this.client, { ...this.urlParams }, {}, HttpMethod.DELETE, body, route)
70
+ }
71
+
72
+ private buildRoute(): string {
73
+ if (this.edgeRoute) return this.edgeRoute
74
+
75
+ return (
76
+ GraphRoutes.baseUrl(this.config.appSlug) +
77
+ (Object.keys(this.urlParams) as GraphRouteKey[]).reduce((acc, key) => {
78
+ const value = this.urlParams[key]
79
+ const routeBuilder = GraphRoutes[key]
80
+ if (value && routeBuilder) {
81
+ acc += routeBuilder(value)
82
+ }
83
+ return acc
84
+ }, "") +
85
+ "/" +
86
+ buildQueryString(this.queryParams as Record<string, unknown>)
87
+ )
88
+ }
89
+
90
+ async execute(): Promise<T | T[]> {
91
+ const url = this.buildRoute()
92
+ const operation = this.operation || HttpMethod.GET
93
+
94
+ switch (operation) {
95
+ case HttpMethod.POST:
96
+ return await this.client.httpClient.post(url, this.body)
97
+ case HttpMethod.PATCH:
98
+ return await this.client.httpClient.patch(url, this.body)
99
+ case HttpMethod.DELETE:
100
+ return await this.client.httpClient.delete(url, this.body)
101
+ case HttpMethod.GET:
102
+ default:
103
+ return await this.client.httpClient.get(url)
104
+ }
105
+ }
106
+ }
@@ -0,0 +1,33 @@
1
+ export type GraphInclude = 'descendants' | 'ancestors' | 'both'
2
+ export type GraphFormat = 'tree' | 'graph'
3
+
4
+ export interface GraphQueryParams {
5
+ include?: GraphInclude
6
+ depth?: number
7
+ format?: GraphFormat
8
+ relationship_type?: string[]
9
+ }
10
+
11
+ export interface GraphUrlParams {
12
+ dataTables?: string
13
+ recordId?: string
14
+ }
15
+
16
+ export interface EdgeRequest {
17
+ from: number | string
18
+ to: number | string
19
+ type: string
20
+ metadata?: Record<string, unknown>
21
+ }
22
+
23
+ export interface EdgeResponse {
24
+ id: number
25
+ from: number | string
26
+ to: number | string
27
+ type: string
28
+ metadata?: Record<string, unknown>
29
+ }
30
+
31
+ export interface EdgeDeleteRequest {
32
+ edge_ids: number[]
33
+ }
@@ -0,0 +1,79 @@
1
+ import type { Client } from "../../client.js"
2
+ import { PolicyRoutes } from "../../lib-internal/routes/PolicyRoutes.js"
3
+ import type { TaruviConfig } from "../../types.js"
4
+ import type { Resources, Resource, Principal, PolicyCheckBatchResult, GetAllowedActionsOptions } from "./types.js"
5
+
6
+ export class Policy {
7
+ private client: Client
8
+ private config: TaruviConfig
9
+ constructor(client: Client) {
10
+ this.client = client
11
+ this.config = this.client.getConfig()
12
+ }
13
+
14
+ async checkResource(resources: Resources): Promise<PolicyCheckBatchResult> {
15
+ const url = PolicyRoutes.baseUrl(this.config.appSlug) + PolicyRoutes.checkResource
16
+ const body = {
17
+ resources: resources.map(r => ({
18
+ resource: {
19
+ kind: `${r.entityType}:${r.tableName}`,
20
+ id: r.recordId,
21
+ attr: r.attributes || {}
22
+ },
23
+ actions: r.actions
24
+ }))
25
+ }
26
+
27
+ return await this.client.httpClient.post<PolicyCheckBatchResult>(url, body)
28
+ }
29
+
30
+ /**
31
+ * Get list of allowed actions for a specific resource.
32
+ *
33
+ * @param resource - Resource with kind and id
34
+ * @param options - Optional actions list, principal override, and aux data
35
+ * @returns List of action names that are allowed
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const allowed = await client.policy.getAllowedActions(
40
+ * { kind: 'datatable:users', id: '123', attr: {} }
41
+ * )
42
+ * // Returns: ['read', 'write', 'update'] // 'delete' not allowed
43
+ * ```
44
+ */
45
+ async getAllowedActions(
46
+ resource: Resource,
47
+ options: GetAllowedActionsOptions = {}
48
+ ): Promise<string[]> {
49
+ const { actions = ['read', 'write', 'create', 'update', 'delete'], principal, auxData } = options
50
+
51
+ const url = PolicyRoutes.baseUrl(this.config.appSlug) + PolicyRoutes.checkResource
52
+ const body: Record<string, unknown> = {
53
+ resources: [{
54
+ resource: resource,
55
+ actions: actions
56
+ }]
57
+ }
58
+
59
+ if (principal) {
60
+ body.principal = principal
61
+ }
62
+ if (auxData) {
63
+ body.auxData = auxData
64
+ }
65
+
66
+ const result = await this.client.httpClient.post<PolicyCheckBatchResult>(url, body)
67
+
68
+ // Extract allowed actions
69
+ if (result.results && result.results.length > 0) {
70
+ const firstResult = result.results[0]
71
+ const actionResults = firstResult?.actions || {}
72
+ return Object.entries(actionResults)
73
+ .filter(([_, effect]) => effect === 'EFFECT_ALLOW')
74
+ .map(([action, _]) => action)
75
+ }
76
+
77
+ return []
78
+ }
79
+ }
@@ -0,0 +1,40 @@
1
+ import type { TaruviResponse } from "../../types.js"
2
+
3
+ export interface Principal {
4
+ id: string
5
+ roles: string[]
6
+ attr: Record<string, unknown>
7
+ }
8
+
9
+ export type Resource = {
10
+ kind: string
11
+ id: string
12
+ attr: Record<string, unknown>
13
+ }
14
+
15
+ export type Resources = {
16
+ entityType: string
17
+ tableName: string
18
+ recordId: string
19
+ attributes: Record<string, unknown>
20
+ actions: string[]
21
+ }[]
22
+
23
+ export interface PolicyCheckResult {
24
+ resource: Resource
25
+ actions: Record<string, string>
26
+ }
27
+
28
+ export interface PolicyCheckBatchResult {
29
+ requestId: string
30
+ results: PolicyCheckResult[]
31
+ }
32
+
33
+ export type GetAllowedActionsOptions = {
34
+ actions?: string[]
35
+ principal?: Principal
36
+ auxData?: Record<string, unknown>
37
+ }
38
+
39
+ // Response types - uses standard wrapper
40
+ export type ResourceCheckResponse = TaruviResponse<PolicyCheckBatchResult>
@@ -0,0 +1,75 @@
1
+ import type { Client } from "../../client.js";
2
+ import type { SecretsUrlParams, GetSecretOptions, GetSecretsOptions, SecretsBatchResponse, SecretsBatchMetadataResponse } from "./types.js";
3
+ import { HttpMethod } from "../../lib-internal/http/types.js";
4
+ import { SecretsRoutes } from "../../lib-internal/routes/SecretsRoutes.js";
5
+ import { buildQueryString } from "../../utils/utils.js";
6
+
7
+ export class Secrets {
8
+ private client: Client
9
+ private urlParams: SecretsUrlParams
10
+ private body: object | undefined
11
+ private method: HttpMethod
12
+
13
+ constructor(client: Client, urlParams: SecretsUrlParams = {}, body?: object, method: HttpMethod = HttpMethod.GET) {
14
+ this.client = client
15
+ this.urlParams = urlParams
16
+ this.body = body
17
+ this.method = method
18
+ }
19
+
20
+ /**
21
+ * Get a specific secret by key.
22
+ *
23
+ * @param key - Secret key/name
24
+ * @param options - Optional app context for 2-tier inheritance and tag validation
25
+ * @returns Secrets instance for chaining with execute()
26
+ */
27
+ get(key: string, options: GetSecretOptions = {}): Secrets {
28
+ if (!key || typeof key !== 'string') {
29
+ throw new Error('Secret key is required and must be a string.')
30
+ }
31
+
32
+ const path = SecretsRoutes.get(key)
33
+ const queryParams: Record<string, unknown> = {}
34
+
35
+ if (options.app) queryParams.app = options.app
36
+ if (options.tags && options.tags.length > 0) queryParams.tags = options.tags.join(',')
37
+
38
+ return new Secrets(this.client, { ...this.urlParams, path, queryParams }, undefined, HttpMethod.GET)
39
+ }
40
+
41
+ /**
42
+ * List multiple secrets by keys using backend batch endpoint.
43
+ * More efficient than making multiple individual requests - uses a single API call.
44
+ *
45
+ * @param keys - List of secret keys to retrieve
46
+ * @param options - Optional app context and metadata flag
47
+ * @returns Promise with dict mapping keys to values (or full objects if includeMetadata=true)
48
+ */
49
+ async list(keys: string[], options: GetSecretsOptions = {}): Promise<SecretsBatchResponse | SecretsBatchMetadataResponse> {
50
+ const queryParams: Record<string, unknown> = {
51
+ keys: keys.join(',')
52
+ }
53
+
54
+ if (options.app) queryParams.app = options.app
55
+ if (options.includeMetadata) queryParams.include_metadata = options.includeMetadata
56
+
57
+ const queryString = buildQueryString(queryParams)
58
+ const url = SecretsRoutes.baseUrl + queryString
59
+
60
+ return await this.client.httpClient.get<SecretsBatchResponse | SecretsBatchMetadataResponse>(url)
61
+ }
62
+
63
+ async execute<T = unknown>(): Promise<T> {
64
+ const queryString = buildQueryString(this.urlParams.queryParams)
65
+ const url = (this.urlParams.path ?? SecretsRoutes.baseUrl) + queryString
66
+
67
+ switch (this.method) {
68
+ case HttpMethod.PUT:
69
+ return await this.client.httpClient.put<T>(url, this.body)
70
+ case HttpMethod.GET:
71
+ default:
72
+ return await this.client.httpClient.get<T>(url)
73
+ }
74
+ }
75
+ }