@taruvi/sdk 1.0.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/.claude/settings.local.json +16 -0
- package/DATAPROVIDER_CONTEXT.md +828 -0
- package/README.md +703 -0
- package/USAGE_EXAMPLE.md +86 -0
- package/package.json +25 -0
- package/src/client.ts +81 -0
- package/src/index.ts +20 -0
- package/src/lib/Database/DatabaseClient.ts +87 -0
- package/src/lib/Database/types.ts +29 -0
- package/src/lib/Function/FunctionsClient.ts +27 -0
- package/src/lib/Function/types.ts +17 -0
- package/src/lib/Secrets/SecretsClient.ts +44 -0
- package/src/lib/Secrets/types.ts +17 -0
- package/src/lib/Settings/SettingsClient.ts +14 -0
- package/src/lib/Settings/types.ts +4 -0
- package/src/lib/Storage/StorageClient.ts +88 -0
- package/src/lib/Storage/types.ts +40 -0
- package/src/lib/auth/AuthClient.ts +64 -0
- package/src/lib/auth/types.ts +9 -0
- package/src/lib/user/UserClient.ts +44 -0
- package/src/lib/user/types.ts +69 -0
- package/src/lib-internal/errors/ErrorClient.ts +12 -0
- package/src/lib-internal/errors/index.ts +25 -0
- package/src/lib-internal/errors/types.ts +105 -0
- package/src/lib-internal/http/HttpClient.ts +96 -0
- package/src/lib-internal/http/types.ts +10 -0
- package/src/lib-internal/routes/AuthRoutes.ts +0 -0
- package/src/lib-internal/routes/DatabaseRoutes.ts +5 -0
- package/src/lib-internal/routes/FunctionRoutes.ts +3 -0
- package/src/lib-internal/routes/RouteBuilder.ts +0 -0
- package/src/lib-internal/routes/SecretsRoutes.ts +5 -0
- package/src/lib-internal/routes/SettingsRoutes.ts +3 -0
- package/src/lib-internal/routes/StorageRoutes.ts +7 -0
- package/src/lib-internal/routes/UserRoutes.ts +9 -0
- package/src/lib-internal/routes/index.ts +0 -0
- package/src/lib-internal/token/TokenClient.ts +30 -0
- package/src/lib-internal/token/types.ts +0 -0
- package/src/types.ts +68 -0
- package/src/utils/enums.ts +12 -0
- package/src/utils/utils.ts +36 -0
- package/tests/mocks/db.json +1 -0
- package/tsconfig.json +43 -0
package/USAGE_EXAMPLE.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Taruvi SDK - Usage Example
|
|
2
|
+
|
|
3
|
+
## New Pattern: Dependency Injection (No Singleton)
|
|
4
|
+
|
|
5
|
+
### Basic Usage
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { Client, Auth, User, Database } from '@taruvi/sdk'
|
|
9
|
+
|
|
10
|
+
// 1. Create the main client (can create multiple instances)
|
|
11
|
+
const client = new Client({
|
|
12
|
+
apiKey: 'your-site-key',
|
|
13
|
+
appSlug: 'my-app',
|
|
14
|
+
baseUrl: 'https://api.taruvi.com',
|
|
15
|
+
token: 'optional-initial-token' // optional
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
// 2. Create only the clients you need (lazy initialization)
|
|
19
|
+
const auth = new Auth(client)
|
|
20
|
+
const user = new User(client)
|
|
21
|
+
const database = new Database(client)
|
|
22
|
+
|
|
23
|
+
// 3. Use the clients
|
|
24
|
+
if (auth.isUserAuthenticated()) {
|
|
25
|
+
console.log('User is authenticated')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const token = auth.signInWithSSO()
|
|
29
|
+
console.log('Token:', token)
|
|
30
|
+
|
|
31
|
+
const userDetails = user.getUser()
|
|
32
|
+
console.log('User:', userDetails)
|
|
33
|
+
|
|
34
|
+
// Access token via User
|
|
35
|
+
console.log('Current token:', user.token)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Multiple Instances
|
|
39
|
+
|
|
40
|
+
You can now create multiple instances for different environments or configs:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
const prodClient = new Client({
|
|
44
|
+
apiKey: 'prod-key',
|
|
45
|
+
appSlug: 'main-app',
|
|
46
|
+
baseUrl: 'https://api.taruvi.com'
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const devClient = new Client({
|
|
50
|
+
apiKey: 'dev-key',
|
|
51
|
+
appSlug: 'dev-app',
|
|
52
|
+
baseUrl: 'https://dev-api.taruvi.com'
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const prodAuth = new Auth(prodClient)
|
|
56
|
+
const devAuth = new Auth(devClient)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Benefits
|
|
60
|
+
|
|
61
|
+
✅ **No singleton** - Multiple instances possible
|
|
62
|
+
✅ **Lazy initialization** - Only create clients you need
|
|
63
|
+
✅ **Better testability** - Easy to mock and test
|
|
64
|
+
✅ **Explicit dependencies** - Clear what each client needs
|
|
65
|
+
✅ **No global state** - No hidden global `taruvi` variable
|
|
66
|
+
✅ **Tree-shakable** - Only bundle what you use
|
|
67
|
+
|
|
68
|
+
### Internal Architecture
|
|
69
|
+
|
|
70
|
+
The `taruvi` variable is no longer exported. Internal clients like `httpClient` and `tokenClient` are accessible only within the SDK through the `Client` instance passed to each client.
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// Inside Auth
|
|
74
|
+
export class Auth {
|
|
75
|
+
private client: Client
|
|
76
|
+
|
|
77
|
+
constructor(client: Client) {
|
|
78
|
+
this.client = client
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
isUserAuthenticated(): boolean {
|
|
82
|
+
// Access internal tokenClient through the client instance
|
|
83
|
+
return !!this.client.tokenClient.getToken()
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@taruvi/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Taruvi SDK",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"taruvi",
|
|
12
|
+
"sdk",
|
|
13
|
+
"EOX Vantage"
|
|
14
|
+
],
|
|
15
|
+
"author": "Curran C Doddabele",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "^24.10.1",
|
|
19
|
+
"typescript": "^5.7.3"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"@types/node": "^18.0.0 || ^20.0.0 || ^22.0.0",
|
|
23
|
+
"axios": "^1.0.0"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
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
|
+
|
|
5
|
+
export class Client {
|
|
6
|
+
private readonly config: TaruviConfig
|
|
7
|
+
private readonly _httpClient: HttpClient
|
|
8
|
+
private readonly _tokenClient: TokenClient
|
|
9
|
+
|
|
10
|
+
constructor(config: TaruviConfig) {
|
|
11
|
+
if (!config) {
|
|
12
|
+
throw new Error("Config is required")
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (!config.apiKey) {
|
|
16
|
+
throw new Error("API key is required")
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!config.baseUrl) {
|
|
20
|
+
throw new Error("Base URL is required")
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
this.config = config
|
|
24
|
+
|
|
25
|
+
// Internal clients for SDK use only
|
|
26
|
+
// TokenClient must be created first, then passed to HttpClient
|
|
27
|
+
|
|
28
|
+
this._tokenClient = new TokenClient(config.token)
|
|
29
|
+
this._httpClient = new HttpClient(this.config, this._tokenClient)
|
|
30
|
+
|
|
31
|
+
// Check URL hash for tokens (OAuth callback)
|
|
32
|
+
this.extractTokensFromUrl()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Extracts access_token and refresh_token from URL hash and stores them in localStorage.
|
|
37
|
+
* This handles OAuth callback URLs like: #access_token=xxx&refresh_token=xxx
|
|
38
|
+
*/
|
|
39
|
+
private extractTokensFromUrl(): void {
|
|
40
|
+
if (typeof window === "undefined" || typeof localStorage === "undefined") {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const hash = window.location.hash
|
|
45
|
+
if (!hash) {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const params = new URLSearchParams(hash.substring(1))
|
|
50
|
+
const accessToken = params.get("access_token")
|
|
51
|
+
const refreshToken = params.get("refresh_token")
|
|
52
|
+
|
|
53
|
+
if (accessToken) {
|
|
54
|
+
localStorage.setItem("jwt", accessToken)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (refreshToken) {
|
|
58
|
+
localStorage.setItem("refresh_token", refreshToken)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @internal
|
|
64
|
+
* Internal use only - not part of public API
|
|
65
|
+
*/
|
|
66
|
+
get httpClient(): HttpClient {
|
|
67
|
+
return this._httpClient
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @internal
|
|
72
|
+
* Internal use only - not part of public API
|
|
73
|
+
*/
|
|
74
|
+
get tokenClient(): TokenClient {
|
|
75
|
+
return this._tokenClient
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getConfig(): Readonly<TaruviConfig> {
|
|
79
|
+
return { ...this.config }
|
|
80
|
+
}
|
|
81
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Export main client
|
|
2
|
+
export { Client } from "./client.js"
|
|
3
|
+
|
|
4
|
+
// Export public client classes
|
|
5
|
+
export { Auth } from "./lib/auth/AuthClient.js"
|
|
6
|
+
export { User } from "./lib/user/UserClient.js"
|
|
7
|
+
export { Storage } from "./lib/Storage/StorageClient.js"
|
|
8
|
+
export { Database } from "./lib/Database/DatabaseClient.js"
|
|
9
|
+
export { Settings } from "./lib/Settings/SettingsClient.js"
|
|
10
|
+
export { Functions } from "./lib/Function/FunctionsClient.js"
|
|
11
|
+
export { Secrets } from "./lib/Secrets/SecretsClient.js"
|
|
12
|
+
|
|
13
|
+
// Export types
|
|
14
|
+
export type { TaruviConfig, StorageFilters, DatabaseFilters } from "./types.js"
|
|
15
|
+
export type { UserCreateRequest, UserCreateResponse as UserResponse, UserDataResponse } from "./lib/user/types.js"
|
|
16
|
+
export type { FunctionRequest, FunctionResponse, FunctionInvocation } from "./lib/Function/types.js"
|
|
17
|
+
export type { DatabaseRequest, DatabaseResponse } from "./lib/Database/types.js"
|
|
18
|
+
export type { StorageRequest, StorageUpdateRequest, StorageResponse } from "./lib/Storage/types.js"
|
|
19
|
+
export type { SettingsRequest, SettingsResponse, SettingsMetadataResponse } from "./lib/Settings/types.js"
|
|
20
|
+
export type { SecretRequest, SecretResponse } from "./lib/Secrets/types.js"
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Client } from "../../client.js";
|
|
2
|
+
import { DatabaseRoutes } from "../../lib-internal/routes/DatabaseRoutes.js";
|
|
3
|
+
import { HttpMethod } from "../../lib-internal/http/types.js";
|
|
4
|
+
import type { TaruviConfig, DatabaseFilters } from "../../types.js";
|
|
5
|
+
import type { UrlParams } from "./types.js";
|
|
6
|
+
import { buildQueryString } from "../../utils/utils.js";
|
|
7
|
+
|
|
8
|
+
// Used to access app data
|
|
9
|
+
export class Database {
|
|
10
|
+
private client: Client
|
|
11
|
+
private urlParams: UrlParams
|
|
12
|
+
private config: TaruviConfig
|
|
13
|
+
private operation: HttpMethod | undefined
|
|
14
|
+
private body: object | undefined
|
|
15
|
+
private filters: DatabaseFilters | undefined
|
|
16
|
+
|
|
17
|
+
constructor(client: Client, urlParams: UrlParams, operation?: HttpMethod | undefined, body?: object | undefined, filters?: 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.filters = filters
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
from(dataTables: string): Database {
|
|
27
|
+
return new Database(this.client, { ...this.urlParams, dataTables }, undefined, undefined)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
filter(filters: DatabaseFilters): Database {
|
|
31
|
+
return new Database(this.client, { ...this.urlParams }, undefined, undefined, filters)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get(recordId: string): Database {
|
|
35
|
+
return new Database(this.client, this.urlParams = { ...this.urlParams, recordId }, HttpMethod.GET)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
update(body: any): Database {
|
|
39
|
+
return new Database(this.client, this.urlParams = { ...this.urlParams }, HttpMethod.POST, body)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
delete(recordId?: any): Database {
|
|
43
|
+
return new Database(this.client, this.urlParams = { ...this.urlParams, recordId }, HttpMethod.DELETE)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private buildRoute(): string {
|
|
47
|
+
return DatabaseRoutes.baseUrl(this.config.appSlug) + Object.keys(this.urlParams).reduce((acc, key) => {
|
|
48
|
+
if (this.urlParams[key] && DatabaseRoutes[key]) {
|
|
49
|
+
acc += DatabaseRoutes[key](this.urlParams[key])
|
|
50
|
+
}
|
|
51
|
+
return acc
|
|
52
|
+
}, "") + "/" + buildQueryString(this.filters)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async execute() {
|
|
56
|
+
// Build the API URL
|
|
57
|
+
const url = this.buildRoute()
|
|
58
|
+
const fullUrl = `sites/eox_site/${url}` //remove for productions because baseurl is in the appscope, no need for site
|
|
59
|
+
|
|
60
|
+
const operation = this.operation || HttpMethod.GET
|
|
61
|
+
|
|
62
|
+
switch (operation) {
|
|
63
|
+
case HttpMethod.POST:
|
|
64
|
+
return await this.client.httpClient.post(fullUrl, this.body)
|
|
65
|
+
|
|
66
|
+
case HttpMethod.PUT:
|
|
67
|
+
if (!this.urlParams.recordId) {
|
|
68
|
+
throw new Error('PUT operation requires a record ID. Use .get(recordId) before .update()')
|
|
69
|
+
}
|
|
70
|
+
return await this.client.httpClient.put(fullUrl, this.body)
|
|
71
|
+
|
|
72
|
+
case HttpMethod.DELETE:
|
|
73
|
+
return await this.client.httpClient.delete(fullUrl)
|
|
74
|
+
|
|
75
|
+
case HttpMethod.GET:
|
|
76
|
+
default:
|
|
77
|
+
return await this.client.httpClient.get(fullUrl)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
// TODO: Implement storage operations
|
|
84
|
+
// - upload files
|
|
85
|
+
// - download files
|
|
86
|
+
// - delete files
|
|
87
|
+
// - list files
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Client } from "../../client.js"
|
|
2
|
+
import { HttpMethod } from "../../lib-internal/http/types.js"
|
|
3
|
+
|
|
4
|
+
export type DatabaseOperation = HttpMethod
|
|
5
|
+
|
|
6
|
+
// Internal types
|
|
7
|
+
export interface UrlParams {
|
|
8
|
+
appSlug?: string
|
|
9
|
+
dataTables?: string
|
|
10
|
+
recordId?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface DatabaseClientInterface {
|
|
14
|
+
client: Client
|
|
15
|
+
urlParams?: UrlParams
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Request types
|
|
19
|
+
export interface DatabaseRequest {
|
|
20
|
+
[key: string]: unknown
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Response types
|
|
24
|
+
export interface DatabaseResponse<T = unknown> {
|
|
25
|
+
id?: string | number
|
|
26
|
+
created_at?: string
|
|
27
|
+
updated_at?: string
|
|
28
|
+
[key: string]: T | string | number | undefined
|
|
29
|
+
}
|
|
@@ -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,17 @@
|
|
|
1
|
+
export interface FunctionRequest {
|
|
2
|
+
async?: boolean
|
|
3
|
+
params?: Record<string, unknown>
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface FunctionInvocation {
|
|
7
|
+
invocation_id: number
|
|
8
|
+
celery_task_id: string
|
|
9
|
+
status: string
|
|
10
|
+
created_at: string
|
|
11
|
+
updated_at: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface FunctionResponse<T = unknown> {
|
|
15
|
+
data: T | null
|
|
16
|
+
invocation: FunctionInvocation
|
|
17
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Client } from "../../client.js";
|
|
2
|
+
import type { SecretsUrlParams } from "./types.js";
|
|
3
|
+
import { HttpMethod } from "../../lib-internal/http/types.js";
|
|
4
|
+
import { SecretsRoutes } from "../../lib-internal/routes/SecretsRoutes.js";
|
|
5
|
+
|
|
6
|
+
export class Secrets {
|
|
7
|
+
private client: Client
|
|
8
|
+
private urlParams: SecretsUrlParams
|
|
9
|
+
private body: object | undefined
|
|
10
|
+
private method: HttpMethod
|
|
11
|
+
|
|
12
|
+
constructor(client: Client, urlParams: SecretsUrlParams = {}, body?: object, method: HttpMethod = HttpMethod.GET) {
|
|
13
|
+
this.client = client
|
|
14
|
+
this.urlParams = urlParams
|
|
15
|
+
this.body = body
|
|
16
|
+
this.method = method
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
list(): Secrets {
|
|
20
|
+
return new Secrets(this.client, { path: SecretsRoutes.baseUrl }, undefined, HttpMethod.GET)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get(key: string): Secrets {
|
|
24
|
+
const path = SecretsRoutes.get(key)
|
|
25
|
+
return new Secrets(this.client, { ...this.urlParams, path }, undefined, HttpMethod.GET)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
update(key: string, body: object): Secrets {
|
|
29
|
+
const path = SecretsRoutes.update(key)
|
|
30
|
+
return new Secrets(this.client, { ...this.urlParams, path }, body, HttpMethod.PUT)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async execute<T = unknown>(): Promise<T> {
|
|
34
|
+
const url = this.urlParams.path ?? SecretsRoutes.baseUrl
|
|
35
|
+
|
|
36
|
+
switch (this.method) {
|
|
37
|
+
case HttpMethod.PUT:
|
|
38
|
+
return await this.client.httpClient.put<T>(url, this.body)
|
|
39
|
+
case HttpMethod.GET:
|
|
40
|
+
default:
|
|
41
|
+
return await this.client.httpClient.get<T>(url)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Internal types
|
|
2
|
+
export interface SecretsUrlParams {
|
|
3
|
+
path?: string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// Request types
|
|
7
|
+
export interface SecretRequest {
|
|
8
|
+
value: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Response types
|
|
12
|
+
export interface SecretResponse {
|
|
13
|
+
key: string
|
|
14
|
+
value: string
|
|
15
|
+
created_at?: string
|
|
16
|
+
updated_at?: string
|
|
17
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { Client } from "../../client.js";
|
|
2
|
+
import type { BucketFileUpload, BucketUrlParams } from "./types.js";
|
|
3
|
+
import { StorageRoutes } from "../../lib-internal/routes/StorageRoutes.js";
|
|
4
|
+
import type { TaruviConfig, StorageFilters } from "../../types.js";
|
|
5
|
+
import { HttpMethod } from "../../lib-internal/http/types.js";
|
|
6
|
+
import { buildQueryString } from "../../utils/utils.js";
|
|
7
|
+
|
|
8
|
+
export class Storage {
|
|
9
|
+
|
|
10
|
+
private client: Client
|
|
11
|
+
private config: TaruviConfig
|
|
12
|
+
private urlParams: BucketUrlParams
|
|
13
|
+
private operation: HttpMethod | undefined
|
|
14
|
+
private body: object | undefined
|
|
15
|
+
private filters: StorageFilters | undefined
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
constructor(client: Client, urlParams: BucketUrlParams, operation?: HttpMethod | undefined, body?: object, filters?: StorageFilters) {
|
|
19
|
+
this.client = client
|
|
20
|
+
this.urlParams = urlParams
|
|
21
|
+
this.operation = operation
|
|
22
|
+
this.config = this.client.getConfig()
|
|
23
|
+
this.body = body
|
|
24
|
+
this.filters = filters
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
from(bucket: string): Storage {
|
|
29
|
+
return new Storage(this.client, { ...this.urlParams, bucket }, undefined, undefined)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
filter(filters: StorageFilters) {
|
|
33
|
+
return new Storage(this.client, { ...this.urlParams }, undefined, undefined, filters)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
delete(path: string): Storage {
|
|
37
|
+
return new Storage(this.client, { ...this.urlParams, path }, HttpMethod.DELETE)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
update(path: string, body: object): Storage {
|
|
41
|
+
return new Storage(this.client, { ...this.urlParams, path }, HttpMethod.PUT, body)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
download(path: string): Storage {
|
|
45
|
+
return new Storage(this.client, { ...this.urlParams, path }, HttpMethod.GET)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
upload(filesData: { files: File[], metadatas: object[], paths: string[] }): Storage {
|
|
49
|
+
const formData = new FormData()
|
|
50
|
+
filesData.files.forEach(f => formData.append('files', f))
|
|
51
|
+
formData.append('paths', JSON.stringify(filesData.paths))
|
|
52
|
+
formData.append('metadata', JSON.stringify(filesData.metadatas))
|
|
53
|
+
return new Storage(this.client, {
|
|
54
|
+
...this.urlParams, upload: "upload"
|
|
55
|
+
}, HttpMethod.POST, formData)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
private buildRoute(): string {
|
|
60
|
+
return StorageRoutes.baseUrl(this.config.appSlug, this.urlParams.bucket) + Object.keys(this.urlParams).reduce((acc, key) => {
|
|
61
|
+
if (this.urlParams[key] && StorageRoutes[key]) {
|
|
62
|
+
acc += StorageRoutes[key](this.urlParams[key])
|
|
63
|
+
}
|
|
64
|
+
return acc
|
|
65
|
+
}, "") + "/" + buildQueryString(this.filters as Record<string, unknown>)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async execute(): Promise<T> {
|
|
69
|
+
const url = this.buildRoute()
|
|
70
|
+
const operation = this.operation || HttpMethod.GET
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
switch (operation) {
|
|
74
|
+
case HttpMethod.POST:
|
|
75
|
+
return await this.client.httpClient.post(url, this.body)
|
|
76
|
+
|
|
77
|
+
case HttpMethod.PUT:
|
|
78
|
+
return await this.client.httpClient.put(url, this.body)
|
|
79
|
+
|
|
80
|
+
case HttpMethod.DELETE:
|
|
81
|
+
return await this.client.httpClient.delete(url)
|
|
82
|
+
|
|
83
|
+
case HttpMethod.GET:
|
|
84
|
+
default:
|
|
85
|
+
return await this.client.httpClient.get(url)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Internal types
|
|
2
|
+
export interface BucketUrlParams {
|
|
3
|
+
appSlug: string
|
|
4
|
+
bucket: string
|
|
5
|
+
path?: string | undefined
|
|
6
|
+
upload: string,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface BucketFileUpload {
|
|
10
|
+
files: []
|
|
11
|
+
path: string
|
|
12
|
+
metadata?: Record<string, unknown>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Request types
|
|
16
|
+
export interface StorageRequest {
|
|
17
|
+
files: File[]
|
|
18
|
+
paths: string[]
|
|
19
|
+
metadatas: object[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface StorageUpdateRequest {
|
|
23
|
+
metadata?: Record<string, unknown>
|
|
24
|
+
visibility?: 'public' | 'private'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Response types
|
|
28
|
+
export interface StorageResponse {
|
|
29
|
+
id: number
|
|
30
|
+
uuid: string
|
|
31
|
+
filename: string
|
|
32
|
+
file_path: string
|
|
33
|
+
file_url: string
|
|
34
|
+
size: number
|
|
35
|
+
mimetype: string
|
|
36
|
+
metadata?: Record<string, unknown>
|
|
37
|
+
visibility?: string
|
|
38
|
+
created_at: string
|
|
39
|
+
updated_at: string
|
|
40
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Client } from "../../client.js";
|
|
2
|
+
import { User } from "../user/UserClient.js";
|
|
3
|
+
import { Settings } from "../Settings/SettingsClient.js";
|
|
4
|
+
|
|
5
|
+
// handles user auth not dev auth
|
|
6
|
+
export class Auth {
|
|
7
|
+
private client: Client
|
|
8
|
+
|
|
9
|
+
constructor(client: Client) {
|
|
10
|
+
this.client = client
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async authenticateUser() {
|
|
14
|
+
// const myHeaders = new Headers();
|
|
15
|
+
// myHeaders.append("sec-ch-ua-platform", "\"Linux\"");
|
|
16
|
+
// myHeaders.append("Referer", "http://localhost:5173/");
|
|
17
|
+
// myHeaders.append("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36");
|
|
18
|
+
// myHeaders.append("sec-ch-ua", "\"Chromium\";v=\"142\", \"Google Chrome\";v=\"142\", \"Not_A Brand\";v=\"99\"");
|
|
19
|
+
// myHeaders.append("Content-Type", "application/json");
|
|
20
|
+
// myHeaders.append("sec-ch-ua-mobile", "?0");
|
|
21
|
+
|
|
22
|
+
// const raw = JSON.stringify({
|
|
23
|
+
// "password": "admin123",
|
|
24
|
+
// "email": "admin@example.com"
|
|
25
|
+
// });
|
|
26
|
+
|
|
27
|
+
// const requestOptions: RequestInit = {
|
|
28
|
+
// method: "POST",
|
|
29
|
+
// headers: myHeaders,
|
|
30
|
+
// body: raw,
|
|
31
|
+
// redirect: "follow"
|
|
32
|
+
// };
|
|
33
|
+
|
|
34
|
+
// await fetch("https://test-api.taruvi.cloud/api/v1/auth/login", requestOptions)
|
|
35
|
+
// .then((response) => response.json())
|
|
36
|
+
// .then((result) => {
|
|
37
|
+
// localStorage.setItem("jwt", result.meta.accesstoken)
|
|
38
|
+
// })
|
|
39
|
+
// .catch((error) => console.error(error));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async isUserAuthenticated(): Promise<boolean> {
|
|
43
|
+
const authValue = localStorage.getItem("jwt")
|
|
44
|
+
return authValue ? true : false
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async redirectToLogin() {
|
|
48
|
+
const settings = new Settings(this.client)
|
|
49
|
+
// let { frontEndUrl } = await settings.get().execute()
|
|
50
|
+
let frontEndUrl
|
|
51
|
+
const currentUrl = window.location.href
|
|
52
|
+
|
|
53
|
+
if (!frontEndUrl) frontEndUrl = this.client.getConfig().deskUrl
|
|
54
|
+
window.location.href = frontEndUrl + `?redirect=${currentUrl}`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// TODO: Implement authentication methods
|
|
58
|
+
// - signInWithSSO
|
|
59
|
+
// - signInWithPassword ?
|
|
60
|
+
// - signOut
|
|
61
|
+
// - isUserAuthenticated
|
|
62
|
+
// - refreshSession
|
|
63
|
+
// - redirectToLogin
|
|
64
|
+
}
|