@magentrix-corp/magentrix-sdk 1.0.0 → 1.0.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 CHANGED
@@ -1,50 +1,721 @@
1
- Magentrix SDK for Javascript.
1
+ # Magentrix SDK for JavaScript
2
2
 
3
- Javascript:
3
+ A TypeScript-based SDK for seamless integration with Magentrix APIs. This SDK provides a convenient interface for authentication, CRUD operations, and custom queries with built-in session management and error handling.
4
4
 
5
+ ## Features
6
+
7
+ - ✅ **Dual Authentication Modes**: Token-based (dev) and cookie-based (production) authentication
8
+ - ✅ **Automatic Session Management**: Token refresh with configurable expiration handling
9
+ - ✅ **CRUD Operations**: Create, read, update, delete operations for entities
10
+ - ✅ **Custom Queries**: Execute custom queries and retrieve data by ID
11
+ - ✅ **Vue 3 Integration**: Dedicated composable for Vue.js applications
12
+ - ✅ **TypeScript Support**: Full type definitions included
13
+ - ✅ **Error Handling**: Custom error classes with optional global error callbacks
14
+ - ✅ **ESM & CommonJS**: Supports both module formats
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @magentrix-corp/magentrix-sdk
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ### JavaScript/TypeScript
25
+
26
+ ```typescript
5
27
  import { MagentrixClient } from 'magentrix-sdk'
6
28
 
7
29
  const client = new MagentrixClient({
8
- baseUrl: 'https://xyz.com',
9
- token: '',
10
- refreshToken: 'xyz',
11
- antiForgeryToken: '',
12
- onSessionExpired: () => Promise<void> | void
13
- onError?: (error: any) => void
30
+ baseUrl: 'https://your-instance.magentrix.com',
31
+ refreshToken: 'your-refresh-token',
32
+ isDevMode: true, // Use token-based auth
33
+ onSessionExpired: async () => {
34
+ console.log('Session expired!')
35
+ },
36
+ onError: (error) => {
37
+ console.error('API Error:', error)
38
+ }
14
39
  })
15
40
 
16
- client.createSession().then(si => {
17
- console.log(si.token)
18
- client.retrieve('xyz').then(r => console.log(r))
19
- })
41
+ // Create a session
42
+ const session = await client.createSession()
43
+ console.log('Token:', session.token)
20
44
 
45
+ // Query data
46
+ const results = await client.query('SELECT Id, Name FROM Account')
47
+ console.log(results)
21
48
 
22
- VUE JS:
49
+ // Retrieve by ID
50
+ const record = await client.retrieve('account-id-123')
51
+ console.log(record)
52
+ ```
23
53
 
