@taruvi/sdk 1.5.0-beta.1 → 1.5.0-beta.2

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 (69) hide show
  1. package/README.md +58 -1295
  2. package/package.json +10 -2
  3. package/.claude/settings.local.json +0 -19
  4. package/.github/worflows/publish.yml +0 -57
  5. package/.github/workflows/publish.yml +0 -58
  6. package/.kiro/settings/lsp.json +0 -198
  7. package/MODULE_NAMING_CHANGES.md +0 -81
  8. package/PARAMETER_NAMING_CHANGES.md +0 -106
  9. package/USAGE_EXAMPLE.md +0 -86
  10. package/src/client.ts +0 -88
  11. package/src/index.ts +0 -51
  12. package/src/lib/analytics/AnalyticsClient.ts +0 -24
  13. package/src/lib/analytics/types.ts +0 -8
  14. package/src/lib/app/AppClient.ts +0 -54
  15. package/src/lib/app/types.ts +0 -50
  16. package/src/lib/auth/AuthClient.ts +0 -126
  17. package/src/lib/auth/types.ts +0 -123
  18. package/src/lib/database/DatabaseClient.ts +0 -306
  19. package/src/lib/database/types.ts +0 -156
  20. package/src/lib/functions/FunctionsClient.ts +0 -27
  21. package/src/lib/functions/types.ts +0 -27
  22. package/src/lib/policy/PolicyClient.ts +0 -79
  23. package/src/lib/policy/types.ts +0 -39
  24. package/src/lib/secrets/SecretsClient.ts +0 -75
  25. package/src/lib/secrets/types.ts +0 -59
  26. package/src/lib/settings/SettingsClient.ts +0 -22
  27. package/src/lib/settings/types.ts +0 -9
  28. package/src/lib/storage/StorageClient.ts +0 -131
  29. package/src/lib/storage/types.ts +0 -86
  30. package/src/lib/users/UserClient.ts +0 -63
  31. package/src/lib/users/types.ts +0 -123
  32. package/src/lib-internal/errors/ErrorClient.ts +0 -114
  33. package/src/lib-internal/errors/index.ts +0 -3
  34. package/src/lib-internal/errors/types.ts +0 -29
  35. package/src/lib-internal/http/HttpClient.ts +0 -116
  36. package/src/lib-internal/http/types.ts +0 -12
  37. package/src/lib-internal/routes/AnalyticsRoutes.ts +0 -3
  38. package/src/lib-internal/routes/AppRoutes.ts +0 -9
  39. package/src/lib-internal/routes/AuthRoutes.ts +0 -0
  40. package/src/lib-internal/routes/DatabaseRoutes.ts +0 -10
  41. package/src/lib-internal/routes/FunctionRoutes.ts +0 -3
  42. package/src/lib-internal/routes/PolicyRoutes.ts +0 -4
  43. package/src/lib-internal/routes/SecretsRoutes.ts +0 -5
  44. package/src/lib-internal/routes/SettingsRoutes.ts +0 -4
  45. package/src/lib-internal/routes/StorageRoutes.ts +0 -15
  46. package/src/lib-internal/routes/UserRoutes.ts +0 -12
  47. package/src/lib-internal/routes/index.ts +0 -0
  48. package/src/lib-internal/token/TokenClient.ts +0 -108
  49. package/src/lib-internal/token/types.ts +0 -0
  50. package/src/types.ts +0 -104
  51. package/src/utils/enums.ts +0 -24
  52. package/src/utils/utils.ts +0 -38
  53. package/tests/fixtures/mockClient.ts +0 -19
  54. package/tests/mocks/db.json +0 -1
  55. package/tests/unit/analytics/AnalyticsClient.test.ts +0 -84
  56. package/tests/unit/app/AppClient.test.ts +0 -114
  57. package/tests/unit/auth/AuthClient.test.ts +0 -91
  58. package/tests/unit/client/Client.test.ts +0 -87
  59. package/tests/unit/database/DatabaseClient.test.ts +0 -652
  60. package/tests/unit/edge-cases/robustness.test.ts +0 -258
  61. package/tests/unit/errors/errors.test.ts +0 -236
  62. package/tests/unit/functions/FunctionsClient.test.ts +0 -99
  63. package/tests/unit/policy/PolicyClient.test.ts +0 -180
  64. package/tests/unit/secrets/SecretsClient.test.ts +0 -146
  65. package/tests/unit/settings/SettingsClient.test.ts +0 -50
  66. package/tests/unit/storage/StorageClient.test.ts +0 -252
  67. package/tests/unit/users/UserClient.test.ts +0 -150
  68. package/tsconfig.json +0 -44
  69. package/vitest.config.ts +0 -7
