@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.
Files changed (42) hide show
  1. package/.claude/settings.local.json +16 -0
  2. package/DATAPROVIDER_CONTEXT.md +828 -0
  3. package/README.md +703 -0
  4. package/USAGE_EXAMPLE.md +86 -0
  5. package/package.json +25 -0
  6. package/src/client.ts +81 -0
  7. package/src/index.ts +20 -0
  8. package/src/lib/Database/DatabaseClient.ts +87 -0
  9. package/src/lib/Database/types.ts +29 -0
  10. package/src/lib/Function/FunctionsClient.ts +27 -0
  11. package/src/lib/Function/types.ts +17 -0
  12. package/src/lib/Secrets/SecretsClient.ts +44 -0
  13. package/src/lib/Secrets/types.ts +17 -0
  14. package/src/lib/Settings/SettingsClient.ts +14 -0
  15. package/src/lib/Settings/types.ts +4 -0
  16. package/src/lib/Storage/StorageClient.ts +88 -0
  17. package/src/lib/Storage/types.ts +40 -0
  18. package/src/lib/auth/AuthClient.ts +64 -0
  19. package/src/lib/auth/types.ts +9 -0
  20. package/src/lib/user/UserClient.ts +44 -0
  21. package/src/lib/user/types.ts +69 -0
  22. package/src/lib-internal/errors/ErrorClient.ts +12 -0
  23. package/src/lib-internal/errors/index.ts +25 -0
  24. package/src/lib-internal/errors/types.ts +105 -0
  25. package/src/lib-internal/http/HttpClient.ts +96 -0
  26. package/src/lib-internal/http/types.ts +10 -0
  27. package/src/lib-internal/routes/AuthRoutes.ts +0 -0
  28. package/src/lib-internal/routes/DatabaseRoutes.ts +5 -0
  29. package/src/lib-internal/routes/FunctionRoutes.ts +3 -0
  30. package/src/lib-internal/routes/RouteBuilder.ts +0 -0
  31. package/src/lib-internal/routes/SecretsRoutes.ts +5 -0
  32. package/src/lib-internal/routes/SettingsRoutes.ts +3 -0
  33. package/src/lib-internal/routes/StorageRoutes.ts +7 -0
  34. package/src/lib-internal/routes/UserRoutes.ts +9 -0
  35. package/src/lib-internal/routes/index.ts +0 -0
  36. package/src/lib-internal/token/TokenClient.ts +30 -0
  37. package/src/lib-internal/token/types.ts +0 -0
  38. package/src/types.ts +68 -0
  39. package/src/utils/enums.ts +12 -0
  40. package/src/utils/utils.ts +36 -0
  41. package/tests/mocks/db.json +1 -0
  42. package/tsconfig.json +43 -0
