@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.
- package/README.md +58 -1295
- package/package.json +10 -2
- package/.claude/settings.local.json +0 -19
- package/.github/worflows/publish.yml +0 -57
- package/.github/workflows/publish.yml +0 -58
- package/.kiro/settings/lsp.json +0 -198
- package/MODULE_NAMING_CHANGES.md +0 -81
- package/PARAMETER_NAMING_CHANGES.md +0 -106
- package/USAGE_EXAMPLE.md +0 -86
- package/src/client.ts +0 -88
- package/src/index.ts +0 -51
- package/src/lib/analytics/AnalyticsClient.ts +0 -24
- package/src/lib/analytics/types.ts +0 -8
- package/src/lib/app/AppClient.ts +0 -54
- package/src/lib/app/types.ts +0 -50
- package/src/lib/auth/AuthClient.ts +0 -126
- package/src/lib/auth/types.ts +0 -123
- package/src/lib/database/DatabaseClient.ts +0 -306
- package/src/lib/database/types.ts +0 -156
- package/src/lib/functions/FunctionsClient.ts +0 -27
- package/src/lib/functions/types.ts +0 -27
- package/src/lib/policy/PolicyClient.ts +0 -79
- package/src/lib/policy/types.ts +0 -39
- package/src/lib/secrets/SecretsClient.ts +0 -75
- package/src/lib/secrets/types.ts +0 -59
- package/src/lib/settings/SettingsClient.ts +0 -22
- package/src/lib/settings/types.ts +0 -9
- package/src/lib/storage/StorageClient.ts +0 -131
- package/src/lib/storage/types.ts +0 -86
- package/src/lib/users/UserClient.ts +0 -63
- package/src/lib/users/types.ts +0 -123
- package/src/lib-internal/errors/ErrorClient.ts +0 -114
- package/src/lib-internal/errors/index.ts +0 -3
- package/src/lib-internal/errors/types.ts +0 -29
- package/src/lib-internal/http/HttpClient.ts +0 -116
- package/src/lib-internal/http/types.ts +0 -12
- package/src/lib-internal/routes/AnalyticsRoutes.ts +0 -3
- package/src/lib-internal/routes/AppRoutes.ts +0 -9
- package/src/lib-internal/routes/AuthRoutes.ts +0 -0
- package/src/lib-internal/routes/DatabaseRoutes.ts +0 -10
- package/src/lib-internal/routes/FunctionRoutes.ts +0 -3
- package/src/lib-internal/routes/PolicyRoutes.ts +0 -4
- package/src/lib-internal/routes/SecretsRoutes.ts +0 -5
- package/src/lib-internal/routes/SettingsRoutes.ts +0 -4
- package/src/lib-internal/routes/StorageRoutes.ts +0 -15
- package/src/lib-internal/routes/UserRoutes.ts +0 -12
- package/src/lib-internal/routes/index.ts +0 -0
- package/src/lib-internal/token/TokenClient.ts +0 -108
- package/src/lib-internal/token/types.ts +0 -0
- package/src/types.ts +0 -104
- package/src/utils/enums.ts +0 -24
- package/src/utils/utils.ts +0 -38
- package/tests/fixtures/mockClient.ts +0 -19
- package/tests/mocks/db.json +0 -1
- package/tests/unit/analytics/AnalyticsClient.test.ts +0 -84
- package/tests/unit/app/AppClient.test.ts +0 -114
- package/tests/unit/auth/AuthClient.test.ts +0 -91
- package/tests/unit/client/Client.test.ts +0 -87
- package/tests/unit/database/DatabaseClient.test.ts +0 -652
- package/tests/unit/edge-cases/robustness.test.ts +0 -258
- package/tests/unit/errors/errors.test.ts +0 -236
- package/tests/unit/functions/FunctionsClient.test.ts +0 -99
- package/tests/unit/policy/PolicyClient.test.ts +0 -180
- package/tests/unit/secrets/SecretsClient.test.ts +0 -146
- package/tests/unit/settings/SettingsClient.test.ts +0 -50
- package/tests/unit/storage/StorageClient.test.ts +0 -252
- package/tests/unit/users/UserClient.test.ts +0 -150
- package/tsconfig.json +0 -44
- package/vitest.config.ts +0 -7
|
@@ -1,75 +0,0 @@
|
|
|
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
|
-
}
|
package/src/lib/secrets/types.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { TaruviResponse } from "../../types.js"
|
|
2
|
-
|
|
3
|
-
// Internal types
|
|
4
|
-
export interface SecretsUrlParams {
|
|
5
|
-
path?: string
|
|
6
|
-
queryParams?: Record<string, unknown>
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// Request types - matches SiteSecretIn from backend
|
|
10
|
-
export interface SecretCreateRequest {
|
|
11
|
-
key: string
|
|
12
|
-
value: string | Record<string, unknown>
|
|
13
|
-
secret_type: string
|
|
14
|
-
tags?: string[]
|
|
15
|
-
app?: string
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface SecretUpdateRequest {
|
|
19
|
-
value?: string | Record<string, unknown>
|
|
20
|
-
secret_type?: string
|
|
21
|
-
tags?: string[]
|
|
22
|
-
app?: string
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Options for getting a single secret
|
|
26
|
-
export interface GetSecretOptions {
|
|
27
|
-
app?: string
|
|
28
|
-
tags?: string[]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Options for batch getting secrets
|
|
32
|
-
export interface GetSecretsOptions {
|
|
33
|
-
app?: string
|
|
34
|
-
includeMetadata?: boolean
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Secret data
|
|
38
|
-
export interface SecretData {
|
|
39
|
-
key: string
|
|
40
|
-
value: string | Record<string, unknown>
|
|
41
|
-
tags?: string[]
|
|
42
|
-
secret_type?: string
|
|
43
|
-
created_at?: string
|
|
44
|
-
updated_at?: string
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Response types - uses standard wrapper
|
|
48
|
-
export type SecretResponse = TaruviResponse<SecretData>
|
|
49
|
-
export type SecretsListResponse = TaruviResponse<SecretData[]>
|
|
50
|
-
|
|
51
|
-
// Batch get response - values only
|
|
52
|
-
export type SecretsBatchResponse = TaruviResponse<Record<string, string>>
|
|
53
|
-
|
|
54
|
-
// Batch get response - with metadata
|
|
55
|
-
export type SecretsBatchMetadataResponse = TaruviResponse<Record<string, {
|
|
56
|
-
value: string
|
|
57
|
-
tags: string[]
|
|
58
|
-
secret_type: string
|
|
59
|
-
}>>
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { Client } from "../../client.js";
|
|
2
|
-
import { SettingsRoutes } from "../../lib-internal/routes/SettingsRoutes.js";
|
|
3
|
-
|
|
4
|
-
export class Settings {
|
|
5
|
-
private client: Client
|
|
6
|
-
|
|
7
|
-
constructor(client: Client) {
|
|
8
|
-
this.client = client
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async get<T = unknown>(): Promise<T> {
|
|
12
|
-
return await this.client.httpClient.get<T>(SettingsRoutes.metadata)
|
|
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
|
-
}
|
|
22
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import type { Client } from "../../client.js";
|
|
2
|
-
import type {
|
|
3
|
-
BucketUrlParams,
|
|
4
|
-
StorageResponse,
|
|
5
|
-
StorageListResponse,
|
|
6
|
-
StorageUploadBatchResponse,
|
|
7
|
-
StorageDeleteBatchResponse
|
|
8
|
-
} from "./types.js";
|
|
9
|
-
import { StorageRoutes, type StorageRouteKey } from "../../lib-internal/routes/StorageRoutes.js";
|
|
10
|
-
import type { TaruviConfig, StorageFilters } from "../../types.js";
|
|
11
|
-
import { HttpMethod } from "../../lib-internal/http/types.js";
|
|
12
|
-
import { buildQueryString } from "../../utils/utils.js";
|
|
13
|
-
|
|
14
|
-
export class Storage {
|
|
15
|
-
|
|
16
|
-
private client: Client
|
|
17
|
-
private config: TaruviConfig
|
|
18
|
-
private urlParams: BucketUrlParams
|
|
19
|
-
private operation: HttpMethod | undefined
|
|
20
|
-
private body: object | undefined
|
|
21
|
-
private filters: StorageFilters | undefined
|
|
22
|
-
private queryParams: Record<string, string> | undefined
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
constructor(client: Client, urlParams: BucketUrlParams = {} as BucketUrlParams, operation?: HttpMethod | undefined, body?: object, filters?: StorageFilters, queryParams?: Record<string, string>) {
|
|
26
|
-
this.client = client
|
|
27
|
-
this.urlParams = urlParams
|
|
28
|
-
this.operation = operation
|
|
29
|
-
this.config = this.client.getConfig()
|
|
30
|
-
this.body = body
|
|
31
|
-
this.filters = filters
|
|
32
|
-
this.queryParams = queryParams
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
from(bucket: string): Storage {
|
|
37
|
-
return new Storage(this.client, { ...this.urlParams, bucket }, undefined, undefined)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
filter(filters: StorageFilters) {
|
|
41
|
-
return new Storage(this.client, { ...this.urlParams }, undefined, undefined, filters)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
delete(paths: string[]): Storage {
|
|
45
|
-
return new Storage(this.client, {
|
|
46
|
-
...this.urlParams, delete: "delete"
|
|
47
|
-
}, HttpMethod.POST, { paths })
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
update(path: string, body: object): Storage {
|
|
51
|
-
return new Storage(this.client, { ...this.urlParams, path }, HttpMethod.PUT, body)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
download(path: string): Storage {
|
|
55
|
-
return new Storage(this.client, { ...this.urlParams, path }, HttpMethod.GET)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
metadata(path: string): Storage {
|
|
59
|
-
return new Storage(this.client, { ...this.urlParams, path }, HttpMethod.GET, undefined, undefined, { metadata: 'true' })
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
upload(filesData: { files: File[], metadatas: object[], paths: string[] }): Storage {
|
|
63
|
-
const formData = new FormData()
|
|
64
|
-
filesData.files.forEach(f => formData.append('files', f))
|
|
65
|
-
formData.append('paths', JSON.stringify(filesData.paths))
|
|
66
|
-
formData.append('metadata', JSON.stringify(filesData.metadatas))
|
|
67
|
-
return new Storage(this.client, {
|
|
68
|
-
...this.urlParams, upload: "upload"
|
|
69
|
-
}, HttpMethod.POST, formData)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private buildRoute(): string {
|
|
73
|
-
if (!this.urlParams.bucket) {
|
|
74
|
-
throw new Error('Bucket is required. Call .from(bucketName) first.')
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return (
|
|
78
|
-
StorageRoutes.baseUrl(this.config.appSlug, this.urlParams.bucket) +
|
|
79
|
-
(Object.keys(this.urlParams) as StorageRouteKey[]).reduce((acc, key) => {
|
|
80
|
-
const value = this.urlParams[key as keyof BucketUrlParams]
|
|
81
|
-
|
|
82
|
-
if (!value) return acc
|
|
83
|
-
|
|
84
|
-
if (key === 'path' && typeof value === 'string') {
|
|
85
|
-
acc += StorageRoutes.path(value)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if ((key === 'upload' || key === 'delete') && typeof StorageRoutes[key] === 'function') {
|
|
89
|
-
acc += (StorageRoutes[key] as () => string)()
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return acc
|
|
93
|
-
}, '') +
|
|
94
|
-
'/' +
|
|
95
|
-
buildQueryString({ ...this.filters as Record<string, unknown>, ...this.queryParams })
|
|
96
|
-
)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Execute the storage operation.
|
|
103
|
-
* Returns different types based on the operation:
|
|
104
|
-
* - List files: StorageListResponse[]
|
|
105
|
-
* - Download: Blob
|
|
106
|
-
* - Upload: StorageUploadBatchResponse
|
|
107
|
-
* - Delete: StorageDeleteBatchResponse
|
|
108
|
-
* - Update: StorageResponse
|
|
109
|
-
*/
|
|
110
|
-
async execute<T = StorageListResponse[] | StorageResponse | StorageUploadBatchResponse | StorageDeleteBatchResponse | Blob>(): Promise<T> {
|
|
111
|
-
const url = this.buildRoute()
|
|
112
|
-
const operation = this.operation || HttpMethod.GET
|
|
113
|
-
|
|
114
|
-
switch (operation) {
|
|
115
|
-
case HttpMethod.POST:
|
|
116
|
-
return await this.client.httpClient.post<T>(url, this.body)
|
|
117
|
-
|
|
118
|
-
case HttpMethod.PUT:
|
|
119
|
-
return await this.client.httpClient.put<T>(url, this.body)
|
|
120
|
-
|
|
121
|
-
case HttpMethod.DELETE:
|
|
122
|
-
return await this.client.httpClient.delete<T>(url)
|
|
123
|
-
|
|
124
|
-
case HttpMethod.GET:
|
|
125
|
-
default: {
|
|
126
|
-
const isDownload = this.urlParams.path && !this.queryParams?.metadata
|
|
127
|
-
return await this.client.httpClient.get<T>(url, isDownload ? { responseType: 'blob' } : undefined)
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
package/src/lib/storage/types.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import type { TaruviResponse } from "../../types.js"
|
|
2
|
-
|
|
3
|
-
// Internal types - all optional since they're built incrementally via builder pattern
|
|
4
|
-
export interface BucketUrlParams {
|
|
5
|
-
appSlug?: string
|
|
6
|
-
bucket?: string
|
|
7
|
-
path?: string
|
|
8
|
-
upload?: string
|
|
9
|
-
delete?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface BucketFileUpload {
|
|
13
|
-
files: []
|
|
14
|
-
path: string
|
|
15
|
-
metadata?: Record<string, unknown>
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Request types
|
|
19
|
-
export interface StorageRequest {
|
|
20
|
-
files: File[]
|
|
21
|
-
paths: string[]
|
|
22
|
-
metadatas: object[]
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface StorageUpdateRequest {
|
|
26
|
-
metadata?: Record<string, unknown>
|
|
27
|
-
visibility?: 'public' | 'private'
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Storage object - matches StorageObjectSerializer from API
|
|
31
|
-
export interface StorageObject {
|
|
32
|
-
id: number
|
|
33
|
-
uuid: string
|
|
34
|
-
bucket?: number
|
|
35
|
-
bucket_slug?: string
|
|
36
|
-
bucket_name?: string
|
|
37
|
-
filename: string
|
|
38
|
-
file_path: string
|
|
39
|
-
file_url: string
|
|
40
|
-
size: number
|
|
41
|
-
mimetype: string
|
|
42
|
-
metadata?: Record<string, unknown>
|
|
43
|
-
visibility?: string
|
|
44
|
-
created_at: string
|
|
45
|
-
updated_at: string
|
|
46
|
-
created_by?: string
|
|
47
|
-
modified_by?: string
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Response types - uses standard wrapper
|
|
51
|
-
export type StorageResponse = TaruviResponse<StorageObject>
|
|
52
|
-
export type StorageListResponse = TaruviResponse<StorageObject[]>
|
|
53
|
-
|
|
54
|
-
// Batch upload response
|
|
55
|
-
export interface StorageUploadBatchResponse {
|
|
56
|
-
status: "success" | "error"
|
|
57
|
-
message: string
|
|
58
|
-
data: {
|
|
59
|
-
uploaded_count: number
|
|
60
|
-
failed_count: number
|
|
61
|
-
total: number
|
|
62
|
-
successful: Array<{
|
|
63
|
-
index: number
|
|
64
|
-
path: string
|
|
65
|
-
object: StorageObject
|
|
66
|
-
}>
|
|
67
|
-
failed: Array<{
|
|
68
|
-
index: number
|
|
69
|
-
path: string
|
|
70
|
-
error: string
|
|
71
|
-
}>
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Batch delete response
|
|
76
|
-
export interface StorageDeleteBatchResponse {
|
|
77
|
-
status: "success" | "error"
|
|
78
|
-
message: string
|
|
79
|
-
data: {
|
|
80
|
-
deleted_count: number
|
|
81
|
-
failed: Array<{
|
|
82
|
-
path: string
|
|
83
|
-
error: string
|
|
84
|
-
}>
|
|
85
|
-
}
|
|
86
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type { Client } from "../../client.js";
|
|
2
|
-
import type { UserCreateRequest, UserResponse, UserListResponse, UserListFilters, UserUpdateRequest, UserAppsResponse, AssignRolesRequest, RevokeRolesRequest, RolesResponse, UserPreferencesResponse, UserPreferencesUpdate } from "./types.js";
|
|
3
|
-
import { UserRoutes } from "../../lib-internal/routes/UserRoutes.js";
|
|
4
|
-
import { buildQueryString } from "../../utils/utils.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export class User {
|
|
8
|
-
private client: Client
|
|
9
|
-
|
|
10
|
-
constructor(client: Client) {
|
|
11
|
-
this.client = client
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async updateUser(username: string, body: UserUpdateRequest): Promise<UserResponse> {
|
|
15
|
-
return await this.client.httpClient.put(UserRoutes.updateUser(username), body)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async getUser(username: string): Promise<UserResponse> {
|
|
19
|
-
return await this.client.httpClient.get<UserResponse>(UserRoutes.getUser(username))
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async list(filters?: UserListFilters): Promise<UserListResponse> {
|
|
23
|
-
const queryString = buildQueryString(filters as unknown as Record<string, unknown>)
|
|
24
|
-
return await this.client.httpClient.get<UserListResponse>(UserRoutes.listUser(queryString))
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async getUserApps(username: string): Promise<UserAppsResponse> {
|
|
28
|
-
return await this.client.httpClient.get<UserAppsResponse>(UserRoutes.getUserApps(username))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async createUser(userData: UserCreateRequest): Promise<UserResponse> {
|
|
32
|
-
return await this.client.httpClient.post<UserResponse, UserCreateRequest>(
|
|
33
|
-
UserRoutes.baseUrl,
|
|
34
|
-
userData
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async deleteUser(username: string): Promise<void> {
|
|
39
|
-
return await this.client.httpClient.delete(UserRoutes.deleteUser(username))
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async assignRoles(request: AssignRolesRequest): Promise<RolesResponse> {
|
|
43
|
-
return await this.client.httpClient.post<RolesResponse, AssignRolesRequest>(
|
|
44
|
-
UserRoutes.assignRoles(),
|
|
45
|
-
request
|
|
46
|
-
)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async revokeRoles(request: RevokeRolesRequest): Promise<RolesResponse> {
|
|
50
|
-
return await this.client.httpClient.delete<RolesResponse>(
|
|
51
|
-
UserRoutes.revokeRoles(),
|
|
52
|
-
request
|
|
53
|
-
)
|
|
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
|
-
}
|
|
63
|
-
}
|
package/src/lib/users/types.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import type { TaruviResponse } from "../../types.js"
|
|
2
|
-
|
|
3
|
-
export interface UserCreateRequest {
|
|
4
|
-
username: string
|
|
5
|
-
email: string
|
|
6
|
-
password: string
|
|
7
|
-
confirm_password: string
|
|
8
|
-
first_name: string
|
|
9
|
-
last_name: string
|
|
10
|
-
is_active?: boolean
|
|
11
|
-
is_staff?: boolean
|
|
12
|
-
is_cloud_user?: boolean
|
|
13
|
-
attributes?: Record<string, unknown>
|
|
14
|
-
role_slugs?: string[]
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface UserData {
|
|
18
|
-
id: string
|
|
19
|
-
username: string
|
|
20
|
-
email: string
|
|
21
|
-
first_name: string
|
|
22
|
-
last_name: string
|
|
23
|
-
full_name?: string
|
|
24
|
-
is_active: boolean
|
|
25
|
-
is_staff: boolean
|
|
26
|
-
is_superuser?: boolean
|
|
27
|
-
is_deleted: boolean
|
|
28
|
-
date_joined: string
|
|
29
|
-
last_login?: string
|
|
30
|
-
groups?: UserGroup[]
|
|
31
|
-
user_permissions?: UserPermission[]
|
|
32
|
-
attributes?: Record<string, unknown>
|
|
33
|
-
missing_attributes?: string[]
|
|
34
|
-
roles?: UserRole[]
|
|
35
|
-
icon_url?: string
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface UserGroup {
|
|
39
|
-
id: number
|
|
40
|
-
name: string
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface UserPermission {
|
|
44
|
-
id: number
|
|
45
|
-
name: string
|
|
46
|
-
codename: string
|
|
47
|
-
content_type: string
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface UserRole {
|
|
51
|
-
name: string
|
|
52
|
-
slug: string
|
|
53
|
-
type: string
|
|
54
|
-
app_slug: string
|
|
55
|
-
source: "direct" | "site_role" | "inherited"
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface UserUpdateRequest {
|
|
59
|
-
username?: string
|
|
60
|
-
email?: string
|
|
61
|
-
first_name?: string
|
|
62
|
-
last_name?: string
|
|
63
|
-
is_active?: boolean
|
|
64
|
-
is_staff?: boolean
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface UserListFilters {
|
|
68
|
-
search?: string
|
|
69
|
-
is_active?: boolean
|
|
70
|
-
is_staff?: boolean
|
|
71
|
-
is_superuser?: boolean
|
|
72
|
-
is_deleted?: boolean
|
|
73
|
-
roles?: string
|
|
74
|
-
ordering?: string
|
|
75
|
-
page?: number
|
|
76
|
-
page_size?: number
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface UserApp {
|
|
80
|
-
name: string
|
|
81
|
-
slug: string
|
|
82
|
-
icon: string
|
|
83
|
-
url: string
|
|
84
|
-
display_name: string
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Response types - uses standard wrapper
|
|
88
|
-
export type UserResponse = TaruviResponse<UserData>
|
|
89
|
-
export type UserListResponse = TaruviResponse<UserData[]>
|
|
90
|
-
export type UserAppsResponse = TaruviResponse<UserApp[]>
|
|
91
|
-
|
|
92
|
-
export interface UserPreferences {
|
|
93
|
-
date_format: string
|
|
94
|
-
time_format: string
|
|
95
|
-
timezone: string
|
|
96
|
-
theme: string
|
|
97
|
-
widget_config: Record<string, unknown>
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export interface UserPreferencesUpdate {
|
|
101
|
-
date_format?: string
|
|
102
|
-
time_format?: string
|
|
103
|
-
timezone?: string
|
|
104
|
-
theme?: string
|
|
105
|
-
widget_config?: Record<string, unknown>
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export type UserPreferencesResponse = TaruviResponse<UserPreferences>
|
|
109
|
-
|
|
110
|
-
export interface AssignRolesRequest {
|
|
111
|
-
roles: string[]
|
|
112
|
-
usernames: string[]
|
|
113
|
-
expires_at?: string
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export interface RevokeRolesRequest {
|
|
117
|
-
roles: string[]
|
|
118
|
-
usernames: string[]
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export type RolesResponse = TaruviResponse<{
|
|
122
|
-
count: number
|
|
123
|
-
}>
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { ErrorCode, type ErrorResponseBody } from './types.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Base SDK error. All typed errors extend this.
|
|
5
|
-
*/
|
|
6
|
-
export class TaruviError extends Error {
|
|
7
|
-
public readonly code: string
|
|
8
|
-
public readonly statusCode: number
|
|
9
|
-
public readonly detail: string | undefined
|
|
10
|
-
public readonly errors: Record<string, unknown> | undefined
|
|
11
|
-
public readonly data: unknown
|
|
12
|
-
|
|
13
|
-
constructor(message: string, statusCode: number, code: string = ErrorCode.INTERNAL_ERROR, detail?: string, errors?: Record<string, unknown>, data?: unknown) {
|
|
14
|
-
super(message)
|
|
15
|
-
this.name = 'TaruviError'
|
|
16
|
-
this.statusCode = statusCode
|
|
17
|
-
this.code = code
|
|
18
|
-
this.detail = detail
|
|
19
|
-
this.errors = errors
|
|
20
|
-
this.data = data
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export class ValidationError extends TaruviError {
|
|
25
|
-
constructor(message = 'Validation failed', detail?: string, errors?: Record<string, unknown>) {
|
|
26
|
-
super(message, 400, ErrorCode.VALIDATION_ERROR, detail, errors)
|
|
27
|
-
this.name = 'ValidationError'
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export class AuthError extends TaruviError {
|
|
32
|
-
constructor(message = 'Authentication required') {
|
|
33
|
-
super(message, 401, ErrorCode.UNAUTHORIZED)
|
|
34
|
-
this.name = 'AuthError'
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export class ForbiddenError extends TaruviError {
|
|
39
|
-
constructor(message = 'Permission denied') {
|
|
40
|
-
super(message, 403, ErrorCode.FORBIDDEN)
|
|
41
|
-
this.name = 'ForbiddenError'
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export class NotFoundError extends TaruviError {
|
|
46
|
-
constructor(message = 'Resource not found') {
|
|
47
|
-
super(message, 404, ErrorCode.NOT_FOUND)
|
|
48
|
-
this.name = 'NotFoundError'
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export class ConflictError extends TaruviError {
|
|
53
|
-
constructor(message = 'Resource conflict', detail?: string) {
|
|
54
|
-
super(message, 409, ErrorCode.CONFLICT, detail)
|
|
55
|
-
this.name = 'ConflictError'
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export class TimeoutError extends TaruviError {
|
|
60
|
-
constructor(message = 'Request timeout') {
|
|
61
|
-
super(message, 504, ErrorCode.GATEWAY_TIMEOUT)
|
|
62
|
-
this.name = 'TimeoutError'
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export class RateLimitError extends TaruviError {
|
|
67
|
-
public readonly retryAfter: number | undefined
|
|
68
|
-
|
|
69
|
-
constructor(message = 'Rate limit exceeded', retryAfter?: number) {
|
|
70
|
-
super(message, 429, ErrorCode.RATE_LIMITED)
|
|
71
|
-
this.name = 'RateLimitError'
|
|
72
|
-
this.retryAfter = retryAfter
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export class NetworkError extends TaruviError {
|
|
77
|
-
constructor(message = 'Network error') {
|
|
78
|
-
super(message, 0, ErrorCode.NETWORK_ERROR)
|
|
79
|
-
this.name = 'NetworkError'
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Maps HTTP status + response body to the appropriate typed error.
|
|
85
|
-
*/
|
|
86
|
-
export function createErrorFromResponse(statusCode: number, body?: ErrorResponseBody): TaruviError {
|
|
87
|
-
const message = body?.message || 'Request failed'
|
|
88
|
-
const code = body?.code || ErrorCode.INTERNAL_ERROR
|
|
89
|
-
const detail = body?.detail
|
|
90
|
-
const errors = body?.errors
|
|
91
|
-
const data = body?.data
|
|
92
|
-
|
|
93
|
-
switch (statusCode) {
|
|
94
|
-
case 400:
|
|
95
|
-
if (code === ErrorCode.VALIDATION_ERROR) {
|
|
96
|
-
return new ValidationError(message, detail, errors)
|
|
97
|
-
}
|
|
98
|
-
return new TaruviError(message, 400, code, detail, errors, data)
|
|
99
|
-
case 401:
|
|
100
|
-
return new AuthError(message)
|
|
101
|
-
case 403:
|
|
102
|
-
return new ForbiddenError(message)
|
|
103
|
-
case 404:
|
|
104
|
-
return new NotFoundError(message)
|
|
105
|
-
case 409:
|
|
106
|
-
return new ConflictError(message, detail)
|
|
107
|
-
case 429:
|
|
108
|
-
return new RateLimitError(message)
|
|
109
|
-
case 504:
|
|
110
|
-
return new TimeoutError(message)
|
|
111
|
-
default:
|
|
112
|
-
return new TaruviError(message, statusCode, code, detail, errors, data)
|
|
113
|
-
}
|
|
114
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export { TaruviError, ValidationError, AuthError, ForbiddenError, NotFoundError, ConflictError, TimeoutError, NetworkError, RateLimitError, createErrorFromResponse } from './ErrorClient.js'
|
|
2
|
-
export { ErrorCode } from './types.js'
|
|
3
|
-
export type { ErrorResponseBody } from './types.js'
|