package/src/client.ts DELETED
@@ -1,88 +0,0 @@
1
- import { HttpClient } from "./lib-internal/http/HttpClient.js";
2
- import { TokenClient } from "./lib-internal/token/TokenClient.js";
3
- import type { TaruviConfig } from "./types.js";
4
- import packageJson from "../package.json" with { type: "json" };
5
-
6
- export class Client {
7
- private readonly config: TaruviConfig
8
- private readonly _httpClient: HttpClient
9
- private readonly _tokenClient: TokenClient
10
-
11
- constructor(config: TaruviConfig) {
12
- if (!config) {
13
- throw new Error("Config is required")
14
- }
15
-
16
- if (!config.apiKey) {
17
- throw new Error("API key is required")
18
- }
19
-
20
- if (!config.apiUrl) {
21
- throw new Error("API URL is required")
22
- }
23
-
24
- this.config = config
25
-
26
- // Internal clients for SDK use only
27
- // TokenClient must be created first, then passed to HttpClient
28
-
29
- this._tokenClient = new TokenClient(config.token)
30
- this._httpClient = new HttpClient(this.config, this._tokenClient)
31
-
32
- // Check URL hash for tokens (OAuth callback)
33
- this.extractTokensFromUrl()
34
-
35
- console.info(`Taruvi SDK v${packageJson.version} initialized`)
36
- }
37
-
38
- /**
39
- * Extracts session token from URL hash and stores it using TokenClient.
40
- * Handles callback URLs like: #session_token=xxx
41
- * After extraction, the URL hash is cleared.
42
- */
43
- private extractTokensFromUrl(): void {
44
- if (typeof window === "undefined" || typeof localStorage === "undefined") {
45
- return
46
- }
47
-
48
- const hash = window.location.hash
49
- if (!hash) {
50
- return
51
- }
52
-
53
- const params = new URLSearchParams(hash.substring(1))
54
- const sessionToken = params.get("session_token")
55
-
56
- if (!sessionToken) {
57
- return
58
- }
59
-
60
- this._tokenClient.setTokens({ sessionToken })
61
-
62
- // Clear hash from URL without reloading page
63
- if (window.history && window.history.replaceState) {
64
- const urlWithoutHash = window.location.pathname + window.location.search
65
- window.history.replaceState(null, "", urlWithoutHash)
66
- }
67
- }
68
-
69
- /**
70
- * @internal
71
- * Internal use only - not part of public API
72
- */
73
- get httpClient(): HttpClient {
74
- return this._httpClient
75
- }
76
-
77
- /**
78
- * @internal
79
- * Internal use only - not part of public API
80
- */
81
- get tokenClient(): TokenClient {
82
- return this._tokenClient
83
- }
84
-
85
- getConfig(): Readonly<TaruviConfig> {
86
- return { ...this.config }
87
- }
88
- }
package/src/index.ts DELETED
@@ -1,51 +0,0 @@
1
- // Export main client
2
- export { Client } from "./client.js"
3
-
4
- // Export error classes
5
- export { TaruviError, ValidationError, AuthError, ForbiddenError, NotFoundError, ConflictError, TimeoutError, NetworkError, RateLimitError } from "./lib-internal/errors/index.js"
6
- export { ErrorCode } from "./lib-internal/errors/index.js"
7
- export type { ErrorResponseBody } from "./lib-internal/errors/index.js"
8
-
9
- // Export public client classes
10
- export { Auth } from "./lib/auth/AuthClient.js"
11
- export { User } from "./lib/users/UserClient.js"
12
- export { Storage } from "./lib/storage/StorageClient.js"
13
- export { Database } from "./lib/database/DatabaseClient.js"
14
- export { Settings } from "./lib/settings/SettingsClient.js"
15
- export { Functions } from "./lib/functions/FunctionsClient.js"
16
- export { Secrets } from "./lib/secrets/SecretsClient.js"
17
- export { Policy } from "./lib/policy/PolicyClient.js"
18
- export { App } from "./lib/app/AppClient.js"
19
- export { Analytics } from "./lib/analytics/AnalyticsClient.js"
20
-
21
- // Export core types
22
- export type { TaruviConfig, TaruviResponse, PaginationInfo, StorageFilters, DatabaseFilters } from "./types.js"
23
- export type { AuthTokens } from "./lib-internal/token/TokenClient.js"
24
-
25
- // User types
26
- export type { UserCreateRequest, UserData, UserUpdateRequest, UserListFilters, UserApp, UserResponse, UserListResponse, UserAppsResponse, AssignRolesRequest, RevokeRolesRequest, RolesResponse, UserGroup, UserPermission, UserRole, UserPreferences, UserPreferencesUpdate, UserPreferencesResponse } from "./lib/users/types.js"
27
-
28
- // Policy types
29
- export type { Principal, Resource, Resources, PolicyCheckResult, PolicyCheckBatchResult, ResourceCheckResponse, GetAllowedActionsOptions } from "./lib/policy/types.js"
30
-
31
- // App types
32
- export type { RoleData, AppSettingsData, RoleResponse, RolesListResponse, AppSettingsResponse } from "./lib/app/types.js"
33
-
34
- // Function types
35
- export type { FunctionRequest, FunctionResponse, FunctionInvocation } from "./lib/functions/types.js"
36
-
37
- // Database types
38
- export type { DatabaseRequest, DatabaseResponse, DatabaseSingleResponse, FilterOperator, SortOrder, GraphInclude, GraphFormat, EdgeRequest, EdgeResponse, EdgeDeleteRequest, PgRangeValue, BackendFilterLeafNode, BackendFilterLogicalNode, BackendFilterNode, BackendFilterTreeRoot } from "./lib/database/types.js"
39
- export { isBackendFilterTreeRoot } from "./lib/database/types.js"
40
-
41
- // Storage types
42
- export type { StorageRequest, StorageUpdateRequest, StorageObject, StorageResponse, StorageListResponse, StorageUploadBatchResponse, StorageDeleteBatchResponse } from "./lib/storage/types.js"
43
-
44
- // Settings types
45
- export type { SiteSettingsData, SettingsResponse } from "./lib/settings/types.js"
46
-
47
- // Secrets types
48
- export type { SecretCreateRequest, SecretUpdateRequest, SecretData, SecretResponse, SecretsListResponse, SecretsBatchResponse, SecretsBatchMetadataResponse, GetSecretOptions, GetSecretsOptions } from "./lib/secrets/types.js"
49
-
50
- // Analytics types
51
- export type { AnalyticsRequest, AnalyticsResponse } from "./lib/analytics/types.js"
@@ -1,24 +0,0 @@
1
- import type { Client } from "../../client.js";
2
- import type { TaruviConfig } from "../../types.js";
3
- import type { AnalyticsRequest, AnalyticsResponse } from "./types.js";
4
- import { AnalyticsRoutes } from "../../lib-internal/routes/AnalyticsRoutes.js";
5
-
6
- export class Analytics {
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>(querySlug: string, options: AnalyticsRequest = {}): Promise<AnalyticsResponse<T>> {
16
- const url = AnalyticsRoutes.baseUrl(this.config.appSlug, querySlug)
17
-
18
- const body = {
19
- params: options.params || {}
20
- }
21
-
22
- return await this.client.httpClient.post<AnalyticsResponse<T>>(url, body)
23
- }
24
- }
@@ -1,8 +0,0 @@
1
- import type { TaruviResponse } from "../../types.js"
2
-
3
- export interface AnalyticsRequest {
4
- params?: Record<string, unknown>
5
- }
6
-
7
- // Response type - uses standard wrapper
8
- export type AnalyticsResponse<T = unknown> = TaruviResponse<T>
@@ -1,54 +0,0 @@
1
- import type { Client } from "../../client.js";
2
- import { AppRoutes, type AppRouteKey } from "../../lib-internal/routes/AppRoutes.js";
3
- import { HttpMethod } from "../../lib-internal/http/types.js";
4
- import type { TaruviConfig } from "../../types.js";
5
- import type { UrlParams } from "./types.js";
6
-
7
- export class App {
8
- private client: Client
9
- private urlParams: UrlParams
10
- private config: TaruviConfig
11
- private operation: HttpMethod | undefined
12
-
13
- constructor(client: Client, urlParams: UrlParams = {}, operation?: HttpMethod | undefined) {
14
- this.client = client
15
- this.urlParams = urlParams
16
- this.operation = operation
17
- this.config = this.client.getConfig()
18
- }
19
-
20
- roles() {
21
- return new App(this.client, { ...this.urlParams, roles: "roles" }, HttpMethod.GET)
22
- }
23
-
24
- settings() {
25
- return new App(this.client, {...this.urlParams, settings: "settings"}, HttpMethod.GET)
26
- }
27
-
28
- private buildRoute(): string {
29
- return (
30
- AppRoutes.baseUrl(this.config.appSlug) +
31
- (Object.keys(this.urlParams) as AppRouteKey[]).reduce((acc, key) => {
32
- const value = this.urlParams[key]
33
- const routeBuilder = AppRoutes[key]
34
-
35
- if (value && routeBuilder) {
36
- acc += routeBuilder()
37
- }
38
-
39
- return acc
40
- }, "")
41
- )
42
- }
43
-
44
- async execute() {
45
- const url = this.buildRoute()
46
- const operation = this.operation || HttpMethod.GET
47
-
48
- switch (operation) {
49
- case HttpMethod.GET:
50
- default:
51
- return await this.client.httpClient.get(url)
52
- }
53
- }
54
- }
@@ -1,50 +0,0 @@
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 AppOperation = HttpMethod
6
-
7
- // Internal types
8
- export interface UrlParams {
9
- appSlug?: string
10
- roles?: string
11
- settings?: string
12
- }
13
-
14
- export interface AppClientInterface {
15
- client: Client
16
- urlParams?: UrlParams
17
- }
18
-
19
- // Role data
20
- export interface RoleData {
21
- id: string | number
22
- name: string
23
- slug: string
24
- description?: string
25
- permissions?: string[]
26
- created_at?: string
27
- updated_at?: string
28
- }
29
-
30
- // App settings data
31
- export interface AppSettingsData {
32
- display_name: string
33
- icon: string | null
34
- icon_url: string | null
35
- primary_color: string
36
- secondary_color: string
37
- banner_image: string | null
38
- banner_image_url: string | null
39
- category: string
40
- documentation_url: string | null
41
- support_email: string | null
42
- default_frontend_worker_url: string | null
43
- created_at: string
44
- updated_at: string
45
- }
46
-
47
- // Response types - uses standard wrapper
48
- export type RoleResponse = TaruviResponse<RoleData>
49
- export type RolesListResponse = TaruviResponse<RoleData[]>
50
- export type AppSettingsResponse = TaruviResponse<AppSettingsData>
@@ -1,126 +0,0 @@
1
- import type { Client } from "../../client.js";
2
- import type { TaruviResponse } from "../../types.js";
3
- import type { UserData } from "../users/types.js";
4
- import { UserRoutes } from "../../lib-internal/routes/UserRoutes.js";
5
-
6
- /**
7
- * Auth Client - Handles user authentication using Web UI Flow
8
- * Uses session token for API authentication via X-Session-Token header.
9
- * On 401/403, tokens are cleared automatically by HttpClient interceptor.
10
- */
11
- export class Auth {
12
- private client: Client
13
-
14
- constructor(client: Client) {
15
- this.client = client
16
- }
17
-
18
- /**
19
- * Redirect to login page (Web UI Flow)
20
- */
21
- login(callbackUrl?: string): void {
22
- if (typeof window === "undefined") {
23
- console.error("login() can only be called in browser environment")
24
- return
25
- }
26
-
27
- const config = this.client.getConfig()
28
- const callback = callbackUrl || window.location.origin + window.location.pathname
29
- const deskUrl = config.deskUrl || config.apiUrl
30
- const loginUrl = `${deskUrl}/accounts/login/?redirect_to=${encodeURIComponent(callback)}`
31
-
32
- if (typeof sessionStorage !== "undefined") {
33
- sessionStorage.setItem("auth_state", JSON.stringify({
34
- returnTo: window.location.pathname,
35
- timestamp: Date.now()
36
- }))
37
- }
38
-
39
- window.location.href = loginUrl
40
- }
41
-
42
- /**
43
- * Redirect to signup page (Web UI Flow)
44
- */
45
- signup(callbackUrl?: string): void {
46
- if (typeof window === "undefined") {
47
- console.error("signup() can only be called in browser environment")
48
- return
49
- }
50
-
51
- const config = this.client.getConfig()
52
- const callback = callbackUrl || window.location.origin + window.location.pathname
53
- const signupUrl = `${config.apiUrl}/accounts/signup/?redirect_to=${encodeURIComponent(callback)}`
54
-
55
- if (typeof sessionStorage !== "undefined") {
56
- sessionStorage.setItem("auth_state", JSON.stringify({
57
- returnTo: window.location.pathname,
58
- timestamp: Date.now()
59
- }))
60
- }
61
-
62
- window.location.href = signupUrl
63
- }
64
-
65
- /**
66
- * Logout user and redirect to logout page
67
- */
68
- async logout(callbackUrl?: string): Promise<void> {
69
- if (typeof window === "undefined") {
70
- console.error("logout() can only be called in browser environment")
71
- return
72
- }
73
-
74
- this.client.tokenClient.clearTokens()
75
-
76
- const config = this.client.getConfig()
77
- const deskUrl = config.deskUrl || config.apiUrl
78
- let callback: string = callbackUrl || ""
79
-
80
- if (!callback) {
81
- try {
82
- const settings = await this.client.httpClient.get<{ frontend_url?: string }>(
83
- `api/sites/${config.appSlug}/metadata`
84
- )
85
- callback = settings.frontend_url || window.location.origin
86
- } catch (error) {
87
- console.error("Failed to fetch site settings, using origin:", error)
88
- callback = window.location.origin
89
- }
90
- }
91
-
92
- const logoutUrl = `${deskUrl}/accounts/logout/?redirect_to=${encodeURIComponent(callback)}`
93
- window.location.href = logoutUrl
94
- }
95
-
96
- /**
97
- * Check if user is authenticated (has session token)
98
- */
99
- isUserAuthenticated(): boolean {
100
- return this.client.tokenClient.isAuthenticated()
101
- }
102
-
103
- /**
104
- * Get the current session token
105
- */
106
- getSessionToken(): string | null {
107
- return this.client.tokenClient.getSessionToken()
108
- }
109
-
110
- /**
111
- * Get current user from API
112
- * @returns Promise with user data or null if not authenticated
113
- */
114
- async getCurrentUser(): Promise<TaruviResponse<UserData> | null> {
115
- if (!this.isUserAuthenticated()) {
116
- return null
117
- }
118
-
119
- try {
120
- return await this.client.httpClient.get<TaruviResponse<UserData>>(UserRoutes.getCurrentUser())
121
- } catch (error) {
122
- console.error("Failed to fetch current user:", error)
123
- return null
124
- }
125
- }
126
- }
@@ -1,123 +0,0 @@
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: string
17
- username: string
18
- email: string
19
- first_name: string
20
- last_name: string
21
- full_name: string
22
- is_active: boolean
23
- is_superuser: boolean
24
- is_deleted: boolean
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
33
- }
34
-
35
- export interface UserGroup {
36
- id: number
37
- name: string
38
- }
39
-
40
- export interface UserPermission {
41
- id: number
42
- name: string
43
- codename: string
44
- content_type: string // "app_label.model"
45
- }
46
-
47
- export interface UserRole {
48
- name: string
49
- slug: string
50
- type: "app_role"
51
- app_slug: string
52
- source: "direct" | "site_role" | "inherited"
53
- }
54
-
55
- export interface UserDataResponse {
56
- id: string
57
- username: string
58
- email: string
59
- first_name: string
60
- last_name: string
61
- full_name: string
62
- is_active: boolean
63
- is_superuser: boolean
64
- is_deleted: boolean
65
- date_joined: string
66
- last_login: string
67
- groups: UserGroup[]
68
- user_permissions: UserPermission[]
69
- attributes: Record<string, unknown>
70
- missing_attributes: string[]
71
- roles: UserRole[]
72
- icon_url: string | null
73
- }
74
-
75
- export interface UserUpdateRequest {
76
- username?: string
77
- email?: string
78
- first_name?: string
79
- last_name?: string
80
- is_active?: boolean
81
- is_staff?: boolean
82
- }
83
-
84
- export interface UserUpdateResponse {
85
- id: string
86
- username: string
87
- email: string
88
- first_name: string
89
- last_name: string
90
- full_name: string
91
- is_active: boolean
92
- is_superuser: boolean
93
- is_deleted: boolean
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
102
- }
103
-
104
- export interface UserList {
105
- search: string
106
- is_active: boolean
107
- is_staff: boolean
108
- is_superuser: boolean
109
- is_deleted: boolean
110
- ordering: string
111
- page: Number
112
- page_size: Number
113
- }
114
-
115
- export interface UserApp {
116
- name: string
117
- slug: string
118
- icon: string
119
- url: string
120
- display_name: string
121
- }
122
-
123
- export type UserAppsResponse = UserApp[]