54
+ ### Vue 3
55
+
56
+ ```vue
24
57
  <script setup>
25
- import { onMounted } from 'vue'
26
- import { MagentrixClient } from 'magentrix-sdk/vue'
58
+ import { ref, onMounted } from 'vue'
59
+ import { useMagentrixSdk } from 'magentrix-sdk/vue'
27
60
 
28
61
  const client = useMagentrixSdk({
29
- baseUrl: 'https://xyz.com',
30
- token: '',
31
- refreshToken: 'xyz',
32
- antiForgeryToken: '',
33
- onSessionExpired: () => Promise<void> | void
34
- onError?: (error: any) => void
62
+ baseUrl: 'https://your-instance.magentrix.com',
63
+ refreshToken: 'your-refresh-token',
64
+ isDevMode: true,
65
+ onError: (error) => {
66
+ console.error('API Error:', error)
67
+ }
35
68
  })
36
69
 
37
- const model = ref()
70
+ const account = ref(null)
38
71
 
39
72
  onMounted(async () => {
40
- const si = await client.createSession()
41
- console.log(si.token)
42
- const r = await client.retrieve('xyz')
43
- console.log(r)
44
- model.value = r
73
+ await client.createSession()
74
+ account.value = await client.retrieve('account-id-123')
45
75
  })
46
76
  </script>
47
77
 
48
78
  <template>
49
- <p>{{ model.Id }}</p>
50
- </template>
79
+ <div v-if="account">
80
+ <h1>{{ account.Name }}</h1>
81
+ <p>ID: {{ account.Id }}</p>
82
+ </div>
83
+ </template>
84
+ ```
85
+
86
+ ## Configuration
87
+
88
+ ### MagentrixConfig
89
+
90
+ | Property | Type | Required | Description |
91
+ |----------|------|----------|-------------|
92
+ | `baseUrl` | `string` | Yes | Base URL of your Magentrix instance (e.g., 'https://your-instance.magentrix.com') |
93
+ | `refreshToken` | `string` | No | Refresh token for authentication. Required when `isDevMode: true` |
94
+ | `isDevMode` | `boolean` | No | Enable token-based authentication (default: `false`). See [Authentication Modes](#authentication-modes) |
95
+ | `onSessionExpired` | `() => Promise<void> \| void` | No | Callback invoked when session expires |
96
+ | `onError` | `(error: any) => void` | No | Global error handler for all API errors |
97
+
98
+ ## Authentication Modes
99
+
100
+ The SDK supports two authentication modes controlled by the `isDevMode` flag:
101
+
102
+ ### Development Mode (`isDevMode: true`)
103
+
104
+ **Use Case**: External applications, mobile apps, or development environments
105
+
106
+ **Behavior**:
107
+ - Uses **token-based authentication** with Bearer tokens
108
+ - Automatically refreshes tokens before they expire (30-second buffer)
109
+ - Validates session on every API call
110
+ - Requires `refreshToken` in configuration
111
+
112
+ ```typescript
113
+ const client = new MagentrixClient({
114
+ baseUrl: 'https://your-instance.magentrix.com',
115
+ refreshToken: 'your-refresh-token',
116
+ isDevMode: true
117
+ })
118
+ ```
119
+
120
+ ### Production Mode (`isDevMode: false` or not set)
121
+
122
+ **Use Case**: Web applications using ASP.NET Forms Authentication
123
+
124
+ **Behavior**:
125
+ - Uses **cookie-based authentication** (ASP.NET session cookies)
126
+ - No bearer tokens sent in requests
127
+ - No automatic session validation
128
+ - Automatically redirects to login page when session expires
129
+ - No `refreshToken` required
130
+
131
+ ```typescript
132
+ const client = new MagentrixClient({
133
+ baseUrl: 'https://your-instance.magentrix.com',
134
+ isDevMode: false // or omit this property
135
+ })
136
+ ```
137
+
138
+ ## API Reference
139
+
140
+ ### Session Management
141
+
142
+ #### `createSession(refreshToken?: string): Promise<SessionInfo>`
143
+
144
+ Creates a new session using the refresh token.
145
+
146
+ ```typescript
147
+ const session = await client.createSession()
148
+ console.log(session.token) // Bearer token
149
+ console.log(session.expires_in) // Seconds until expiration
150
+ ```
151
+
152
+ **Parameters**:
153
+ - `refreshToken` (optional): Override the refresh token from config
154
+
155
+ **Returns**: `SessionInfo` object with `token` and `expires_in`
156
+
157
+ **Throws**: `MagentrixError` if token is invalid or expired
158
+
159
+
160
+ ### Query Operations
161
+
162
+ #### `query(query: string): Promise<any>`
163
+
164
+ Execute a custom query using Magentrix query language.
165
+
166
+ ```typescript
167
+ const results = await client.query('SELECT Id, Name, Email FROM Contact WHERE Status = "Active"')
168
+ console.log(results)
169
+ ```
170
+
171
+ **Parameters**:
172
+ - `query`: Query string in Magentrix query language
173
+
174
+ **Returns**: Query results
175
+
176
+ **Throws**: `MagentrixError` if query is empty or invalid
177
+
178
+ ---
179
+
180
+ #### `retrieve(id: string): Promise<any>`
181
+
182
+ Retrieve a single record by ID.
183
+
184
+ ```typescript
185
+ const account = await client.retrieve('account-id-123')
186
+ console.log(account.Name)
187
+ ```
188
+
189
+ **Parameters**:
190
+ - `id`: Record ID to retrieve
191
+
192
+ **Returns**: Record object
193
+
194
+ **Throws**: `MagentrixError` if ID is not provided
195
+
196
+ ---
197
+
198
+ ### CRUD Operations
199
+
200
+ #### `create(entityName: string, data: any): Promise<any>`
201
+
202
+ Create a new record.
203
+
204
+ ```typescript
205
+ const newAccount = await client.create('Account', {
206
+ Name: 'Acme Corporation',
207
+ Email: 'contact@acme.com',
208
+ Status: 'Active'
209
+ })
210
+ console.log('Created ID:', newAccount.Id)
211
+ ```
212
+
213
+ **Parameters**:
214
+ - `entityName`: Name of the entity (e.g., 'Account', 'Contact')
215
+ - `data`: Object containing the record data
216
+
217
+ **Returns**: Created record with ID
218
+
219
+ **Throws**: `MagentrixError` if entityName or data is missing
220
+
221
+ ---
222
+
223
+ #### `edit(entityName: string, data: any): Promise<any>`
224
+
225
+ Update an existing record (requires `Id` in data).
226
+
227
+ ```typescript
228
+ const updated = await client.edit('Account', {
229
+ Id: 'account-id-123',
230
+ Name: 'Updated Name',
231
+ Status: 'Inactive'
232
+ })
233
+ ```
234
+
235
+ **Parameters**:
236
+ - `entityName`: Name of the entity
237
+ - `data`: Object containing the record data with `Id`
238
+
239
+ **Returns**: Updated record
240
+
241
+ **Throws**: `MagentrixError` if entityName or data is missing
242
+
243
+ ---
244
+
245
+ #### `upsert(entityName: string, data: any): Promise<any>`
246
+
247
+ Create or update a record. If `Id` is provided and exists, updates the record; otherwise creates a new one.
248
+
249
+ ```typescript
250
+ const record = await client.upsert('Contact', {
251
+ Id: 'contact-id-456', // Optional
252
+ Name: 'John Doe',
253
+ Email: 'john@example.com'
254
+ })
255
+ ```
256
+
257
+ **Parameters**:
258
+ - `entityName`: Name of the entity
259
+ - `data`: Object containing the record data
260
+
261
+ **Returns**: Created or updated record
262
+
263
+ **Throws**: `MagentrixError` if entityName or data is missing
264
+
265
+ ---
266
+
267
+ #### `delete(entityName: string, id: string, permanent?: boolean): Promise<any>`
268
+
269
+ Delete a record by ID.
270
+
271
+ ```typescript
272
+ // Soft delete (default)
273
+ await client.delete('Account', 'account-id-123')
274
+
275
+ // Permanent delete
276
+ await client.delete('Account', 'account-id-123', true)
277
+ ```
278
+
279
+ **Parameters**:
280
+ - `entityName`: Name of the entity
281
+ - `id`: Record ID to delete
282
+ - `permanent` (optional): If `true`, permanently deletes the record (default: `false`)
283
+
284
+ **Returns**: Deletion result
285
+
286
+ **Throws**: `MagentrixError` if entityName or id is missing
287
+
288
+ ---
289
+
290
+ #### `deleteMany(entityName: string, ids: string[], permanent?: boolean): Promise<any>`
291
+
292
+ Delete multiple records by IDs.
293
+
294
+ ```typescript
295
+ await client.deleteMany('Contact', ['id-1', 'id-2', 'id-3'])
296
+ ```
297
+
298
+ **Parameters**:
299
+ - `entityName`: Name of the entity
300
+ - `ids`: Array of record IDs to delete
301
+ - `permanent` (optional): If `true`, permanently deletes the records (default: `false`)
302
+
303
+ **Returns**: Deletion result
304
+
305
+ **Throws**: `MagentrixError` if entityName or ids is missing/empty
306
+
307
+ ---
308
+
309
+ ### Custom Endpoints
310
+
311
+ #### `execute(path: string, model?: any, method?: RequestMethod): Promise<any>`
312
+
313
+ Execute a custom API endpoint.
314
+
315
+ ```typescript
316
+ import { RequestMethod } from 'magentrix-sdk'
317
+
318
+ // GET request
319
+ const data = await client.execute('/custom/endpoint', null, RequestMethod.get)
320
+
321
+ // POST request
322
+ const result = await client.execute('/custom/action', {
323
+ param1: 'value1',
324
+ param2: 'value2'
325
+ }, RequestMethod.post)
326
+ ```
327
+
328
+ **Parameters**:
329
+ - `path`: API endpoint path
330
+ - `model` (optional): Request body data
331
+ - `method` (optional): HTTP method (default: `RequestMethod.post`)
332
+
333
+ **Returns**: API response
334
+
335
+ **Throws**: `MagentrixError` if path is missing or GET request has a body
336
+
337
+ ---
338
+
339
+ ## Error Handling
340
+
341
+ The SDK provides two custom error classes:
342
+
343
+ ### MagentrixError
344
+
345
+ General SDK errors (authentication, validation, API errors).
346
+
347
+ ```typescript
348
+ import { MagentrixError } from 'magentrix-sdk'
349
+
350
+ try {
351
+ await client.createSession()
352
+ } catch (error) {
353
+ if (error instanceof MagentrixError) {
354
+ console.error('Magentrix Error:', error.message)
355
+ }
356
+ }
357
+ ```
358
+
359
+ ### DatabaseError
360
+
361
+ Database-specific errors with detailed error information.
362
+
363
+ ```typescript
364
+ import { DatabaseError } from 'magentrix-sdk'
365
+
366
+ try {
367
+ await client.create('Account', invalidData)
368
+ } catch (error) {
369
+ if (error instanceof DatabaseError) {
370
+ console.error('Database Error:', error.message)
371
+ if (error.hasErrors()) {
372
+ error.getErrors().forEach(err => {
373
+ console.error(`Field: ${err.fieldName}, Message: ${err.message}`)
374
+ })
375
+ }
376
+ }
377
+ }
378
+ ```
379
+
380
+ ### Global Error Handler
381
+
382
+ Set a global error handler in the configuration:
383
+
384
+ ```typescript
385
+ const client = new MagentrixClient({
386
+ baseUrl: 'https://your-instance.magentrix.com',
387
+ onError: (error) => {
388
+ // Log to monitoring service
389
+ console.error('Global error handler:', error)
390
+
391
+ // Show user notification
392
+ showNotification('An error occurred', 'error')
393
+ }
394
+ })
395
+ ```
396
+
397
+
398
+ ---
399
+
400
+ ## Advanced Usage
401
+
402
+ ### Session Expiration Handling
403
+
404
+ Handle session expiration gracefully:
405
+
406
+ ```typescript
407
+ const client = new MagentrixClient({
408
+ baseUrl: 'https://your-instance.magentrix.com',
409
+ refreshToken: 'your-refresh-token',
410
+ isDevMode: true,
411
+ onSessionExpired: async () => {
412
+ console.log('Session expired, refreshing...')
413
+ // The SDK will automatically refresh the session
414
+ // You can add custom logic here (e.g., show notification)
415
+ }
416
+ })
417
+ ```
418
+
419
+ ### TypeScript Types
420
+
421
+ Import types for better type safety:
422
+
423
+ ```typescript
424
+ import {
425
+ MagentrixClient,
426
+ MagentrixConfig,
427
+ SessionInfo,
428
+ MagentrixError,
429
+ DatabaseError,
430
+ RequestMethod,
431
+ ContentType
432
+ } from 'magentrix-sdk'
433
+
434
+ const config: MagentrixConfig = {
435
+ baseUrl: 'https://your-instance.magentrix.com',
436
+ refreshToken: 'your-refresh-token',
437
+ isDevMode: true
438
+ }
439
+
440
+ const client = new MagentrixClient(config)
441
+ ```
442
+
443
+ ### Batch Operations
444
+
445
+ Perform multiple operations efficiently:
446
+
447
+ ```typescript
448
+ // Create multiple records
449
+ const accounts = [
450
+ { Name: 'Account 1', Status: 'Active' },
451
+ { Name: 'Account 2', Status: 'Active' },
452
+ { Name: 'Account 3', Status: 'Active' }
453
+ ]
454
+
455
+ const created = await Promise.all(
456
+ accounts.map(account => client.create('Account', account))
457
+ )
458
+
459
+ console.log('Created IDs:', created.map(a => a.Id))
460
+
461
+ // Delete multiple records
462
+ const idsToDelete = ['id-1', 'id-2', 'id-3']
463
+ await client.deleteMany('Account', idsToDelete)
464
+ ```
465
+
466
+ ### Custom Query Examples
467
+
468
+ ```typescript
469
+ // Simple query
470
+ const activeContacts = await client.query(
471
+ 'SELECT Id, Name, Email FROM Contact WHERE Status = "Active"'
472
+ )
473
+
474
+ // Query with sorting
475
+ const sortedAccounts = await client.query(
476
+ 'SELECT Id, Name FROM Account ORDER BY Name ASC'
477
+ )
478
+
479
+ // Query with limit
480
+ const recentRecords = await client.query(
481
+ 'SELECT Id, Name FROM Account LIMIT 10'
482
+ )
483
+ ```
484
+
485
+ ---
486
+
487
+ ## Vue 3 Integration
488
+
489
+ ### Composable Usage
490
+
491
+ The SDK provides a dedicated Vue 3 composable:
492
+
493
+ ```vue
494
+ <script setup>
495
+ import { ref, onMounted } from 'vue'
496
+ import { useMagentrixSdk } from 'magentrix-sdk/vue'
497
+
498
+ const client = useMagentrixSdk({
499
+ baseUrl: 'https://your-instance.magentrix.com',
500
+ refreshToken: 'your-refresh-token',
501
+ isDevMode: true
502
+ })
503
+
504
+ const accounts = ref([])
505
+ const loading = ref(false)
506
+ const error = ref(null)
507
+
508
+ const loadAccounts = async () => {
509
+ loading.value = true
510
+ error.value = null
511
+
512
+ try {
513
+ await client.createSession()
514
+ const results = await client.query('SELECT Id, Name FROM Account')
515
+ accounts.value = results
516
+ } catch (err) {
517
+ error.value = err.message
518
+ } finally {
519
+ loading.value = false
520
+ }
521
+ }
522
+
523
+ onMounted(() => {
524
+ loadAccounts()
525
+ })
526
+ </script>
527
+
528
+ <template>
529
+ <div>
530
+ <div v-if="loading">Loading...</div>
531
+ <div v-else-if="error">Error: {{ error }}</div>
532
+ <ul v-else>
533
+ <li v-for="account in accounts" :key="account.Id">
534
+ {{ account.Name }}
535
+ </li>
536
+ </ul>
537
+ </div>
538
+ </template>
539
+ ```
540
+
541
+ ### Reactive CRUD Operations
542
+
543
+ ```vue
544
+ <script setup>
545
+ import { ref } from 'vue'
546
+ import { useMagentrixSdk } from 'magentrix-sdk/vue'
547
+
548
+ const client = useMagentrixSdk({
549
+ baseUrl: 'https://your-instance.magentrix.com',
550
+ isDevMode: true
551
+ })
552
+
553
+ const formData = ref({
554
+ Name: '',
555
+ Email: '',
556
+ Status: 'Active'
557
+ })
558
+
559
+ const createAccount = async () => {
560
+ try {
561
+ const created = await client.create('Account', formData.value)
562
+ console.log('Created:', created)
563
+
564
+ // Reset form
565
+ formData.value = { Name: '', Email: '', Status: 'Active' }
566
+ } catch (error) {
567
+ console.error('Failed to create account:', error)
568
+ }
569
+ }
570
+
571
+ const updateAccount = async (id) => {
572
+ try {
573
+ await client.edit('Account', {
574
+ Id: id,
575
+ ...formData.value
576
+ })
577
+ console.log('Updated successfully')
578
+ } catch (error) {
579
+ console.error('Failed to update account:', error)
580
+ }
581
+ }
582
+
583
+ const deleteAccount = async (id) => {
584
+ try {
585
+ await client.delete('Account', id)
586
+ console.log('Deleted successfully')
587
+ } catch (error) {
588
+ console.error('Failed to delete account:', error)
589
+ }
590
+ }
591
+ </script>
592
+ ```
593
+
594
+ ---
595
+
596
+ ## Best Practices
597
+
598
+ ### 1. Environment-Specific Configuration
599
+
600
+ Use environment variables for configuration:
601
+
602
+ ```typescript
603
+ const client = new MagentrixClient({
604
+ baseUrl: process.env.MAGENTRIX_BASE_URL || 'https://default.magentrix.com',
605
+ refreshToken: process.env.MAGENTRIX_REFRESH_TOKEN,
606
+ isDevMode: process.env.NODE_ENV === 'development'
607
+ })
608
+ ```
609
+
610
+ ### 2. Error Handling
611
+
612
+ Always handle errors appropriately:
613
+
614
+ ```typescript
615
+ try {
616
+ const result = await client.create('Account', data)
617
+ // Handle success
618
+ } catch (error) {
619
+ if (error instanceof DatabaseError) {
620
+ // Handle database validation errors
621
+ error.getErrors().forEach(err => {
622
+ console.error(`${err.fieldName}: ${err.message}`)
623
+ })
624
+ } else if (error instanceof MagentrixError) {
625
+ // Handle general SDK errors
626
+ console.error('SDK Error:', error.message)
627
+ } else {
628
+ // Handle unexpected errors
629
+ console.error('Unexpected error:', error)
630
+ }
631
+ }
632
+ ```
633
+
634
+ ### 3. Session Management
635
+
636
+ For development mode, create session once at app initialization:
637
+
638
+ ```typescript
639
+ // app.ts or main.ts
640
+ const client = new MagentrixClient({
641
+ baseUrl: 'https://your-instance.magentrix.com',
642
+ refreshToken: 'your-refresh-token',
643
+ isDevMode: true
644
+ })
645
+
646
+ // Initialize session
647
+ await client.createSession()
648
+
649
+ // Export for use throughout the app
650
+ export { client }
651
+ ```
652
+
653
+ ### 4. Production Deployment
654
+
655
+ For production (cookie-based auth), no session creation needed:
656
+
657
+ ```typescript
658
+ const client = new MagentrixClient({
659
+ baseUrl: 'https://your-instance.magentrix.com',
660
+ isDevMode: false // Uses ASP.NET session cookies
661
+ })
662
+
663
+ // No need to call createSession()
664
+ // Just use the client directly
665
+ const data = await client.query('SELECT Id FROM Account')
666
+ ```
667
+
668
+ ---
669
+
670
+ ## Troubleshooting
671
+
672
+ ### Common Issues
673
+
674
+ **Issue**: `Session expired and no refresh token available`
675
+
676
+ **Solution**: Ensure `refreshToken` is provided in config when using `isDevMode: true`
677
+
678
+ ```typescript
679
+ const client = new MagentrixClient({
680
+ baseUrl: 'https://your-instance.magentrix.com',
681
+ refreshToken: 'your-refresh-token', // Required for dev mode
682
+ isDevMode: true
683
+ })
684
+ ```
685
+
686
+ ---
687
+
688
+ **Issue**: `Login failed` error when creating session
689
+
690
+ **Solution**: Verify that your refresh token is valid and not expired. Refresh tokens can be obtained from your Magentrix instance.
691
+
692
+ ---
693
+
694
+ **Issue**: Redirected to login page in production
695
+
696
+ **Solution**: This is expected behavior when using `isDevMode: false`. The SDK automatically detects session expiration and redirects to the login page. Ensure users are authenticated via ASP.NET Forms Authentication.
697
+
698
+ ---
699
+
700
+ ## License
701
+
702
+ Proprietary
703
+
704
+ ## Support
705
+
706
+ For issues and questions:
707
+ - GitHub Issues: [Create an issue](https://github.com/your-repo/magentrix-sdk/issues)
708
+ - Documentation: [Magentrix Developer Portal](https://your-instance.magentrix.com/docs)
709
+
710
+ ---
711
+
712
+ ## Changelog
713
+
714
+ ### 1.0.0
715
+ - Initial release
716
+ - Token-based and cookie-based authentication
717
+ - CRUD operations
718
+ - Custom queries
719
+ - Vue 3 composable
720
+ - TypeScript support
721
+ - Automatic session management
package/package.json CHANGED
@@ -1,39 +1,54 @@
1
- {
2
- "name": "@magentrix-corp/magentrix-sdk",
3
- "version": "1.0.0",
4
- "description": "",
5
- "main": "dist/index.cjs.js",
6
- "module": "dist/index.js",
7
- "types": "dist/types/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/index.js",
11
- "require": "./dist/index.cjs.js"
12
- },
13
- "./vue": {
14
- "import": "./dist/vue/useMagentrixSdk.js",
15
- "require": "./dist/vue/useMagentrixSdk.js"
16
- }
17
- },
18
- "files": [
19
- "dist"
20
- ],
21
- "scripts": {
22
- "build": "rollup -c"
23
- },
24
- "peerDependencies": {
25
- "vue": "^3.5.22"
26
- },
27
- "devDependencies": {
28
- "@rollup/plugin-commonjs": "^29.0.0",
29
- "@rollup/plugin-node-resolve": "^16.0.3",
30
- "@rollup/plugin-typescript": "^12.3.0",
31
- "rollup": "^2.79.2",
32
- "rollup-plugin-copy": "^3.5.0",
33
- "rollup-plugin-terser": "^7.0.2",
34
- "typescript": "^5.9.3"
35
- },
36
- "dependencies": {
37
- "tslib": "^2.8.1"
38
- }
39
- }
1
+ {
2
+ "name": "@magentrix-corp/magentrix-sdk",
3
+ "version": "1.0.2",
4
+ "description": "TypeScript SDK for Magentrix APIs with dual authentication modes, automatic session management, CRUD operations, and Vue 3 integration",
5
+ "main": "dist/index.cjs.js",
6
+ "module": "dist/index.js",
7
+ "types": "dist/types/index.d.ts",
8
+ "keywords": [
9
+ "magentrix",
10
+ "sdk",
11
+ "api",
12
+ "typescript",
13
+ "vue",
14
+ "crm",
15
+ "portal"
16
+ ],
17
+ "author": "Magentrix Corporation",
18
+ "license": "Proprietary",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/your-repo/magentrix-sdk.git"
22
+ },
23
+ "exports": {
24
+ ".": {
25
+ "import": "./dist/index.js",
26
+ "require": "./dist/index.cjs.js"
27
+ },
28
+ "./vue": {
29
+ "import": "./dist/vue/useMagentrixSdk.js",
30
+ "require": "./dist/vue/useMagentrixSdk.js"
31
+ }
32
+ },
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "scripts": {
37
+ "build": "rollup -c"
38
+ },
39
+ "peerDependencies": {
40
+ "vue": "^3.5.22"
41
+ },
42
+ "devDependencies": {
43
+ "@rollup/plugin-commonjs": "^29.0.0",
44
+ "@rollup/plugin-node-resolve": "^16.0.3",
45
+ "@rollup/plugin-typescript": "^12.3.0",
46
+ "rollup": "^2.79.2",
47
+ "rollup-plugin-copy": "^3.5.0",
48
+ "rollup-plugin-terser": "^7.0.2",
49
+ "typescript": "^5.9.3"
50
+ },
51
+ "dependencies": {
52
+ "tslib": "^2.8.1"
53
+ }
54
+ }
package/dist/index.cjs.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";var t,e;Object.defineProperty(exports,"__esModule",{value:!0}),exports.RequestMethod=void 0,(t=exports.RequestMethod||(exports.RequestMethod={})).get="GET",t.post="POST",t.put="PUT",t.patch="PATCH",t.delete="DELETE",exports.ContentType=void 0,(e=exports.ContentType||(exports.ContentType={})).json="application/json",e.form_url_encoded="application/x-www-form-urlencoded",e.xml="application/xml",e.text="text/plain";class r extends Error{constructor(t){super(t),this.name="MagentrixError",Object.setPrototypeOf(this,r.prototype)}}class s extends Error{errors;constructor(t,e=[]){super(t),this.name="DatabaseError",this.errors=e,Object.setPrototypeOf(this,s.prototype)}getErrors(){return this.errors}hasErrors(){return this.errors.length>0}}exports.DatabaseError=s,exports.MagentrixClient=class{config;sessionInfo=null;restVersion="3.0";constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),token:t.token,refreshToken:t.refreshToken,antiForgeryToken:t.antiForgeryToken,onSessionExpired:t.onSessionExpired,onError:t.onError},t.token&&(this.sessionInfo={token:t.token,refresh_token:t.refreshToken||"",expires_in:0})}async createSession(t){const e=t||this.config.refreshToken;if(!e)throw new r("Refresh token is required to create a session");const s=`${this.config.baseUrl}/api/${this.restVersion}/token`,o={grant_type:"refresh_token",refresh_token:e},n=await fetch(s,{method:"POST",headers:{"Content-Type":exports.ContentType.json},body:JSON.stringify(o)});if(!n.ok){const t=await n.json();throw new r(t.message||"Failed to create session")}return this.sessionInfo=await n.json(),this.sessionInfo}async query(t){if(!t)throw new r("Query is required");const e={query:t,permissions:null},s=this.convertToEncodedKeyValuePairs(e);return this.postData("/iris/query",s,exports.ContentType.form_url_encoded)}async execute(t,e=null,s=exports.RequestMethod.post){if(!t)throw new r("Endpoint path is required");if(s===exports.RequestMethod.get&&e)throw new r("GET requests cannot have a request body");if(s===exports.RequestMethod.get)return this.getData(t);{const r=e?this.convertToEncodedKeyValuePairs(e):null;return this.postData(t,r,exports.ContentType.form_url_encoded)}}async retrieve(t){if(!t)throw new r("ID is required");const e={id:t,permissions:null},s=`/iris/retrieve?${this.convertToEncodedKeyValuePairs(e)}`;return this.getData(s)}async create(t,e){if(!t)throw new r("Entity name is required");if(!e)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${t}`;return this.postData(s,e)}async edit(t,e){if(!t)throw new r("Entity name is required");if(!e)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${t}`;return this.patchData(s,e)}async upsert(t,e){if(!t)throw new r("Entity name is required");if(!e)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${t}`;return this.putData(s,e)}async delete(t,e,s=!1){if(!e)throw new r("ID is required");if(!t)throw new r("Entity name is required");const o=`/api/${this.restVersion}/entity/${t}/${e}?isPermanent=${s}`;return this.deleteData(o)}async deleteMany(t,e,s=!1){if(!e||0===e.length)throw new r("IDs are required");if(!t)throw new r("Entity name is required");const o=`/api/${this.restVersion}/entity/${t}?isPermanent=${s}`;return this.deleteData(o,e)}convertToEncodedKeyValuePairs(t){let e="";for(const[r,s]of Object.entries(t)){let t;t=null==s?"":"object"==typeof s?JSON.stringify(s):s.toString(),e+=`${r}=${encodeURIComponent(t)}&`}return e.endsWith("&")&&(e=e.substring(0,e.length-1)),e}async getData(t){const e=this.getFullUrl(t),r=this.getRequestOptions(),s=await fetch(e,r);if(await this.handleAuthError(s))return this.getData(t);const o=await s.json();return s.ok||this.throwError(o),o}async postData(t,e,r=exports.ContentType.json){const s=this.getFullUrl(t),o={...this.getRequestOptions(exports.RequestMethod.post,r),body:r===exports.ContentType.json?JSON.stringify(e):e},n=await fetch(s,o);if(await this.handleAuthError(n))return this.postData(t,e,r);const i=await n.json();return n.ok||this.throwError(i),this.fillIdsOnCreate(e,i),e?.hasOwnProperty("ModifiedOn")&&(e.ModifiedOn=(new Date).toISOString().slice(0,-1)),i}async patchData(t,e){const r=this.getFullUrl(t),s={...this.getRequestOptions(exports.RequestMethod.patch),body:JSON.stringify(e)},o=await fetch(r,s);if(await this.handleAuthError(o))return this.patchData(t,e);const n=await o.json();return o.ok||this.throwError(n),e?.hasOwnProperty("ModifiedOn")&&(e.ModifiedOn=(new Date).toISOString().slice(0,-1)),n}async putData(t,e){const r=this.getFullUrl(t),s={...this.getRequestOptions(exports.RequestMethod.put),body:JSON.stringify(e)},o=await fetch(r,s);if(await this.handleAuthError(o))return this.putData(t,e);const n=await o.json();return o.ok||this.throwError(n),e.Id||this.fillIdsOnCreate(e,n),e?.hasOwnProperty("ModifiedOn")&&(e.ModifiedOn=(new Date).toISOString().slice(0,-1)),n}async deleteData(t,e=null){const r=this.getFullUrl(t),s={...this.getRequestOptions(exports.RequestMethod.delete),body:e?JSON.stringify(e):null},o=await fetch(r,s);if(await this.handleAuthError(o))return this.deleteData(t,e);const n=await o.json();return o.ok||this.throwError(n),n}getRequestOptions(t=exports.RequestMethod.get,e=exports.ContentType.json,r=exports.ContentType.json){const s={method:t,headers:{"Content-Type":e,"MAG-StrictMode":"false",Accept:r}};return t===exports.RequestMethod.post&&this.config.antiForgeryToken&&(s.headers.__RequestVerificationToken=this.config.antiForgeryToken),this.sessionInfo?.token&&(s.headers.Authorization=`Bearer ${this.sessionInfo.token}`),s}async handleAuthError(t){return!(401!==t.status&&403!==t.status||!this.config.onSessionExpired)&&(await this.config.onSessionExpired(),!0)}getFullUrl(t){return t.startsWith("http://")||t.startsWith("https://")?t:`${this.config.baseUrl}${t.startsWith("/")?t:"/"+t}`}fillIdsOnCreate(t,e){if(null==t)return;if(Array.isArray(t)){const r=t.length;if(0===r)return;for(let s=0;s<r;s++)void 0===t[s].Id&&e[s].Id&&(t[s].Id=e[s].Id)}else void 0===t.Id&&e.Id&&(t.Id=e.Id)}throwError(t){throw this.config.onError&&this.config.onError(t),"string"==typeof t?new r(t):t.hasOwnProperty("message")?new r(t.message):t.hasOwnProperty("errors")?new s("Database Error",t.errors):new r("Unknown error!")}},exports.MagentrixError=r;
2
- //# sourceMappingURL=index.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/helpers/enums.ts","../src/helpers/errors.ts","../src/helpers/MagentrixClient.ts"],"sourcesContent":["export enum RequestMethod {\n get = 'GET',\n post = 'POST',\n put = 'PUT',\n patch = 'PATCH',\n delete = 'DELETE'\n}\n\nexport enum ContentType {\n json = 'application/json',\n form_url_encoded = 'application/x-www-form-urlencoded',\n xml = 'application/xml',\n text = 'text/plain'\n}\n","export class MagentrixError extends Error {\r\n constructor(message: string) {\r\n super(message)\r\n this.name = 'MagentrixError'\r\n Object.setPrototypeOf(this, MagentrixError.prototype)\r\n }\r\n}\r\n\r\nexport class DatabaseError extends Error {\r\n errors: any[]\r\n\r\n constructor(message: string, errors: any[] = []) {\r\n super(message)\r\n this.name = 'DatabaseError'\r\n this.errors = errors\r\n Object.setPrototypeOf(this, DatabaseError.prototype)\r\n }\r\n\r\n getErrors(): any[] {\r\n return this.errors\r\n }\r\n\r\n hasErrors(): boolean {\r\n return this.errors.length > 0\r\n }\r\n}\r\n","import { RequestMethod, ContentType } from './enums'\r\nimport { MagentrixConfig, SessionInfo } from './interfaces'\r\nimport { MagentrixError, DatabaseError } from './errors'\r\n\r\nexport class MagentrixClient {\r\n private config: MagentrixConfig\r\n private sessionInfo: SessionInfo | null = null\r\n private restVersion = '3.0'\r\n\r\n constructor(config: MagentrixConfig) {\r\n this.config = {\r\n baseUrl: config.baseUrl.replace(/\\/$/, ''),\r\n token: config.token,\r\n refreshToken: config.refreshToken,\r\n antiForgeryToken: config.antiForgeryToken,\r\n onSessionExpired: config.onSessionExpired,\r\n onError: config.onError\r\n }\r\n\r\n if (config.token) {\r\n this.sessionInfo = {\r\n token: config.token,\r\n refresh_token: config.refreshToken || '',\r\n expires_in: 0\r\n }\r\n }\r\n }\r\n\r\n async createSession(refreshToken?: string): Promise<SessionInfo> {\r\n const token = refreshToken || this.config.refreshToken\r\n\r\n if (!token)\r\n throw new MagentrixError('Refresh token is required to create a session')\r\n\r\n const url = `${this.config.baseUrl}/api/${this.restVersion}/token`\r\n const body = { grant_type: 'refresh_token', refresh_token: token }\r\n \r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: { 'Content-Type': ContentType.json },\r\n body: JSON.stringify(body)\r\n })\r\n\r\n if (!response.ok) {\r\n const error = await response.json()\r\n throw new MagentrixError(error.message || 'Failed to create session')\r\n }\r\n\r\n this.sessionInfo = await response.json()\r\n return this.sessionInfo!\r\n }\r\n\r\n async query(query: string): Promise<any> {\r\n if (!query)\r\n throw new MagentrixError('Query is required')\r\n\r\n const path = '/iris/query'\r\n const model = { query, permissions: null }\r\n const data = this.convertToEncodedKeyValuePairs(model)\r\n \r\n return this.postData(path, data, ContentType.form_url_encoded)\r\n }\r\n\r\n async execute(path: string, model: any = null, method = RequestMethod.post): Promise<any> {\r\n if (!path)\r\n throw new MagentrixError('Endpoint path is required')\r\n\r\n if (method === RequestMethod.get && model)\r\n throw new MagentrixError('GET requests cannot have a request body')\r\n\r\n if (method === RequestMethod.get)\r\n return this.getData(path)\r\n else {\r\n const data = model ? this.convertToEncodedKeyValuePairs(model) : null\r\n return this.postData(path, data, ContentType.form_url_encoded)\r\n }\r\n }\r\n\r\n async retrieve(id: string): Promise<any> {\r\n if (!id)\r\n throw new MagentrixError('ID is required')\r\n\r\n const model = { id, permissions: null }\r\n const data = this.convertToEncodedKeyValuePairs(model)\r\n const path = `/iris/retrieve?${data}`\r\n \r\n return this.getData(path)\r\n }\r\n\r\n async create(entityName: string, data: any): Promise<any> {\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n if (!data)\r\n throw new MagentrixError('Data is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}`\r\n \r\n return this.postData(path, data)\r\n }\r\n\r\n async edit(entityName: string, data: any): Promise<any> {\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n if (!data)\r\n throw new MagentrixError('Data is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}`\r\n \r\n return this.patchData(path, data)\r\n }\r\n\r\n async upsert(entityName: string, data: any): Promise<any> {\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n if (!data)\r\n throw new MagentrixError('Data is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}`\r\n \r\n return this.putData(path, data)\r\n }\r\n\r\n async delete(entityName: string, id: string, permanent: boolean = false): Promise<any> {\r\n if (!id)\r\n throw new MagentrixError('ID is required')\r\n\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}/${id}?isPermanent=${permanent}`\r\n \r\n return this.deleteData(path)\r\n }\r\n\r\n async deleteMany(entityName: string, ids: string[], permanent: boolean = false): Promise<any> {\r\n if (!ids || ids.length === 0)\r\n throw new MagentrixError('IDs are required')\r\n\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}?isPermanent=${permanent}`\r\n \r\n return this.deleteData(path, ids)\r\n }\r\n\r\n private convertToEncodedKeyValuePairs(obj: any): string {\r\n let result = ''\r\n\r\n for (const [key, value] of Object.entries(obj)) {\r\n let modifiedValue: string\r\n\r\n if (value === null || value === undefined)\r\n modifiedValue = ''\r\n else if (typeof value === 'object')\r\n modifiedValue = JSON.stringify(value)\r\n else\r\n modifiedValue = value.toString()\r\n\r\n result += `${key}=${encodeURIComponent(modifiedValue)}&`\r\n }\r\n\r\n if (result.endsWith('&'))\r\n result = result.substring(0, result.length - 1)\r\n\r\n return result\r\n }\r\n\r\n private async getData(path: string): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = this.getRequestOptions()\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.getData(path)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n return result\r\n }\r\n\r\n private async postData(path: string, data: any, contentType: ContentType = ContentType.json): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.post, contentType),\r\n body: contentType === ContentType.json ? JSON.stringify(data) : data\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.postData(path, data, contentType)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n this.fillIdsOnCreate(data, result)\r\n\r\n if (data?.hasOwnProperty('ModifiedOn'))\r\n data.ModifiedOn = new Date().toISOString().slice(0, -1)\r\n\r\n return result\r\n }\r\n\r\n private async patchData(path: string, data: any): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.patch),\r\n body: JSON.stringify(data)\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.patchData(path, data)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n if (data?.hasOwnProperty('ModifiedOn'))\r\n data.ModifiedOn = new Date().toISOString().slice(0, -1)\r\n\r\n return result\r\n }\r\n\r\n private async putData(path: string, data: any): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.put),\r\n body: JSON.stringify(data)\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.putData(path, data)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n if (!data.Id)\r\n this.fillIdsOnCreate(data, result)\r\n\r\n if (data?.hasOwnProperty('ModifiedOn'))\r\n data.ModifiedOn = new Date().toISOString().slice(0, -1)\r\n\r\n return result\r\n }\r\n\r\n private async deleteData(path: string, data: any = null): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.delete),\r\n body: data ? JSON.stringify(data) : null\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.deleteData(path, data)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n return result\r\n }\r\n\r\n private getRequestOptions(\r\n method: RequestMethod = RequestMethod.get,\r\n contentType: ContentType = ContentType.json,\r\n acceptType: ContentType = ContentType.json\r\n ): RequestInit {\r\n const options: RequestInit = {\r\n method: method,\r\n headers: {\r\n 'Content-Type': contentType,\r\n 'MAG-StrictMode': 'false',\r\n 'Accept': acceptType\r\n }\r\n }\r\n\r\n if (method === RequestMethod.post && this.config.antiForgeryToken) {\r\n (options.headers as any).__RequestVerificationToken = this.config.antiForgeryToken\r\n }\r\n\r\n if (this.sessionInfo?.token) {\r\n (options.headers as any).Authorization = `Bearer ${this.sessionInfo.token}`\r\n }\r\n\r\n return options\r\n }\r\n\r\n private async handleAuthError(response: Response): Promise<boolean> {\r\n if (response.status === 401 || response.status === 403) {\r\n if (this.config.onSessionExpired) {\r\n await this.config.onSessionExpired()\r\n return true\r\n }\r\n }\r\n\r\n return false\r\n }\r\n\r\n private getFullUrl(path: string): string {\r\n if (path.startsWith('http://') || path.startsWith('https://'))\r\n return path\r\n\r\n return `${this.config.baseUrl}${path.startsWith('/') ? path : '/' + path}`\r\n }\r\n\r\n private fillIdsOnCreate(data: any | any[], result: any | any[]): void {\r\n if (data == null)\r\n return\r\n\r\n const isArray = Array.isArray(data)\r\n\r\n if (isArray) {\r\n const count = data.length\r\n\r\n if (count === 0)\r\n return\r\n\r\n for (let i = 0; i < count; i++) {\r\n if (data[i].Id === undefined && result[i].Id)\r\n data[i].Id = result[i].Id\r\n }\r\n } else {\r\n if (data.Id === undefined && result.Id)\r\n data.Id = result.Id\r\n }\r\n }\r\n\r\n private throwError(error: any): never {\r\n if (this.config.onError)\r\n this.config.onError(error)\r\n\r\n if (typeof error === 'string')\r\n throw new MagentrixError(error)\r\n else if (error.hasOwnProperty('message'))\r\n throw new MagentrixError(error.message)\r\n else if (error.hasOwnProperty('errors'))\r\n throw new DatabaseError('Database Error', error.errors)\r\n else\r\n throw new MagentrixError('Unknown error!')\r\n }\r\n}\r\n"],"names":["RequestMethod","ContentType","MagentrixError","Error","constructor","message","super","this","name","Object","setPrototypeOf","prototype","DatabaseError","errors","getErrors","hasErrors","length","config","sessionInfo","restVersion","baseUrl","replace","token","refreshToken","antiForgeryToken","onSessionExpired","onError","refresh_token","expires_in","createSession","url","body","grant_type","response","fetch","method","headers","json","JSON","stringify","ok","error","query","model","permissions","data","convertToEncodedKeyValuePairs","postData","form_url_encoded","execute","path","post","get","getData","retrieve","id","create","entityName","edit","patchData","upsert","putData","permanent","deleteData","deleteMany","ids","obj","result","key","value","entries","modifiedValue","toString","encodeURIComponent","endsWith","substring","getFullUrl","options","getRequestOptions","handleAuthError","throwError","contentType","fillIdsOnCreate","hasOwnProperty","ModifiedOn","Date","toISOString","slice","patch","put","Id","delete","acceptType","Accept","__RequestVerificationToken","Authorization","status","startsWith","Array","isArray","count","i","undefined"],"mappings":"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"}
package/dist/index.js DELETED
@@ -1,2 +0,0 @@
1
- var t,e;!function(t){t.get="GET",t.post="POST",t.put="PUT",t.patch="PATCH",t.delete="DELETE"}(t||(t={})),function(t){t.json="application/json",t.form_url_encoded="application/x-www-form-urlencoded",t.xml="application/xml",t.text="text/plain"}(e||(e={}));class r extends Error{constructor(t){super(t),this.name="MagentrixError",Object.setPrototypeOf(this,r.prototype)}}class s extends Error{errors;constructor(t,e=[]){super(t),this.name="DatabaseError",this.errors=e,Object.setPrototypeOf(this,s.prototype)}getErrors(){return this.errors}hasErrors(){return this.errors.length>0}}class n{config;sessionInfo=null;restVersion="3.0";constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),token:t.token,refreshToken:t.refreshToken,antiForgeryToken:t.antiForgeryToken,onSessionExpired:t.onSessionExpired,onError:t.onError},t.token&&(this.sessionInfo={token:t.token,refresh_token:t.refreshToken||"",expires_in:0})}async createSession(t){const s=t||this.config.refreshToken;if(!s)throw new r("Refresh token is required to create a session");const n=`${this.config.baseUrl}/api/${this.restVersion}/token`,i={grant_type:"refresh_token",refresh_token:s},o=await fetch(n,{method:"POST",headers:{"Content-Type":e.json},body:JSON.stringify(i)});if(!o.ok){const t=await o.json();throw new r(t.message||"Failed to create session")}return this.sessionInfo=await o.json(),this.sessionInfo}async query(t){if(!t)throw new r("Query is required");const s={query:t,permissions:null},n=this.convertToEncodedKeyValuePairs(s);return this.postData("/iris/query",n,e.form_url_encoded)}async execute(s,n=null,i=t.post){if(!s)throw new r("Endpoint path is required");if(i===t.get&&n)throw new r("GET requests cannot have a request body");if(i===t.get)return this.getData(s);{const t=n?this.convertToEncodedKeyValuePairs(n):null;return this.postData(s,t,e.form_url_encoded)}}async retrieve(t){if(!t)throw new r("ID is required");const e={id:t,permissions:null},s=`/iris/retrieve?${this.convertToEncodedKeyValuePairs(e)}`;return this.getData(s)}async create(t,e){if(!t)throw new r("Entity name is required");if(!e)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${t}`;return this.postData(s,e)}async edit(t,e){if(!t)throw new r("Entity name is required");if(!e)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${t}`;return this.patchData(s,e)}async upsert(t,e){if(!t)throw new r("Entity name is required");if(!e)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${t}`;return this.putData(s,e)}async delete(t,e,s=!1){if(!e)throw new r("ID is required");if(!t)throw new r("Entity name is required");const n=`/api/${this.restVersion}/entity/${t}/${e}?isPermanent=${s}`;return this.deleteData(n)}async deleteMany(t,e,s=!1){if(!e||0===e.length)throw new r("IDs are required");if(!t)throw new r("Entity name is required");const n=`/api/${this.restVersion}/entity/${t}?isPermanent=${s}`;return this.deleteData(n,e)}convertToEncodedKeyValuePairs(t){let e="";for(const[r,s]of Object.entries(t)){let t;t=null==s?"":"object"==typeof s?JSON.stringify(s):s.toString(),e+=`${r}=${encodeURIComponent(t)}&`}return e.endsWith("&")&&(e=e.substring(0,e.length-1)),e}async getData(t){const e=this.getFullUrl(t),r=this.getRequestOptions(),s=await fetch(e,r);if(await this.handleAuthError(s))return this.getData(t);const n=await s.json();return s.ok||this.throwError(n),n}async postData(r,s,n=e.json){const i=this.getFullUrl(r),o={...this.getRequestOptions(t.post,n),body:n===e.json?JSON.stringify(s):s},a=await fetch(i,o);if(await this.handleAuthError(a))return this.postData(r,s,n);const h=await a.json();return a.ok||this.throwError(h),this.fillIdsOnCreate(s,h),s?.hasOwnProperty("ModifiedOn")&&(s.ModifiedOn=(new Date).toISOString().slice(0,-1)),h}async patchData(e,r){const s=this.getFullUrl(e),n={...this.getRequestOptions(t.patch),body:JSON.stringify(r)},i=await fetch(s,n);if(await this.handleAuthError(i))return this.patchData(e,r);const o=await i.json();return i.ok||this.throwError(o),r?.hasOwnProperty("ModifiedOn")&&(r.ModifiedOn=(new Date).toISOString().slice(0,-1)),o}async putData(e,r){const s=this.getFullUrl(e),n={...this.getRequestOptions(t.put),body:JSON.stringify(r)},i=await fetch(s,n);if(await this.handleAuthError(i))return this.putData(e,r);const o=await i.json();return i.ok||this.throwError(o),r.Id||this.fillIdsOnCreate(r,o),r?.hasOwnProperty("ModifiedOn")&&(r.ModifiedOn=(new Date).toISOString().slice(0,-1)),o}async deleteData(e,r=null){const s=this.getFullUrl(e),n={...this.getRequestOptions(t.delete),body:r?JSON.stringify(r):null},i=await fetch(s,n);if(await this.handleAuthError(i))return this.deleteData(e,r);const o=await i.json();return i.ok||this.throwError(o),o}getRequestOptions(r=t.get,s=e.json,n=e.json){const i={method:r,headers:{"Content-Type":s,"MAG-StrictMode":"false",Accept:n}};return r===t.post&&this.config.antiForgeryToken&&(i.headers.__RequestVerificationToken=this.config.antiForgeryToken),this.sessionInfo?.token&&(i.headers.Authorization=`Bearer ${this.sessionInfo.token}`),i}async handleAuthError(t){return!(401!==t.status&&403!==t.status||!this.config.onSessionExpired)&&(await this.config.onSessionExpired(),!0)}getFullUrl(t){return t.startsWith("http://")||t.startsWith("https://")?t:`${this.config.baseUrl}${t.startsWith("/")?t:"/"+t}`}fillIdsOnCreate(t,e){if(null==t)return;if(Array.isArray(t)){const r=t.length;if(0===r)return;for(let s=0;s<r;s++)void 0===t[s].Id&&e[s].Id&&(t[s].Id=e[s].Id)}else void 0===t.Id&&e.Id&&(t.Id=e.Id)}throwError(t){throw this.config.onError&&this.config.onError(t),"string"==typeof t?new r(t):t.hasOwnProperty("message")?new r(t.message):t.hasOwnProperty("errors")?new s("Database Error",t.errors):new r("Unknown error!")}}export{e as ContentType,s as DatabaseError,n as MagentrixClient,r as MagentrixError,t as RequestMethod};
2
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../src/helpers/enums.ts","../src/helpers/errors.ts","../src/helpers/MagentrixClient.ts"],"sourcesContent":["export enum RequestMethod {\n get = 'GET',\n post = 'POST',\n put = 'PUT',\n patch = 'PATCH',\n delete = 'DELETE'\n}\n\nexport enum ContentType {\n json = 'application/json',\n form_url_encoded = 'application/x-www-form-urlencoded',\n xml = 'application/xml',\n text = 'text/plain'\n}\n","export class MagentrixError extends Error {\r\n constructor(message: string) {\r\n super(message)\r\n this.name = 'MagentrixError'\r\n Object.setPrototypeOf(this, MagentrixError.prototype)\r\n }\r\n}\r\n\r\nexport class DatabaseError extends Error {\r\n errors: any[]\r\n\r\n constructor(message: string, errors: any[] = []) {\r\n super(message)\r\n this.name = 'DatabaseError'\r\n this.errors = errors\r\n Object.setPrototypeOf(this, DatabaseError.prototype)\r\n }\r\n\r\n getErrors(): any[] {\r\n return this.errors\r\n }\r\n\r\n hasErrors(): boolean {\r\n return this.errors.length > 0\r\n }\r\n}\r\n","import { RequestMethod, ContentType } from './enums'\r\nimport { MagentrixConfig, SessionInfo } from './interfaces'\r\nimport { MagentrixError, DatabaseError } from './errors'\r\n\r\nexport class MagentrixClient {\r\n private config: MagentrixConfig\r\n private sessionInfo: SessionInfo | null = null\r\n private restVersion = '3.0'\r\n\r\n constructor(config: MagentrixConfig) {\r\n this.config = {\r\n baseUrl: config.baseUrl.replace(/\\/$/, ''),\r\n token: config.token,\r\n refreshToken: config.refreshToken,\r\n antiForgeryToken: config.antiForgeryToken,\r\n onSessionExpired: config.onSessionExpired,\r\n onError: config.onError\r\n }\r\n\r\n if (config.token) {\r\n this.sessionInfo = {\r\n token: config.token,\r\n refresh_token: config.refreshToken || '',\r\n expires_in: 0\r\n }\r\n }\r\n }\r\n\r\n async createSession(refreshToken?: string): Promise<SessionInfo> {\r\n const token = refreshToken || this.config.refreshToken\r\n\r\n if (!token)\r\n throw new MagentrixError('Refresh token is required to create a session')\r\n\r\n const url = `${this.config.baseUrl}/api/${this.restVersion}/token`\r\n const body = { grant_type: 'refresh_token', refresh_token: token }\r\n \r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: { 'Content-Type': ContentType.json },\r\n body: JSON.stringify(body)\r\n })\r\n\r\n if (!response.ok) {\r\n const error = await response.json()\r\n throw new MagentrixError(error.message || 'Failed to create session')\r\n }\r\n\r\n this.sessionInfo = await response.json()\r\n return this.sessionInfo!\r\n }\r\n\r\n async query(query: string): Promise<any> {\r\n if (!query)\r\n throw new MagentrixError('Query is required')\r\n\r\n const path = '/iris/query'\r\n const model = { query, permissions: null }\r\n const data = this.convertToEncodedKeyValuePairs(model)\r\n \r\n return this.postData(path, data, ContentType.form_url_encoded)\r\n }\r\n\r\n async execute(path: string, model: any = null, method = RequestMethod.post): Promise<any> {\r\n if (!path)\r\n throw new MagentrixError('Endpoint path is required')\r\n\r\n if (method === RequestMethod.get && model)\r\n throw new MagentrixError('GET requests cannot have a request body')\r\n\r\n if (method === RequestMethod.get)\r\n return this.getData(path)\r\n else {\r\n const data = model ? this.convertToEncodedKeyValuePairs(model) : null\r\n return this.postData(path, data, ContentType.form_url_encoded)\r\n }\r\n }\r\n\r\n async retrieve(id: string): Promise<any> {\r\n if (!id)\r\n throw new MagentrixError('ID is required')\r\n\r\n const model = { id, permissions: null }\r\n const data = this.convertToEncodedKeyValuePairs(model)\r\n const path = `/iris/retrieve?${data}`\r\n \r\n return this.getData(path)\r\n }\r\n\r\n async create(entityName: string, data: any): Promise<any> {\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n if (!data)\r\n throw new MagentrixError('Data is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}`\r\n \r\n return this.postData(path, data)\r\n }\r\n\r\n async edit(entityName: string, data: any): Promise<any> {\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n if (!data)\r\n throw new MagentrixError('Data is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}`\r\n \r\n return this.patchData(path, data)\r\n }\r\n\r\n async upsert(entityName: string, data: any): Promise<any> {\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n if (!data)\r\n throw new MagentrixError('Data is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}`\r\n \r\n return this.putData(path, data)\r\n }\r\n\r\n async delete(entityName: string, id: string, permanent: boolean = false): Promise<any> {\r\n if (!id)\r\n throw new MagentrixError('ID is required')\r\n\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}/${id}?isPermanent=${permanent}`\r\n \r\n return this.deleteData(path)\r\n }\r\n\r\n async deleteMany(entityName: string, ids: string[], permanent: boolean = false): Promise<any> {\r\n if (!ids || ids.length === 0)\r\n throw new MagentrixError('IDs are required')\r\n\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}?isPermanent=${permanent}`\r\n \r\n return this.deleteData(path, ids)\r\n }\r\n\r\n private convertToEncodedKeyValuePairs(obj: any): string {\r\n let result = ''\r\n\r\n for (const [key, value] of Object.entries(obj)) {\r\n let modifiedValue: string\r\n\r\n if (value === null || value === undefined)\r\n modifiedValue = ''\r\n else if (typeof value === 'object')\r\n modifiedValue = JSON.stringify(value)\r\n else\r\n modifiedValue = value.toString()\r\n\r\n result += `${key}=${encodeURIComponent(modifiedValue)}&`\r\n }\r\n\r\n if (result.endsWith('&'))\r\n result = result.substring(0, result.length - 1)\r\n\r\n return result\r\n }\r\n\r\n private async getData(path: string): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = this.getRequestOptions()\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.getData(path)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n return result\r\n }\r\n\r\n private async postData(path: string, data: any, contentType: ContentType = ContentType.json): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.post, contentType),\r\n body: contentType === ContentType.json ? JSON.stringify(data) : data\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.postData(path, data, contentType)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n this.fillIdsOnCreate(data, result)\r\n\r\n if (data?.hasOwnProperty('ModifiedOn'))\r\n data.ModifiedOn = new Date().toISOString().slice(0, -1)\r\n\r\n return result\r\n }\r\n\r\n private async patchData(path: string, data: any): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.patch),\r\n body: JSON.stringify(data)\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.patchData(path, data)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n if (data?.hasOwnProperty('ModifiedOn'))\r\n data.ModifiedOn = new Date().toISOString().slice(0, -1)\r\n\r\n return result\r\n }\r\n\r\n private async putData(path: string, data: any): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.put),\r\n body: JSON.stringify(data)\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.putData(path, data)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n if (!data.Id)\r\n this.fillIdsOnCreate(data, result)\r\n\r\n if (data?.hasOwnProperty('ModifiedOn'))\r\n data.ModifiedOn = new Date().toISOString().slice(0, -1)\r\n\r\n return result\r\n }\r\n\r\n private async deleteData(path: string, data: any = null): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.delete),\r\n body: data ? JSON.stringify(data) : null\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.deleteData(path, data)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n return result\r\n }\r\n\r\n private getRequestOptions(\r\n method: RequestMethod = RequestMethod.get,\r\n contentType: ContentType = ContentType.json,\r\n acceptType: ContentType = ContentType.json\r\n ): RequestInit {\r\n const options: RequestInit = {\r\n method: method,\r\n headers: {\r\n 'Content-Type': contentType,\r\n 'MAG-StrictMode': 'false',\r\n 'Accept': acceptType\r\n }\r\n }\r\n\r\n if (method === RequestMethod.post && this.config.antiForgeryToken) {\r\n (options.headers as any).__RequestVerificationToken = this.config.antiForgeryToken\r\n }\r\n\r\n if (this.sessionInfo?.token) {\r\n (options.headers as any).Authorization = `Bearer ${this.sessionInfo.token}`\r\n }\r\n\r\n return options\r\n }\r\n\r\n private async handleAuthError(response: Response): Promise<boolean> {\r\n if (response.status === 401 || response.status === 403) {\r\n if (this.config.onSessionExpired) {\r\n await this.config.onSessionExpired()\r\n return true\r\n }\r\n }\r\n\r\n return false\r\n }\r\n\r\n private getFullUrl(path: string): string {\r\n if (path.startsWith('http://') || path.startsWith('https://'))\r\n return path\r\n\r\n return `${this.config.baseUrl}${path.startsWith('/') ? path : '/' + path}`\r\n }\r\n\r\n private fillIdsOnCreate(data: any | any[], result: any | any[]): void {\r\n if (data == null)\r\n return\r\n\r\n const isArray = Array.isArray(data)\r\n\r\n if (isArray) {\r\n const count = data.length\r\n\r\n if (count === 0)\r\n return\r\n\r\n for (let i = 0; i < count; i++) {\r\n if (data[i].Id === undefined && result[i].Id)\r\n data[i].Id = result[i].Id\r\n }\r\n } else {\r\n if (data.Id === undefined && result.Id)\r\n data.Id = result.Id\r\n }\r\n }\r\n\r\n private throwError(error: any): never {\r\n if (this.config.onError)\r\n this.config.onError(error)\r\n\r\n if (typeof error === 'string')\r\n throw new MagentrixError(error)\r\n else if (error.hasOwnProperty('message'))\r\n throw new MagentrixError(error.message)\r\n else if (error.hasOwnProperty('errors'))\r\n throw new DatabaseError('Database Error', error.errors)\r\n else\r\n throw new MagentrixError('Unknown error!')\r\n }\r\n}\r\n"],"names":["RequestMethod","ContentType","MagentrixError","Error","constructor","message","super","this","name","Object","setPrototypeOf","prototype","DatabaseError","errors","getErrors","hasErrors","length","MagentrixClient","config","sessionInfo","restVersion","baseUrl","replace","token","refreshToken","antiForgeryToken","onSessionExpired","onError","refresh_token","expires_in","createSession","url","body","grant_type","response","fetch","method","headers","json","JSON","stringify","ok","error","query","model","permissions","data","convertToEncodedKeyValuePairs","postData","form_url_encoded","execute","path","post","get","getData","retrieve","id","create","entityName","edit","patchData","upsert","putData","permanent","deleteData","deleteMany","ids","obj","result","key","value","entries","modifiedValue","toString","encodeURIComponent","endsWith","substring","getFullUrl","options","getRequestOptions","handleAuthError","throwError","contentType","fillIdsOnCreate","hasOwnProperty","ModifiedOn","Date","toISOString","slice","patch","put","Id","delete","acceptType","Accept","__RequestVerificationToken","Authorization","status","startsWith","Array","isArray","count","i","undefined"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- var t,e;!function(t){t.get="GET",t.post="POST",t.put="PUT",t.patch="PATCH",t.delete="DELETE"}(t||(t={})),function(t){t.json="application/json",t.form_url_encoded="application/x-www-form-urlencoded",t.xml="application/xml",t.text="text/plain"}(e||(e={}));class r extends Error{constructor(t){super(t),this.name="MagentrixError",Object.setPrototypeOf(this,r.prototype)}}class s extends Error{errors;constructor(t,e=[]){super(t),this.name="DatabaseError",this.errors=e,Object.setPrototypeOf(this,s.prototype)}getErrors(){return this.errors}hasErrors(){return this.errors.length>0}}class n{config;sessionInfo=null;restVersion="3.0";constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),token:t.token,refreshToken:t.refreshToken,antiForgeryToken:t.antiForgeryToken,onSessionExpired:t.onSessionExpired,onError:t.onError},t.token&&(this.sessionInfo={token:t.token,refresh_token:t.refreshToken||"",expires_in:0})}async createSession(t){const s=t||this.config.refreshToken;if(!s)throw new r("Refresh token is required to create a session");const n=`${this.config.baseUrl}/api/${this.restVersion}/token`,i={grant_type:"refresh_token",refresh_token:s},o=await fetch(n,{method:"POST",headers:{"Content-Type":e.json},body:JSON.stringify(i)});if(!o.ok){const t=await o.json();throw new r(t.message||"Failed to create session")}return this.sessionInfo=await o.json(),this.sessionInfo}async query(t){if(!t)throw new r("Query is required");const s={query:t,permissions:null},n=this.convertToEncodedKeyValuePairs(s);return this.postData("/iris/query",n,e.form_url_encoded)}async execute(s,n=null,i=t.post){if(!s)throw new r("Endpoint path is required");if(i===t.get&&n)throw new r("GET requests cannot have a request body");if(i===t.get)return this.getData(s);{const t=n?this.convertToEncodedKeyValuePairs(n):null;return this.postData(s,t,e.form_url_encoded)}}async retrieve(t){if(!t)throw new r("ID is required");const e={id:t,permissions:null},s=`/iris/retrieve?${this.convertToEncodedKeyValuePairs(e)}`;return this.getData(s)}async create(t,e){if(!t)throw new r("Entity name is required");if(!e)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${t}`;return this.postData(s,e)}async edit(t,e){if(!t)throw new r("Entity name is required");if(!e)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${t}`;return this.patchData(s,e)}async upsert(t,e){if(!t)throw new r("Entity name is required");if(!e)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${t}`;return this.putData(s,e)}async delete(t,e,s=!1){if(!e)throw new r("ID is required");if(!t)throw new r("Entity name is required");const n=`/api/${this.restVersion}/entity/${t}/${e}?isPermanent=${s}`;return this.deleteData(n)}async deleteMany(t,e,s=!1){if(!e||0===e.length)throw new r("IDs are required");if(!t)throw new r("Entity name is required");const n=`/api/${this.restVersion}/entity/${t}?isPermanent=${s}`;return this.deleteData(n,e)}convertToEncodedKeyValuePairs(t){let e="";for(const[r,s]of Object.entries(t)){let t;t=null==s?"":"object"==typeof s?JSON.stringify(s):s.toString(),e+=`${r}=${encodeURIComponent(t)}&`}return e.endsWith("&")&&(e=e.substring(0,e.length-1)),e}async getData(t){const e=this.getFullUrl(t),r=this.getRequestOptions(),s=await fetch(e,r);if(await this.handleAuthError(s))return this.getData(t);const n=await s.json();return s.ok||this.throwError(n),n}async postData(r,s,n=e.json){const i=this.getFullUrl(r),o={...this.getRequestOptions(t.post,n),body:n===e.json?JSON.stringify(s):s},a=await fetch(i,o);if(await this.handleAuthError(a))return this.postData(r,s,n);const h=await a.json();return a.ok||this.throwError(h),this.fillIdsOnCreate(s,h),s?.hasOwnProperty("ModifiedOn")&&(s.ModifiedOn=(new Date).toISOString().slice(0,-1)),h}async patchData(e,r){const s=this.getFullUrl(e),n={...this.getRequestOptions(t.patch),body:JSON.stringify(r)},i=await fetch(s,n);if(await this.handleAuthError(i))return this.patchData(e,r);const o=await i.json();return i.ok||this.throwError(o),r?.hasOwnProperty("ModifiedOn")&&(r.ModifiedOn=(new Date).toISOString().slice(0,-1)),o}async putData(e,r){const s=this.getFullUrl(e),n={...this.getRequestOptions(t.put),body:JSON.stringify(r)},i=await fetch(s,n);if(await this.handleAuthError(i))return this.putData(e,r);const o=await i.json();return i.ok||this.throwError(o),r.Id||this.fillIdsOnCreate(r,o),r?.hasOwnProperty("ModifiedOn")&&(r.ModifiedOn=(new Date).toISOString().slice(0,-1)),o}async deleteData(e,r=null){const s=this.getFullUrl(e),n={...this.getRequestOptions(t.delete),body:r?JSON.stringify(r):null},i=await fetch(s,n);if(await this.handleAuthError(i))return this.deleteData(e,r);const o=await i.json();return i.ok||this.throwError(o),o}getRequestOptions(r=t.get,s=e.json,n=e.json){const i={method:r,headers:{"Content-Type":s,"MAG-StrictMode":"false",Accept:n}};return r===t.post&&this.config.antiForgeryToken&&(i.headers.__RequestVerificationToken=this.config.antiForgeryToken),this.sessionInfo?.token&&(i.headers.Authorization=`Bearer ${this.sessionInfo.token}`),i}async handleAuthError(t){return!(401!==t.status&&403!==t.status||!this.config.onSessionExpired)&&(await this.config.onSessionExpired(),!0)}getFullUrl(t){return t.startsWith("http://")||t.startsWith("https://")?t:`${this.config.baseUrl}${t.startsWith("/")?t:"/"+t}`}fillIdsOnCreate(t,e){if(null==t)return;if(Array.isArray(t)){const r=t.length;if(0===r)return;for(let s=0;s<r;s++)void 0===t[s].Id&&e[s].Id&&(t[s].Id=e[s].Id)}else void 0===t.Id&&e.Id&&(t.Id=e.Id)}throwError(t){throw this.config.onError&&this.config.onError(t),"string"==typeof t?new r(t):t.hasOwnProperty("message")?new r(t.message):t.hasOwnProperty("errors")?new s("Database Error",t.errors):new r("Unknown error!")}}function i(){return{getInstance:function(t){return new n(t)}}}export{i as useMagentrixSdk};
2
- //# sourceMappingURL=useMagentrixSdk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useMagentrixSdk.js","sources":["../../src/helpers/enums.ts","../../src/helpers/errors.ts","../../src/helpers/MagentrixClient.ts","../../src/vue/useMagentrixSdk.ts"],"sourcesContent":["export enum RequestMethod {\n get = 'GET',\n post = 'POST',\n put = 'PUT',\n patch = 'PATCH',\n delete = 'DELETE'\n}\n\nexport enum ContentType {\n json = 'application/json',\n form_url_encoded = 'application/x-www-form-urlencoded',\n xml = 'application/xml',\n text = 'text/plain'\n}\n","export class MagentrixError extends Error {\r\n constructor(message: string) {\r\n super(message)\r\n this.name = 'MagentrixError'\r\n Object.setPrototypeOf(this, MagentrixError.prototype)\r\n }\r\n}\r\n\r\nexport class DatabaseError extends Error {\r\n errors: any[]\r\n\r\n constructor(message: string, errors: any[] = []) {\r\n super(message)\r\n this.name = 'DatabaseError'\r\n this.errors = errors\r\n Object.setPrototypeOf(this, DatabaseError.prototype)\r\n }\r\n\r\n getErrors(): any[] {\r\n return this.errors\r\n }\r\n\r\n hasErrors(): boolean {\r\n return this.errors.length > 0\r\n }\r\n}\r\n","import { RequestMethod, ContentType } from './enums'\r\nimport { MagentrixConfig, SessionInfo } from './interfaces'\r\nimport { MagentrixError, DatabaseError } from './errors'\r\n\r\nexport class MagentrixClient {\r\n private config: MagentrixConfig\r\n private sessionInfo: SessionInfo | null = null\r\n private restVersion = '3.0'\r\n\r\n constructor(config: MagentrixConfig) {\r\n this.config = {\r\n baseUrl: config.baseUrl.replace(/\\/$/, ''),\r\n token: config.token,\r\n refreshToken: config.refreshToken,\r\n antiForgeryToken: config.antiForgeryToken,\r\n onSessionExpired: config.onSessionExpired,\r\n onError: config.onError\r\n }\r\n\r\n if (config.token) {\r\n this.sessionInfo = {\r\n token: config.token,\r\n refresh_token: config.refreshToken || '',\r\n expires_in: 0\r\n }\r\n }\r\n }\r\n\r\n async createSession(refreshToken?: string): Promise<SessionInfo> {\r\n const token = refreshToken || this.config.refreshToken\r\n\r\n if (!token)\r\n throw new MagentrixError('Refresh token is required to create a session')\r\n\r\n const url = `${this.config.baseUrl}/api/${this.restVersion}/token`\r\n const body = { grant_type: 'refresh_token', refresh_token: token }\r\n \r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: { 'Content-Type': ContentType.json },\r\n body: JSON.stringify(body)\r\n })\r\n\r\n if (!response.ok) {\r\n const error = await response.json()\r\n throw new MagentrixError(error.message || 'Failed to create session')\r\n }\r\n\r\n this.sessionInfo = await response.json()\r\n return this.sessionInfo!\r\n }\r\n\r\n async query(query: string): Promise<any> {\r\n if (!query)\r\n throw new MagentrixError('Query is required')\r\n\r\n const path = '/iris/query'\r\n const model = { query, permissions: null }\r\n const data = this.convertToEncodedKeyValuePairs(model)\r\n \r\n return this.postData(path, data, ContentType.form_url_encoded)\r\n }\r\n\r\n async execute(path: string, model: any = null, method = RequestMethod.post): Promise<any> {\r\n if (!path)\r\n throw new MagentrixError('Endpoint path is required')\r\n\r\n if (method === RequestMethod.get && model)\r\n throw new MagentrixError('GET requests cannot have a request body')\r\n\r\n if (method === RequestMethod.get)\r\n return this.getData(path)\r\n else {\r\n const data = model ? this.convertToEncodedKeyValuePairs(model) : null\r\n return this.postData(path, data, ContentType.form_url_encoded)\r\n }\r\n }\r\n\r\n async retrieve(id: string): Promise<any> {\r\n if (!id)\r\n throw new MagentrixError('ID is required')\r\n\r\n const model = { id, permissions: null }\r\n const data = this.convertToEncodedKeyValuePairs(model)\r\n const path = `/iris/retrieve?${data}`\r\n \r\n return this.getData(path)\r\n }\r\n\r\n async create(entityName: string, data: any): Promise<any> {\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n if (!data)\r\n throw new MagentrixError('Data is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}`\r\n \r\n return this.postData(path, data)\r\n }\r\n\r\n async edit(entityName: string, data: any): Promise<any> {\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n if (!data)\r\n throw new MagentrixError('Data is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}`\r\n \r\n return this.patchData(path, data)\r\n }\r\n\r\n async upsert(entityName: string, data: any): Promise<any> {\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n if (!data)\r\n throw new MagentrixError('Data is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}`\r\n \r\n return this.putData(path, data)\r\n }\r\n\r\n async delete(entityName: string, id: string, permanent: boolean = false): Promise<any> {\r\n if (!id)\r\n throw new MagentrixError('ID is required')\r\n\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}/${id}?isPermanent=${permanent}`\r\n \r\n return this.deleteData(path)\r\n }\r\n\r\n async deleteMany(entityName: string, ids: string[], permanent: boolean = false): Promise<any> {\r\n if (!ids || ids.length === 0)\r\n throw new MagentrixError('IDs are required')\r\n\r\n if (!entityName)\r\n throw new MagentrixError('Entity name is required')\r\n\r\n const path = `/api/${this.restVersion}/entity/${entityName}?isPermanent=${permanent}`\r\n \r\n return this.deleteData(path, ids)\r\n }\r\n\r\n private convertToEncodedKeyValuePairs(obj: any): string {\r\n let result = ''\r\n\r\n for (const [key, value] of Object.entries(obj)) {\r\n let modifiedValue: string\r\n\r\n if (value === null || value === undefined)\r\n modifiedValue = ''\r\n else if (typeof value === 'object')\r\n modifiedValue = JSON.stringify(value)\r\n else\r\n modifiedValue = value.toString()\r\n\r\n result += `${key}=${encodeURIComponent(modifiedValue)}&`\r\n }\r\n\r\n if (result.endsWith('&'))\r\n result = result.substring(0, result.length - 1)\r\n\r\n return result\r\n }\r\n\r\n private async getData(path: string): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = this.getRequestOptions()\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.getData(path)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n return result\r\n }\r\n\r\n private async postData(path: string, data: any, contentType: ContentType = ContentType.json): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.post, contentType),\r\n body: contentType === ContentType.json ? JSON.stringify(data) : data\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.postData(path, data, contentType)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n this.fillIdsOnCreate(data, result)\r\n\r\n if (data?.hasOwnProperty('ModifiedOn'))\r\n data.ModifiedOn = new Date().toISOString().slice(0, -1)\r\n\r\n return result\r\n }\r\n\r\n private async patchData(path: string, data: any): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.patch),\r\n body: JSON.stringify(data)\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.patchData(path, data)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n if (data?.hasOwnProperty('ModifiedOn'))\r\n data.ModifiedOn = new Date().toISOString().slice(0, -1)\r\n\r\n return result\r\n }\r\n\r\n private async putData(path: string, data: any): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.put),\r\n body: JSON.stringify(data)\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.putData(path, data)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n if (!data.Id)\r\n this.fillIdsOnCreate(data, result)\r\n\r\n if (data?.hasOwnProperty('ModifiedOn'))\r\n data.ModifiedOn = new Date().toISOString().slice(0, -1)\r\n\r\n return result\r\n }\r\n\r\n private async deleteData(path: string, data: any = null): Promise<any> {\r\n const url = this.getFullUrl(path)\r\n const options = {\r\n ...this.getRequestOptions(RequestMethod.delete),\r\n body: data ? JSON.stringify(data) : null\r\n }\r\n const response = await fetch(url, options)\r\n\r\n if (await this.handleAuthError(response))\r\n return this.deleteData(path, data)\r\n\r\n const result = await response.json()\r\n\r\n if (!response.ok)\r\n this.throwError(result)\r\n\r\n return result\r\n }\r\n\r\n private getRequestOptions(\r\n method: RequestMethod = RequestMethod.get,\r\n contentType: ContentType = ContentType.json,\r\n acceptType: ContentType = ContentType.json\r\n ): RequestInit {\r\n const options: RequestInit = {\r\n method: method,\r\n headers: {\r\n 'Content-Type': contentType,\r\n 'MAG-StrictMode': 'false',\r\n 'Accept': acceptType\r\n }\r\n }\r\n\r\n if (method === RequestMethod.post && this.config.antiForgeryToken) {\r\n (options.headers as any).__RequestVerificationToken = this.config.antiForgeryToken\r\n }\r\n\r\n if (this.sessionInfo?.token) {\r\n (options.headers as any).Authorization = `Bearer ${this.sessionInfo.token}`\r\n }\r\n\r\n return options\r\n }\r\n\r\n private async handleAuthError(response: Response): Promise<boolean> {\r\n if (response.status === 401 || response.status === 403) {\r\n if (this.config.onSessionExpired) {\r\n await this.config.onSessionExpired()\r\n return true\r\n }\r\n }\r\n\r\n return false\r\n }\r\n\r\n private getFullUrl(path: string): string {\r\n if (path.startsWith('http://') || path.startsWith('https://'))\r\n return path\r\n\r\n return `${this.config.baseUrl}${path.startsWith('/') ? path : '/' + path}`\r\n }\r\n\r\n private fillIdsOnCreate(data: any | any[], result: any | any[]): void {\r\n if (data == null)\r\n return\r\n\r\n const isArray = Array.isArray(data)\r\n\r\n if (isArray) {\r\n const count = data.length\r\n\r\n if (count === 0)\r\n return\r\n\r\n for (let i = 0; i < count; i++) {\r\n if (data[i].Id === undefined && result[i].Id)\r\n data[i].Id = result[i].Id\r\n }\r\n } else {\r\n if (data.Id === undefined && result.Id)\r\n data.Id = result.Id\r\n }\r\n }\r\n\r\n private throwError(error: any): never {\r\n if (this.config.onError)\r\n this.config.onError(error)\r\n\r\n if (typeof error === 'string')\r\n throw new MagentrixError(error)\r\n else if (error.hasOwnProperty('message'))\r\n throw new MagentrixError(error.message)\r\n else if (error.hasOwnProperty('errors'))\r\n throw new DatabaseError('Database Error', error.errors)\r\n else\r\n throw new MagentrixError('Unknown error!')\r\n }\r\n}\r\n","import { MagentrixConfig } from \"../helpers/interfaces\";\r\nimport { MagentrixClient } from \"../helpers/MagentrixClient\";\r\n\r\nexport function useMagentrixSdk() {\r\n function getInstance(config: MagentrixConfig) {\r\n return new MagentrixClient(config)\r\n }\r\n\r\n return { getInstance };\r\n}\r\n"],"names":["RequestMethod","ContentType","MagentrixError","Error","constructor","message","super","this","name","Object","setPrototypeOf","prototype","DatabaseError","errors","getErrors","hasErrors","length","MagentrixClient","config","sessionInfo","restVersion","baseUrl","replace","token","refreshToken","antiForgeryToken","onSessionExpired","onError","refresh_token","expires_in","createSession","url","body","grant_type","response","fetch","method","headers","json","JSON","stringify","ok","error","query","model","permissions","data","convertToEncodedKeyValuePairs","postData","form_url_encoded","execute","path","post","get","getData","retrieve","id","create","entityName","edit","patchData","upsert","putData","permanent","deleteData","deleteMany","ids","obj","result","key","value","entries","modifiedValue","toString","encodeURIComponent","endsWith","substring","getFullUrl","options","getRequestOptions","handleAuthError","throwError","contentType","fillIdsOnCreate","hasOwnProperty","ModifiedOn","Date","toISOString","slice","patch","put","Id","delete","acceptType","Accept","__RequestVerificationToken","Authorization","status","startsWith","Array","isArray","count","i","undefined","useMagentrixSdk","getInstance"],"mappings":"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"}