@@ -0,0 +1,44 @@
1
+ import type { Client } from "../../client.js";
2
+ import type { UserCreateRequest, UserCreateResponse, UserDataResponse, UserList, UserUpdateRequest } 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
+ // - getUserProfile
15
+ async getUserData(): Promise<UserDataResponse> {
16
+ return await this.client.httpClient.get<UserDataResponse>(UserRoutes.getCurrentUser())
17
+ }
18
+
19
+ // - updateUser
20
+ async updateUser(username: string, body: UserUpdateRequest): Promise<UserCreateResponse> {
21
+ return await this.client.httpClient.put(UserRoutes.updateUser(username), body)
22
+ }
23
+
24
+ async list(filters: UserList) {
25
+ const queryString = buildQueryString(filters as unknown as Record<string, unknown>)
26
+ return await this.client.httpClient.get(UserRoutes.listUser(queryString))
27
+ }
28
+
29
+ // - createUser
30
+ async createUser(userData: UserCreateRequest): Promise<UserCreateResponse> {
31
+ return await this.client.httpClient.post<UserCreateResponse, UserCreateRequest>(
32
+ UserRoutes.baseUrl,
33
+ userData
34
+ )
35
+ }
36
+
37
+ // - deleteUser
38
+ async deleteUser(username: string): Promise<void> {
39
+ return await this.client.httpClient.delete(UserRoutes.deleteUser(username))
40
+ }
41
+
42
+ // TODO: Implement user management methods
43
+ // - token getter (access JWT token)
44
+ }
@@ -0,0 +1,69 @@
1
+ export interface UserCreateRequest {
2
+ username: string,
3
+ email: string,
4
+ password: string,
5
+ confirm_password: string,
6
+ first_name: string,
7
+ last_name: string,
8
+ is_active: boolean,
9
+ is_staff: boolean,
10
+ attributes: string
11
+ }
12
+
13
+ export interface UserCreateResponse {
14
+ username: string,
15
+ email: string,
16
+ first_name: string,
17
+ last_name: string,
18
+ is_active: boolean,
19
+ is_staff: boolean,
20
+ attributes: string
21
+ }
22
+
23
+ export interface UserDataResponse {
24
+ id: number,
25
+ username: string,
26
+ email: string,
27
+ first_name: string,
28
+ last_name: string,
29
+ full_name: string,
30
+ is_active: boolean,
31
+ is_staff: boolean,
32
+ is_deleted: boolean,
33
+ date_joined: string, // ISO 8601 date-time string
34
+ last_login: string, // ISO 8601 date-time string
35
+ attributes: string
36
+ }
37
+
38
+ export interface UserUpdateRequest {
39
+ username?: string,
40
+ email?: string,
41
+ password?: string,
42
+ confirm_password?: string,
43
+ first_name?: string,
44
+ last_name?: string,
45
+ is_active?: boolean,
46
+ is_staff?: boolean,
47
+ attributes?: string
48
+ }
49
+
50
+ export interface UserUpdateResponse {
51
+ username: string,
52
+ email: string,
53
+ first_name: string,
54
+ last_name: string,
55
+ is_active: boolean,
56
+ is_staff: boolean,
57
+ attributes: string
58
+ }
59
+
60
+ export interface UserList {
61
+ search: string
62
+ is_active: boolean
63
+ is_staff: boolean
64
+ is_superuser: boolean
65
+ is_deleted: boolean
66
+ ordering: string
67
+ page: Number
68
+ page_size: Number
69
+ }
@@ -0,0 +1,12 @@
1
+ export class ErrorClient {
2
+
3
+ constructor() {
4
+ // No dependencies needed for now
5
+ }
6
+
7
+ // TODO: Implement error handling
8
+ // - handleError
9
+ // - logError
10
+ // - formatError
11
+ // - Custom error classes (AuthError, NetworkError, etc.)
12
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Error handling module exports
3
+ *
4
+ * This module provides comprehensive error handling for the Taruvi SDK
5
+ * including typed error classes, error codes, and utility functions.
6
+ */
7
+
8
+ // Export error client
9
+ export { ErrorClient } from './ErrorClient.js';
10
+
11
+ // TODO: Export all error classes when implemented
12
+ // - TaruviError
13
+ // - AuthError
14
+ // - DatabaseError
15
+ // - StorageError
16
+ // - NetworkError
17
+ // - ValidationError
18
+ // - FunctionError
19
+
20
+ // TODO: Export types when implemented
21
+ // - ErrorCode
22
+ // - ErrorSeverity
23
+ // - ErrorResponse
24
+ // - HttpErrorResponse
25
+ // - ValidationErrorDetail
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Error severity levels for categorizing errors
3
+ */
4
+ export enum ErrorSeverity {
5
+ LOW = 'low',
6
+ MEDIUM = 'medium',
7
+ HIGH = 'high',
8
+ CRITICAL = 'critical'
9
+ }
10
+
11
+ /**
12
+ * Standard error codes used across the SDK
13
+ */
14
+ export enum ErrorCode {
15
+ // General errors (1000-1099)
16
+ UNKNOWN_ERROR = 'UNKNOWN_ERROR',
17
+ INTERNAL_ERROR = 'INTERNAL_ERROR',
18
+ TIMEOUT_ERROR = 'TIMEOUT_ERROR',
19
+
20
+ // Network errors (1100-1199)
21
+ NETWORK_ERROR = 'NETWORK_ERROR',
22
+ CONNECTION_ERROR = 'CONNECTION_ERROR',
23
+ REQUEST_FAILED = 'REQUEST_FAILED',
24
+
25
+ // Authentication errors (1200-1299)
26
+ AUTH_ERROR = 'AUTH_ERROR',
27
+ UNAUTHORIZED = 'UNAUTHORIZED',
28
+ TOKEN_EXPIRED = 'TOKEN_EXPIRED',
29
+ TOKEN_INVALID = 'TOKEN_INVALID',
30
+ SESSION_EXPIRED = 'SESSION_EXPIRED',
31
+ INVALID_CREDENTIALS = 'INVALID_CREDENTIALS',
32
+
33
+ // Authorization errors (1300-1399)
34
+ FORBIDDEN = 'FORBIDDEN',
35
+ INSUFFICIENT_PERMISSIONS = 'INSUFFICIENT_PERMISSIONS',
36
+
37
+ // Validation errors (1400-1499)
38
+ VALIDATION_ERROR = 'VALIDATION_ERROR',
39
+ INVALID_INPUT = 'INVALID_INPUT',
40
+ MISSING_REQUIRED_FIELD = 'MISSING_REQUIRED_FIELD',
41
+ INVALID_FORMAT = 'INVALID_FORMAT',
42
+
43
+ // Database errors (1500-1599)
44
+ DATABASE_ERROR = 'DATABASE_ERROR',
45
+ QUERY_FAILED = 'QUERY_FAILED',
46
+ RECORD_NOT_FOUND = 'RECORD_NOT_FOUND',
47
+ DUPLICATE_ENTRY = 'DUPLICATE_ENTRY',
48
+ CONSTRAINT_VIOLATION = 'CONSTRAINT_VIOLATION',
49
+
50
+ // Storage errors (1600-1699)
51
+ STORAGE_ERROR = 'STORAGE_ERROR',
52
+ FILE_NOT_FOUND = 'FILE_NOT_FOUND',
53
+ FILE_TOO_LARGE = 'FILE_TOO_LARGE',
54
+ INVALID_FILE_TYPE = 'INVALID_FILE_TYPE',
55
+ UPLOAD_FAILED = 'UPLOAD_FAILED',
56
+ DOWNLOAD_FAILED = 'DOWNLOAD_FAILED',
57
+
58
+ // Function errors (1700-1799)
59
+ FUNCTION_ERROR = 'FUNCTION_ERROR',
60
+ FUNCTION_NOT_FOUND = 'FUNCTION_NOT_FOUND',
61
+ FUNCTION_EXECUTION_FAILED = 'FUNCTION_EXECUTION_FAILED',
62
+ FUNCTION_TIMEOUT = 'FUNCTION_TIMEOUT',
63
+
64
+ // Rate limiting errors (1800-1899)
65
+ RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED',
66
+ QUOTA_EXCEEDED = 'QUOTA_EXCEEDED',
67
+
68
+ // Client errors (1900-1999)
69
+ CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',
70
+ INVALID_API_KEY = 'INVALID_API_KEY',
71
+ INVALID_CONFIG = 'INVALID_CONFIG'
72
+ }
73
+
74
+ /**
75
+ * Base error response structure
76
+ */
77
+ export interface ErrorResponse {
78
+ code: ErrorCode;
79
+ message: string;
80
+ severity: ErrorSeverity;
81
+ timestamp: string;
82
+ requestId?: string | undefined;
83
+ metadata?: Record<string, any> | undefined;
84
+ cause?: Error | undefined;
85
+ }
86
+
87
+ /**
88
+ * HTTP error response from the server
89
+ */
90
+ export interface HttpErrorResponse {
91
+ status: number;
92
+ statusText: string;
93
+ message?: string;
94
+ code?: string;
95
+ details?: any;
96
+ }
97
+
98
+ /**
99
+ * Validation error details
100
+ */
101
+ export interface ValidationErrorDetail {
102
+ field: string;
103
+ message: string;
104
+ value?: any;
105
+ }
@@ -0,0 +1,96 @@
1
+ import type { TaruviConfig } from "../../types.js";
2
+ import type { TokenClient } from "../token/TokenClient.js";
3
+ import axios from "axios";
4
+
5
+ /**
6
+ * HttpClient handles all HTTP requests to the Taruvi API.
7
+ * Automatically adds authentication headers:
8
+ * - Authorization: API key for site/app identification
9
+ * - X-Session-Token: User session token for authenticated requests
10
+ *
11
+ * @internal
12
+ */
13
+ export class HttpClient {
14
+ private config: TaruviConfig
15
+ private tokenClient: TokenClient
16
+
17
+ constructor(config: TaruviConfig, tokenClient: TokenClient) {
18
+ this.config = config
19
+ this.tokenClient = tokenClient
20
+ }
21
+
22
+ private getAuthHeaders(isFormData: boolean = false): Record<string, string> {
23
+ const headers: Record<string, string> = {}
24
+
25
+ // Don't set Content-Type for FormData - let axios set it with the boundary
26
+ if (!isFormData) {
27
+ headers['Content-Type'] = 'application/json'
28
+ }
29
+
30
+ // Site/app API key (developer authentication)
31
+ if (this.config.apiKey) {
32
+ headers['Authorization'] = `Token ${this.config.apiKey}`
33
+ }
34
+
35
+ // Tenant admin session token
36
+ const jwt = this.tokenClient.getToken()
37
+ if (jwt) {
38
+ headers['Authorization'] = `Bearer ${jwt}`
39
+ }
40
+
41
+ return headers
42
+ }
43
+
44
+ async get<T>(endpoint: string) {
45
+ const { data } = await axios.get(`${this.config.baseUrl}/${endpoint}`, {
46
+ headers: this.getAuthHeaders()
47
+ })
48
+ return data
49
+ }
50
+
51
+ async post<T, D = any>(endpoint: string, body: D): Promise<T> {
52
+ const isFormData = body instanceof FormData
53
+ const { data } = await axios.post<T>(
54
+ `${this.config.baseUrl}/${endpoint}`,
55
+ body,
56
+ {
57
+ headers: this.getAuthHeaders(isFormData)
58
+ }
59
+ )
60
+ return data
61
+ }
62
+
63
+ async put<T, D = any>(endpoint: string, body: D) {
64
+ const isFormData = body instanceof FormData
65
+ const { data } = await axios.put<T>(`${this.config.baseUrl}/${endpoint}`,
66
+ body,
67
+ {
68
+ headers: this.getAuthHeaders(isFormData)
69
+ })
70
+
71
+ return data
72
+ }
73
+
74
+ async delete<T, D = any>(endpoint: string, body?: D): Promise<T> {
75
+ const { data } = await axios.delete<T>(
76
+ `${this.config.baseUrl}/${endpoint}`,
77
+ {
78
+ headers: this.getAuthHeaders(),
79
+ data: body
80
+ }
81
+ )
82
+ return data
83
+ }
84
+
85
+ async patch<T, D = any>(endpoint: string, body: D): Promise<T> {
86
+ const isFormData = body instanceof FormData
87
+ const { data } = await axios.patch<T>(
88
+ `${this.config.baseUrl}/${endpoint}`,
89
+ body,
90
+ {
91
+ headers: this.getAuthHeaders(isFormData)
92
+ }
93
+ )
94
+ return data
95
+ }
96
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * HTTP methods supported by the HttpClient
3
+ */
4
+ export enum HttpMethod {
5
+ GET = 'GET',
6
+ POST = 'POST',
7
+ PUT = 'PUT',
8
+ PATCH = 'PATCH',
9
+ DELETE = 'DELETE'
10
+ }
File without changes
@@ -0,0 +1,5 @@
1
+ export const DatabaseRoutes = {
2
+ baseUrl: (appSlug: string) => `api/apps/${appSlug}`,
3
+ dataTables: (tableName: string): string => `/datatables/${tableName}/data`,
4
+ recordId: (recordId: string): string => `/${recordId}`
5
+ }
@@ -0,0 +1,3 @@
1
+ export const FunctionRoutes = {
2
+ baseUrl: (appSlug: string, functionSlug: string) => `api/functions/apps/${appSlug}/functions/${functionSlug}`
3
+ }
File without changes
@@ -0,0 +1,5 @@
1
+ export const SecretsRoutes = {
2
+ baseUrl: "api/secrets/",
3
+ get: (key: string) => `api/secrets/${key}/`,
4
+ update: (key: string) => `api/secrets/${key}/`
5
+ }
@@ -0,0 +1,3 @@
1
+ export const SettingsRoutes = {
2
+ metadata: "api/settings/metadata/"
3
+ }
@@ -0,0 +1,7 @@
1
+ export const StorageRoutes = {
2
+ baseUrl: (appslug: string, bucket: string) => `api/apps/${appslug}/storage/buckets/${bucket}/objects`,
3
+ path: (path: string) => "/" + path,
4
+ upload: () => "/batch-upload",
5
+ delete: () => "/batch-delete"
6
+ // bucket: (appslug: string, bucketslug: string) => `${StorageRoutesClone.baseUrl(appslug)}/${bucketslug}`
7
+ }
@@ -0,0 +1,9 @@
1
+ import type { UserList } from "../../lib/user/types.js";
2
+
3
+ export const UserRoutes = {
4
+ baseUrl: "api/users/",
5
+ getCurrentUser: () => `${UserRoutes.baseUrl}me/`,
6
+ updateUser: (username: string) => `${UserRoutes.baseUrl}${username}/`,
7
+ deleteUser: (username: string) => `${UserRoutes.baseUrl}${username}/`,
8
+ listUser: (filter: string) => `${UserRoutes.baseUrl}${filter}`
9
+ } as const
File without changes
@@ -0,0 +1,30 @@
1
+ import { getRuntimeEnvironment } from "../../utils/utils.js"
2
+
3
+ export class TokenClient {
4
+ // private tenantAdminToken: string | null = null
5
+ private runTimeEnvironment: string
6
+ private browserRunTime: boolean
7
+ // private adminSessionToken: string | null
8
+
9
+ constructor(token?: string) {
10
+ this.runTimeEnvironment = getRuntimeEnvironment()
11
+ this.browserRunTime = this.runTimeEnvironment == "Browser"
12
+ // this.adminSessionToken = this.getToken()
13
+ }
14
+
15
+ getToken(): string | null {
16
+ if (this.browserRunTime) {
17
+ // return localStorage.getItem("")
18
+ return localStorage.getItem("jwt")
19
+ }
20
+ return null
21
+ // return this.tenantAdminToken
22
+ }
23
+
24
+ // TODO: Implement token management
25
+ // - setToken
26
+ // - getToken
27
+ // - refreshToken
28
+ // - clearToken
29
+ // - isTokenExpired
30
+ }
File without changes
package/src/types.ts ADDED
@@ -0,0 +1,68 @@
1
+ import { MimeTypeCategory, Visibility } from './utils/enums.js'
2
+
3
+ export interface TaruviConfig {
4
+ apiKey: string // Identifies which site the client belongs to
5
+ appSlug: string // Identifies which app the client belongs to
6
+ baseUrl: string
7
+ deskUrl?: string // URL for the desk/login page
8
+ token?: string // Optional: Pre-existing auth token
9
+ }
10
+
11
+ export interface StorageFilters {
12
+ // Pagination (DRF style)
13
+ page?: number
14
+ pageSize?: number
15
+
16
+ // Range Filters - Size (in bytes)
17
+ size__gte?: number
18
+ size__lte?: number
19
+ size__gt?: number
20
+ size__lt?: number
21
+ min_size?: number
22
+ max_size?: number
23
+
24
+ // Range Filters - Dates (ISO 8601)
25
+ created_at__gte?: string
26
+ created_at__lte?: string
27
+ created_after?: string
28
+ created_before?: string
29
+ updated_at__gte?: string
30
+ updated_at__lte?: string
31
+
32
+ // Search Filters
33
+ search?: string
34
+ filename__icontains?: string
35
+ prefix?: string
36
+ file?: string
37
+ file__icontains?: string
38
+ file__startswith?: string
39
+ file__istartswith?: string
40
+ metadata_search?: string
41
+
42
+ // MIME Type Filters
43
+ mimetype?: string
44
+ mimetype__in?: string
45
+ mimetype_category?: MimeTypeCategory
46
+
47
+ // Visibility & User Filters
48
+ visibility?: Visibility
49
+ created_by_me?: boolean
50
+ modified_by_me?: boolean
51
+ created_by__username?: string
52
+ created_by__username__icontains?: string
53
+
54
+ // Sorting
55
+ ordering?: string
56
+ }
57
+
58
+ export interface DatabaseFilters {
59
+ // Pagination (DRF style)
60
+ page?: number
61
+ pageSize?: number
62
+
63
+ // Sorting (DRF style: "-field" for desc, "field" for asc)
64
+ ordering?: string
65
+
66
+ // Dynamic filters - allows any field with operators
67
+ [key: string]: string | number | boolean | undefined
68
+ }
@@ -0,0 +1,12 @@
1
+ export enum MimeTypeCategory {
2
+ IMAGE = 'image',
3
+ VIDEO = 'video',
4
+ AUDIO = 'audio',
5
+ APPLICATION = 'application',
6
+ TEXT = 'text'
7
+ }
8
+
9
+ export enum Visibility {
10
+ PUBLIC = 'public',
11
+ PRIVATE = 'private'
12
+ }
@@ -0,0 +1,36 @@
1
+ const _window = typeof window !== 'undefined' ? window : undefined
2
+ const _global = typeof global !== 'undefined' ? global : undefined
3
+ const _process = typeof process !== 'undefined' ? process : undefined
4
+ const _navigator = typeof navigator !== 'undefined' ? navigator : undefined
5
+ const _document = typeof document !== 'undefined' ? document : undefined
6
+ const _self = typeof self !== 'undefined' ? self : undefined
7
+
8
+ export const isBrowser = (): boolean => {
9
+ return _window !== undefined && _document !== undefined
10
+ }
11
+
12
+ export const isReactNative = (): boolean => {
13
+ return _navigator !== undefined &&
14
+ // @ts-ignore - navigator.product is deprecated but still used in RN detection
15
+ _navigator.product === 'ReactNative'
16
+ }
17
+
18
+ export const getRuntimeEnvironment = (): string => {
19
+ if (isBrowser()) return 'Browser'
20
+ if (isReactNative()) return 'ReactNative'
21
+ return 'Server'
22
+ }
23
+
24
+ export function buildQueryString(filters: Record<string, unknown> | undefined): string {
25
+ if (!filters || Object.keys(filters).length === 0) {
26
+ return ''
27
+ }
28
+ const params = new URLSearchParams()
29
+ Object.entries(filters).forEach(([key, value]) => {
30
+ if (value !== undefined && value !== null) {
31
+ params.append(key, String(value))
32
+ }
33
+ })
34
+ const queryString = params.toString()
35
+ return queryString ? `?${queryString}` : ''
36
+ }
@@ -0,0 +1 @@
1
+ {}
package/tsconfig.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ // Visit https://aka.ms/tsconfig to read more about this file
3
+ "compilerOptions": {
4
+ // File Layout
5
+ "rootDir": "./src",
6
+ "outDir": "./dist",
7
+
8
+ // Environment Settings
9
+ // See also https://aka.ms/tsconfig/module
10
+ "module": "nodenext",
11
+ "target": "esnext",
12
+ "lib": ["esnext", "dom"],
13
+ "types": ["node"],
14
+
15
+ // Other Outputs
16
+ "sourceMap": true,
17
+ "declaration": true,
18
+ "declarationMap": true,
19
+
20
+ // Stricter Typechecking Options
21
+ "noUncheckedIndexedAccess": true,
22
+ "exactOptionalPropertyTypes": true,
23
+
24
+ // Style Options
25
+ // "noImplicitReturns": true,
26
+ // "noImplicitOverride": true,
27
+ // "noUnusedLocals": true,
28
+ // "noUnusedParameters": true,
29
+ // "noFallthroughCasesInSwitch": true,
30
+ // "noPropertyAccessFromIndexSignature": true,
31
+
32
+ // Recommended Options
33
+ "strict": true,
34
+ "jsx": "react-jsx",
35
+ "verbatimModuleSyntax": true,
36
+ "isolatedModules": true,
37
+ "noUncheckedSideEffectImports": true,
38
+ "moduleDetection": "force",
39
+ "skipLibCheck": true,
40
+ },
41
+ "include": ["src/**/*"],
42
+ "exclude": ["node_modules", "dist", "taruvi-platform", "tests"]
43
+ }