helpdesk-app-framework-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.
@@ -0,0 +1,156 @@
1
+ /**
2
+ * BoldDesk App Framework - Metadata API
3
+ * Provides app and installation metadata information
4
+ */
5
+
6
+ class MetadataAPI {
7
+ constructor (data = {}) {
8
+ this._data = {
9
+ appId: data.appId || null,
10
+ installationId: data.installationId || null,
11
+ appName: data.appName || null,
12
+ version: data.version || null,
13
+ locations: data.locations || [],
14
+ hasAllBrandAccess: data.hasAllBrandAccess || false,
15
+ hasReadAccess: data.hasReadAccess || false,
16
+ hasWriteAccess: data.hasWriteAccess || false,
17
+ isActive: data.isActive || false,
18
+ isEnabled: data.isEnabled || false,
19
+ frameworkVersion: data.frameworkVersion || null,
20
+ installDate: data.installDate || null,
21
+ developer: data.developer || null
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Get app ID
27
+ * @returns {string} App ID
28
+ */
29
+ getAppId () {
30
+ return this._data.appId
31
+ }
32
+
33
+ /**
34
+ * Get installation ID (unique per installation)
35
+ * @returns {string} Installation ID
36
+ */
37
+ getInstallationId () {
38
+ return this._data.installationId
39
+ }
40
+
41
+ /**
42
+ * Get app name
43
+ * @returns {string} App name
44
+ */
45
+ getAppName () {
46
+ return this._data.appName
47
+ }
48
+
49
+ /**
50
+ * Get app version
51
+ * @returns {string} Version (semantic versioning)
52
+ */
53
+ getVersion () {
54
+ return this._data.version
55
+ }
56
+
57
+ /**
58
+ * Get widget locations where app is available
59
+ * @returns {Array} Array of location strings
60
+ */
61
+ getLocations () {
62
+ return Array.from(this._data.locations)
63
+ }
64
+
65
+ /**
66
+ * Check if app has all brand access
67
+ * @returns {boolean}
68
+ */
69
+ hasAllBrandAccess () {
70
+ return this._data.hasAllBrandAccess === true
71
+ }
72
+
73
+ /**
74
+ * Check if app has read permissions
75
+ * @returns {boolean}
76
+ */
77
+ hasReadAccess () {
78
+ return this._data.hasReadAccess === true
79
+ }
80
+
81
+ /**
82
+ * Check if app has write permissions
83
+ * @returns {boolean}
84
+ */
85
+ hasWriteAccess () {
86
+ return this._data.hasWriteAccess === true
87
+ }
88
+
89
+ /**
90
+ * Check if app is active
91
+ * @returns {boolean}
92
+ */
93
+ isActive () {
94
+ return this._data.isActive === true
95
+ }
96
+
97
+ /**
98
+ * Check if app is enabled
99
+ * @returns {boolean}
100
+ */
101
+ isEnabled () {
102
+ return this._data.isEnabled === true
103
+ }
104
+
105
+ /**
106
+ * Get framework version
107
+ * @returns {string} Framework version
108
+ */
109
+ getFrameworkVersion () {
110
+ return this._data.frameworkVersion
111
+ }
112
+
113
+ /**
114
+ * Get installation date
115
+ * @returns {string} ISO date string
116
+ */
117
+ getInstallDate () {
118
+ return this._data.installDate
119
+ }
120
+
121
+ /**
122
+ * Get developer information
123
+ * @returns {Object} Developer object
124
+ */
125
+ getDeveloper () {
126
+ return this._data.developer ? JSON.parse(JSON.stringify(this._data.developer)) : null
127
+ }
128
+
129
+ /**
130
+ * Check if location is supported
131
+ * @param {string} location - Location to check
132
+ * @returns {boolean}
133
+ */
134
+ isLocationSupported (location) {
135
+ return this._data.locations.includes(location)
136
+ }
137
+
138
+ /**
139
+ * Get all metadata
140
+ * @returns {Object} Full metadata object
141
+ */
142
+ getAll () {
143
+ return JSON.parse(JSON.stringify(this._data))
144
+ }
145
+
146
+ /**
147
+ * Update metadata (internal use)
148
+ * @param {Object} data - New data to merge
149
+ * @internal
150
+ */
151
+ _updateData (data) {
152
+ Object.assign(this._data, data)
153
+ }
154
+ }
155
+
156
+ export default MetadataAPI
@@ -0,0 +1,196 @@
1
+ /**
2
+ * BoldDesk App Framework - Request API (Proxy)
3
+ * Provides secure HTTP request capability through server-side proxy
4
+ */
5
+
6
+ import { isObject, isString, isValidUrl } from '../utils'
7
+
8
+ class RequestAPI {
9
+ constructor (client) {
10
+ this._client = client
11
+ }
12
+
13
+ /**
14
+ * Make an HTTP request through BoldDesk proxy
15
+ * Prevents exposing sensitive data and handles CORS automatically
16
+ *
17
+ * @param {Object} options - Request options
18
+ * @param {string} options.url - Full URL of the API endpoint (required)
19
+ * @param {string} options.method - HTTP method (GET, POST, PUT, DELETE, PATCH) (required)
20
+ * @param {Object} options.headers - HTTP headers (optional)
21
+ * @param {Object} options.params - Query parameters (optional)
22
+ * @param {Object|string} options.body - Request payload (optional, for POST/PUT/PATCH)
23
+ * @param {number} options.timeout - Request timeout in ms (optional, default: 15000, max: 30000)
24
+ * @param {boolean} options.autoRetry - Auto-retry on 429/5xx (optional, default: true)
25
+ * @param {number} options.maxRetry - Max retry attempts (optional, default: 3)
26
+ * @param {number} options.retryDelay - Delay between retries in ms (optional, default: 1000)
27
+ *
28
+ * @returns {Promise} Resolves with response object { status, statusText, headers, data, body }
29
+ *
30
+ * @example
31
+ * // Simple GET request
32
+ * sdk.request({
33
+ * url: 'https://api.example.com/users',
34
+ * method: 'GET'
35
+ * }).then(response => console.log(response.data))
36
+ *
37
+ * @example
38
+ * // POST with data
39
+ * sdk.request({
40
+ * url: 'https://api.example.com/tickets',
41
+ * method: 'POST',
42
+ * headers: { 'Content-Type': 'application/json' },
43
+ * body: JSON.stringify({ subject: 'Help needed', priority: 'high' })
44
+ * })
45
+ *
46
+ * @example
47
+ * // Using secure settings placeholders
48
+ * sdk.request({
49
+ * url: 'https://api.example.com/secure-endpoint',
50
+ * method: 'GET',
51
+ * headers: { 'Authorization': 'Bearer {{setting.api_key}}' }
52
+ * })
53
+ */
54
+ request (options = {}) {
55
+ return new Promise((resolve, reject) => {
56
+ try {
57
+ // Validate required options
58
+ if (!options.url) {
59
+ throw new Error('Request URL is required')
60
+ }
61
+
62
+ if (!options.method) {
63
+ throw new Error('Request method is required')
64
+ }
65
+
66
+ // Validate URL format
67
+ if (!isValidUrl(options.url)) {
68
+ throw new Error('Invalid URL format: ' + options.url)
69
+ }
70
+
71
+ // Validate method
72
+ const validMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']
73
+ const method = (options.method || 'GET').toUpperCase()
74
+ if (!validMethods.includes(method)) {
75
+ throw new Error('Invalid HTTP method: ' + method)
76
+ }
77
+
78
+ // Build request object
79
+ const requestObj = {
80
+ url: options.url,
81
+ method,
82
+ headers: options.headers || {},
83
+ timeout: Math.min(options.timeout || 15000, 30000),
84
+ autoRetry: options.autoRetry !== false,
85
+ maxRetry: options.maxRetry || 3,
86
+ retryDelay: options.retryDelay || 1000
87
+ }
88
+
89
+ // Add query parameters if provided
90
+ if (options.params && isObject(options.params)) {
91
+ const params = new URLSearchParams(options.params)
92
+ const separator = options.url.includes('?') ? '&' : '?'
93
+ requestObj.url += separator + params.toString()
94
+ }
95
+
96
+ // Add body for POST/PUT/PATCH
97
+ if (['POST', 'PUT', 'PATCH'].includes(method)) {
98
+ if (options.body) {
99
+ requestObj.body = isObject(options.body)
100
+ ? JSON.stringify(options.body)
101
+ : options.body
102
+ }
103
+ }
104
+
105
+ // Send request through BoldDesk proxy
106
+ this._client.postMessage('request.send', requestObj, (response) => {
107
+ if (response.error) {
108
+ reject(new Error(response.error))
109
+ } else {
110
+ resolve(response)
111
+ }
112
+ })
113
+ } catch (error) {
114
+ reject(error)
115
+ }
116
+ })
117
+ }
118
+
119
+ /**
120
+ * Make a GET request
121
+ * @param {string} url - URL endpoint
122
+ * @param {Object} options - Additional options
123
+ * @returns {Promise}
124
+ */
125
+ get (url, options = {}) {
126
+ return this.request({
127
+ ...options,
128
+ url,
129
+ method: 'GET'
130
+ })
131
+ }
132
+
133
+ /**
134
+ * Make a POST request
135
+ * @param {string} url - URL endpoint
136
+ * @param {*} body - Request body
137
+ * @param {Object} options - Additional options
138
+ * @returns {Promise}
139
+ */
140
+ post (url, body, options = {}) {
141
+ return this.request({
142
+ ...options,
143
+ url,
144
+ method: 'POST',
145
+ body
146
+ })
147
+ }
148
+
149
+ /**
150
+ * Make a PUT request
151
+ * @param {string} url - URL endpoint
152
+ * @param {*} body - Request body
153
+ * @param {Object} options - Additional options
154
+ * @returns {Promise}
155
+ */
156
+ put (url, body, options = {}) {
157
+ return this.request({
158
+ ...options,
159
+ url,
160
+ method: 'PUT',
161
+ body
162
+ })
163
+ }
164
+
165
+ /**
166
+ * Make a PATCH request
167
+ * @param {string} url - URL endpoint
168
+ * @param {*} body - Request body
169
+ * @param {Object} options - Additional options
170
+ * @returns {Promise}
171
+ */
172
+ patch (url, body, options = {}) {
173
+ return this.request({
174
+ ...options,
175
+ url,
176
+ method: 'PATCH',
177
+ body
178
+ })
179
+ }
180
+
181
+ /**
182
+ * Make a DELETE request
183
+ * @param {string} url - URL endpoint
184
+ * @param {Object} options - Additional options
185
+ * @returns {Promise}
186
+ */
187
+ delete (url, options = {}) {
188
+ return this.request({
189
+ ...options,
190
+ url,
191
+ method: 'DELETE'
192
+ })
193
+ }
194
+ }
195
+
196
+ export default RequestAPI