@tradly/asset 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,270 +0,0 @@
1
- import axios from 'axios'
2
-
3
- /**
4
- * Get the API base URL based on environment
5
- * @returns {string} API base URL
6
- */
7
- const getApiBaseUrl = (environment) => {
8
- // Check if environment includes 'dev' (case insensitive)
9
- const isDev = environment && String(environment).toLowerCase().includes('dev')
10
- return isDev ? 'https://api.dev.tradly.app' : 'https://api.tradly.app'
11
- }
12
-
13
- /**
14
- * API Service for Media Gallery
15
- * Handles all API calls with Tradly authentication
16
- * Includes full upload logic using direct API call to S3 signed URL endpoint
17
- */
18
- class MediaApiService {
19
- constructor(config = {}) {
20
- this.authKey = config.authKey || ''
21
- // Auto-detect API base URL from environment, or use provided one
22
- const environment =
23
- config.environment || (typeof process !== 'undefined' && process.env?.ENVIRONMENT) || ''
24
- this.apiBaseUrl = config.apiBaseUrl || getApiBaseUrl(environment)
25
- this.bearerToken = config.bearerToken || '' // Bearer token for Authorization header
26
- this.onError = config.onError || null
27
- }
28
-
29
- /**
30
- * Set authentication key
31
- */
32
- setAuthKey(authKey) {
33
- this.authKey = authKey
34
- }
35
-
36
- /**
37
- * Set API base URL (used for all API calls)
38
- */
39
- setApiBaseUrl(apiBaseUrl) {
40
- this.apiBaseUrl = apiBaseUrl
41
- }
42
-
43
- /**
44
- * Set Bearer token for Authorization header
45
- */
46
- setBearerToken(bearerToken) {
47
- this.bearerToken = bearerToken
48
- }
49
-
50
- /**
51
- * Make API call with authentication to Tradly API
52
- */
53
- async apiCall({ method, path, data, params, setISLoading, isLoading }) {
54
- if (setISLoading) setISLoading(true)
55
-
56
- try {
57
- const headers = {
58
- 'Content-Type': 'application/json',
59
- }
60
-
61
- // Add auth key to headers if provided (X-Auth-Key header)
62
- if (this.authKey) {
63
- headers['X-Auth-Key'] = this.authKey
64
- }
65
-
66
- // Add Bearer token if provided
67
- if (this.bearerToken) {
68
- headers['Authorization'] = `Bearer ${this.bearerToken}`
69
- }
70
-
71
- const response = await axios({
72
- method,
73
- url: `${this.apiBaseUrl}${path}`,
74
- headers,
75
- data,
76
- params,
77
- })
78
-
79
- if (setISLoading) setISLoading(false)
80
- return response.data
81
- } catch (error) {
82
- if (setISLoading) setISLoading(false)
83
-
84
- if (this.onError) {
85
- this.onError(error)
86
- }
87
-
88
- throw error
89
- }
90
- }
91
-
92
- /**
93
- * Fetch media items from Tradly API
94
- * GET /v1/media?page=1&parent=0&mime_type=...
95
- */
96
- async fetchMedia({ mimeTypes, page = 1, parent = 0, setISLoading, isLoading }) {
97
- const params = {
98
- page,
99
- parent,
100
- }
101
-
102
- // Add mime_type to params if provided
103
- if (mimeTypes) {
104
- const mimeTypeParam = Array.isArray(mimeTypes) ? mimeTypes.join(',') : mimeTypes
105
- params.mime_type = mimeTypeParam
106
- }
107
-
108
- return this.apiCall({
109
- method: 'GET',
110
- path: '/v1/media',
111
- params,
112
- setISLoading,
113
- isLoading,
114
- })
115
- }
116
-
117
- /**
118
- * Get S3 signed upload URLs from API
119
- */
120
- async getS3SignedUrls(files, authKey) {
121
- const auth_key = authKey || this.authKey
122
-
123
- if (!auth_key) {
124
- throw new Error('Authentication key is required for upload')
125
- }
126
-
127
- if (!this.apiBaseUrl) {
128
- throw new Error(
129
- 'API base URL is required. The package automatically detects it from ENVIRONMENT, or you can set apiBaseUrl in config: new MediaApiService({ apiBaseUrl: "https://api.tradly.app" })'
130
- )
131
- }
132
-
133
- // Prepare file data
134
- const fileData = files.map((file) => ({
135
- name: file.name.replace(/\s/g, '-'),
136
- type: file.type,
137
- }))
138
-
139
- // Prepare headers
140
- const headers = {
141
- 'Content-Type': 'application/json',
142
- 'X-Auth-Key': auth_key, // Capital X for Tradly API
143
- }
144
-
145
- // Add Bearer token if provided
146
- if (this.bearerToken) {
147
- headers['Authorization'] = `Bearer ${this.bearerToken}`
148
- }
149
-
150
- try {
151
- const response = await axios({
152
- method: 'POST',
153
- url: `${this.apiBaseUrl}/v1/utils/S3signedUploadURL`,
154
- headers,
155
- data: { files: fileData },
156
- })
157
-
158
- if (response.data.error) {
159
- throw new Error(response.data.error)
160
- }
161
-
162
- return response.data.result || response.data.data?.result || response.data
163
- } catch (error) {
164
- console.error('Error getting S3 signed URLs:', error)
165
- if (this.onError) {
166
- this.onError(error)
167
- }
168
- throw error
169
- }
170
- }
171
-
172
- /**
173
- * Upload media files using direct API call
174
- * This includes the full upload logic: get S3 signed URLs -> upload to S3 -> save to media API
175
- */
176
- async uploadMedia(files, authKey) {
177
- const auth_key = authKey || this.authKey
178
-
179
- if (!auth_key) {
180
- throw new Error('Authentication key is required for upload')
181
- }
182
-
183
- let all_files_uri = []
184
- let upload_files = []
185
- let upload_full_files = []
186
-
187
- // Process all files
188
- for (let i = 0; i < files.length; i++) {
189
- const element = files[i]
190
-
191
- // Check if file already has a path (from previous upload)
192
- if (element.full_file === null && element.path) {
193
- all_files_uri.push(element.path)
194
- } else {
195
- // Prepare file data for upload
196
- let file_data = {
197
- name: element.name.replace(/\s/g, '-'),
198
- type: element.type,
199
- }
200
-
201
- upload_files.push(file_data)
202
- upload_full_files.push(element)
203
- }
204
-
205
- // Upload files when we've processed all files
206
- if (files.length === i + 1 && upload_files.length > 0) {
207
- try {
208
- // Step 1: Get signed URLs from API
209
- const responseFiles = await this.getS3SignedUrls(upload_full_files, auth_key)
210
-
211
- // Step 2: Upload each file to S3
212
- for (let index = 0; index < responseFiles.length; index++) {
213
- const path = responseFiles[index].signedUrl
214
- const fileURI = responseFiles[index].fileUri
215
-
216
- try {
217
- const res = await fetch(path, {
218
- method: 'PUT',
219
- headers: {
220
- ContentType: upload_files[index].type,
221
- },
222
- body: upload_full_files[index],
223
- })
224
-
225
- if (res.ok) {
226
- all_files_uri.push(fileURI)
227
- } else {
228
- console.error(`Failed to upload file ${index + 1}`)
229
- }
230
- } catch (error) {
231
- console.error(`Error uploading file ${index + 1}:`, error)
232
- }
233
- }
234
-
235
- // Step 3: Save media metadata to Tradly API
236
- if (all_files_uri.length > 0) {
237
- const mediaData = all_files_uri.map((url, index) => {
238
- const originalFile = upload_full_files[index]
239
- return {
240
- type: 1,
241
- parent: 0,
242
- url: url,
243
- name: originalFile.name.replace(/\s/g, '-'),
244
- mime_type: originalFile.type,
245
- }
246
- })
247
-
248
- // Save to media API - POST /v1/media with { media: [...] }
249
- await this.apiCall({
250
- method: 'POST',
251
- path: '/v1/media',
252
- data: { media: mediaData },
253
- })
254
- }
255
- } catch (error) {
256
- console.error('Upload error:', error)
257
- if (this.onError) {
258
- this.onError(error)
259
- }
260
- throw error
261
- }
262
- }
263
- }
264
-
265
- // Return all uploaded file URIs
266
- return all_files_uri
267
- }
268
- }
269
-
270
- export default MediaApiService