@magentrix-corp/magentrix-sdk 1.0.1 → 1.0.3
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 +626 -141
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/vue/useMagentrixSdk.js +1 -1
- package/dist/vue/useMagentrixSdk.js.map +1 -1
- package/package.json +54 -39
package/README.md
CHANGED
|
@@ -1,92 +1,57 @@
|
|
|
1
1
|
# Magentrix SDK for JavaScript
|
|
2
2
|
|
|
3
|
-
A
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/magentrix-sdk)
|
|
6
|
-
[](https://opensource.org/licenses/MIT)
|
|
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.
|
|
7
4
|
|
|
8
5
|
## Features
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- ✅ **
|
|
13
|
-
- ✅ **
|
|
14
|
-
- ✅ **
|
|
15
|
-
- ✅ **
|
|
16
|
-
- ✅ **
|
|
17
|
-
- ✅ **
|
|
18
|
-
- ✅ **IRIS data extensions** - Support for metadata and permissions
|
|
19
|
-
|
|
20
|
-
### Developer Experience
|
|
21
|
-
|
|
22
|
-
- ✅ **TypeScript-first** - Full type definitions for enhanced IDE support
|
|
23
|
-
- ✅ **Promise-based API** - Modern async/await syntax
|
|
24
|
-
- ✅ **Vue.js 3 plugin** - Seamless integration with Vue.js applications
|
|
25
|
-
- ✅ **Composable pattern** - Vue composables for reactive data management
|
|
26
|
-
- ✅ **Comprehensive error handling** - Robust error handling with custom callbacks
|
|
27
|
-
- ✅ **Zero external dependencies** - Only uses native Fetch API
|
|
28
|
-
|
|
29
|
-
### Package Quality
|
|
30
|
-
|
|
31
|
-
- ✅ **Modern build system** - Built with Rollup for optimal bundling
|
|
32
|
-
- ✅ **Multiple module formats** - CommonJS and ES Module outputs
|
|
33
|
-
- ✅ **Tree-shakeable** - Import only what you need
|
|
34
|
-
- ✅ **Source maps included** - Easy debugging in development
|
|
35
|
-
- ✅ **Full documentation** - Complete examples and API reference
|
|
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
|
|
36
15
|
|
|
37
16
|
## Installation
|
|
38
17
|
|
|
39
18
|
```bash
|
|
40
|
-
npm install magentrix-sdk
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
or
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
yarn add magentrix-sdk
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
or
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
pnpm add magentrix-sdk
|
|
19
|
+
npm install @magentrix-corp/magentrix-sdk
|
|
53
20
|
```
|
|
54
21
|
|
|
55
22
|
## Quick Start
|
|
56
23
|
|
|
57
|
-
###
|
|
24
|
+
### JavaScript/TypeScript
|
|
58
25
|
|
|
59
|
-
```
|
|
26
|
+
```typescript
|
|
60
27
|
import { MagentrixClient } from 'magentrix-sdk'
|
|
61
28
|
|
|
62
29
|
const client = new MagentrixClient({
|
|
63
|
-
baseUrl: '
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// Handle session expiration
|
|
69
|
-
console.log('Session expired, redirecting to login...')
|
|
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!')
|
|
70
35
|
},
|
|
71
36
|
onError: (error) => {
|
|
72
|
-
// Handle errors globally
|
|
73
37
|
console.error('API Error:', error)
|
|
74
38
|
}
|
|
75
39
|
})
|
|
76
40
|
|
|
77
|
-
// Create a session
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
console.log('Session Token:', sessionInfo.token)
|
|
41
|
+
// Create a session
|
|
42
|
+
const session = await client.createSession()
|
|
43
|
+
console.log('Token:', session.token)
|
|
81
44
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
45
|
+
// Query data
|
|
46
|
+
const results = await client.query('SELECT Id, Name FROM Account')
|
|
47
|
+
console.log(results)
|
|
85
48
|
|
|
86
|
-
|
|
49
|
+
// Retrieve by ID
|
|
50
|
+
const record = await client.retrieve('account-id-123')
|
|
51
|
+
console.log(record)
|
|
87
52
|
```
|
|
88
53
|
|
|
89
|
-
### Vue
|
|
54
|
+
### Vue 3
|
|
90
55
|
|
|
91
56
|
```vue
|
|
92
57
|
<script setup>
|
|
@@ -94,143 +59,663 @@ import { ref, onMounted } from 'vue'
|
|
|
94
59
|
import { useMagentrixSdk } from 'magentrix-sdk/vue'
|
|
95
60
|
|
|
96
61
|
const client = useMagentrixSdk({
|
|
97
|
-
baseUrl: 'https://your-
|
|
98
|
-
token: '',
|
|
62
|
+
baseUrl: 'https://your-instance.magentrix.com',
|
|
99
63
|
refreshToken: 'your-refresh-token',
|
|
100
|
-
|
|
101
|
-
onSessionExpired: () => {
|
|
102
|
-
// Handle session expiration
|
|
103
|
-
console.log('Session expired')
|
|
104
|
-
},
|
|
64
|
+
isDevMode: true,
|
|
105
65
|
onError: (error) => {
|
|
106
|
-
|
|
107
|
-
console.error('Error:', error)
|
|
66
|
+
console.error('API Error:', error)
|
|
108
67
|
}
|
|
109
68
|
})
|
|
110
69
|
|
|
111
|
-
const
|
|
70
|
+
const account = ref(null)
|
|
112
71
|
|
|
113
72
|
onMounted(async () => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const data = await client.retrieve('xyz')
|
|
118
|
-
console.log('Retrieved Data:', data)
|
|
119
|
-
model.value = data
|
|
73
|
+
await client.createSession()
|
|
74
|
+
account.value = await client.retrieve('account-id-123')
|
|
120
75
|
})
|
|
121
76
|
</script>
|
|
122
77
|
|
|
123
78
|
<template>
|
|
124
|
-
<div>
|
|
125
|
-
<
|
|
79
|
+
<div v-if="account">
|
|
80
|
+
<h1>{{ account.Name }}</h1>
|
|
81
|
+
<p>ID: {{ account.Id }}</p>
|
|
126
82
|
</div>
|
|
127
83
|
</template>
|
|
128
84
|
```
|
|
129
85
|
|
|
130
|
-
##
|
|
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
|
+
```
|
|
131
137
|
|
|
132
|
-
|
|
138
|
+
## API Reference
|
|
133
139
|
|
|
134
|
-
|
|
135
|
-
|--------|------|----------|-------------|
|
|
136
|
-
| `baseUrl` | `string` | Yes | Your Magentrix portal domain |
|
|
137
|
-
| `token` | `string` | No | Initial authentication token |
|
|
138
|
-
| `refreshToken` | `string` | No | Token used for refreshing sessions |
|
|
139
|
-
| `antiForgeryToken` | `string` | No | Anti-forgery token for security |
|
|
140
|
-
| `onSessionExpired` | `() => Promise<void> \| void` | No | Callback when session expires |
|
|
141
|
-
| `onError` | `(error: any) => void` | No | Global error handler |
|
|
140
|
+
### Session Management
|
|
142
141
|
|
|
143
|
-
|
|
142
|
+
#### `createSession(refreshToken?: string): Promise<SessionInfo>`
|
|
144
143
|
|
|
145
|
-
|
|
146
|
-
Creates a new session and returns session information.
|
|
144
|
+
Creates a new session using the refresh token.
|
|
147
145
|
|
|
148
|
-
```
|
|
149
|
-
const
|
|
150
|
-
console.log(
|
|
146
|
+
```typescript
|
|
147
|
+
const session = await client.createSession()
|
|
148
|
+
console.log(session.token) // Bearer token
|
|
149
|
+
console.log(session.expires_in) // Seconds until expiration
|
|
151
150
|
```
|
|
152
151
|
|
|
153
|
-
|
|
154
|
-
|
|
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
|
+
|
|
155
159
|
|
|
156
|
-
|
|
157
|
-
|
|
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)
|
|
158
169
|
```
|
|
159
170
|
|
|
160
|
-
|
|
161
|
-
|
|
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>`
|
|
162
181
|
|
|
163
|
-
|
|
164
|
-
|
|
182
|
+
Retrieve a single record by ID.
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
const account = await client.retrieve('account-id-123')
|
|
186
|
+
console.log(account.Name)
|
|
165
187
|
```
|
|
166
188
|
|
|
167
|
-
|
|
189
|
+
**Parameters**:
|
|
190
|
+
- `id`: Record ID to retrieve
|
|
191
|
+
|
|
192
|
+
**Returns**: Record object
|
|
193
|
+
|
|
194
|
+
**Throws**: `MagentrixError` if ID is not provided
|
|
195
|
+
|
|
196
|
+
---
|
|
168
197
|
|
|
169
198
|
### CRUD Operations
|
|
170
199
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
+
}
|
|
176
394
|
})
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## Advanced Usage
|
|
401
|
+
|
|
402
|
+
### Session Expiration Handling
|
|
177
403
|
|
|
178
|
-
|
|
179
|
-
const record = await client.retrieve('record-id')
|
|
404
|
+
Handle session expiration gracefully:
|
|
180
405
|
|
|
181
|
-
|
|
182
|
-
const
|
|
183
|
-
|
|
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
|
+
}
|
|
184
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
|
+
```
|
|
185
465
|
|
|
186
|
-
|
|
187
|
-
|
|
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
|
+
)
|
|
188
483
|
```
|
|
189
484
|
|
|
190
|
-
|
|
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
|
+
})
|
|
191
503
|
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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()
|
|
197
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>
|
|
198
592
|
```
|
|
199
593
|
|
|
200
|
-
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## Best Practices
|
|
201
597
|
|
|
202
|
-
|
|
598
|
+
### 1. Environment-Specific Configuration
|
|
599
|
+
|
|
600
|
+
Use environment variables for configuration:
|
|
203
601
|
|
|
204
602
|
```typescript
|
|
205
|
-
|
|
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
|
+
```
|
|
206
609
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
|
210
644
|
})
|
|
211
645
|
|
|
212
|
-
|
|
646
|
+
// Initialize session
|
|
647
|
+
await client.createSession()
|
|
648
|
+
|
|
649
|
+
// Export for use throughout the app
|
|
650
|
+
export { client }
|
|
213
651
|
```
|
|
214
652
|
|
|
215
|
-
|
|
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
|
+
```
|
|
216
667
|
|
|
217
|
-
|
|
668
|
+
---
|
|
218
669
|
|
|
219
|
-
|
|
220
|
-
- Firefox (latest)
|
|
221
|
-
- Safari (latest)
|
|
222
|
-
- Edge (latest)
|
|
670
|
+
## Troubleshooting
|
|
223
671
|
|
|
224
|
-
|
|
672
|
+
### Common Issues
|
|
225
673
|
|
|
226
|
-
|
|
674
|
+
**Issue**: `Session expired and no refresh token available`
|
|
227
675
|
|
|
228
|
-
|
|
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
|
+
---
|
|
229
699
|
|
|
230
700
|
## License
|
|
231
701
|
|
|
232
|
-
|
|
702
|
+
Proprietary
|
|
233
703
|
|
|
234
704
|
## Support
|
|
235
705
|
|
|
236
|
-
For issues
|
|
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
|