@magentrix-corp/magentrix-sdk 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,7 +24,7 @@ npm install @magentrix-corp/magentrix-sdk
24
24
  ### JavaScript/TypeScript
25
25
 
26
26
  ```typescript
27
- import { MagentrixClient } from 'magentrix-sdk'
27
+ import { MagentrixClient } from '@magentrix-corp/magentrix-sdk'
28
28
 
29
29
  const client = new MagentrixClient({
30
30
  baseUrl: 'https://your-instance.magentrix.com',
@@ -56,7 +56,7 @@ console.log(record)
56
56
  ```vue
57
57
  <script setup>
58
58
  import { ref, onMounted } from 'vue'
59
- import { useMagentrixSdk } from 'magentrix-sdk/vue'
59
+ import { useMagentrixSdk } from '@magentrix-corp/magentrix-sdk/vue'
60
60
 
61
61
  const client = useMagentrixSdk({
62
62
  baseUrl: 'https://your-instance.magentrix.com',
@@ -313,7 +313,7 @@ await client.deleteMany('Contact', ['id-1', 'id-2', 'id-3'])
313
313
  Execute a custom API endpoint.
314
314
 
315
315
  ```typescript
316
- import { RequestMethod } from 'magentrix-sdk'
316
+ import { RequestMethod } from '@magentrix-corp/magentrix-sdk'
317
317
 
318
318
  // GET request
319
319
  const data = await client.execute('/custom/endpoint', null, RequestMethod.get)
@@ -345,7 +345,7 @@ The SDK provides two custom error classes:
345
345
  General SDK errors (authentication, validation, API errors).
346
346
 
347
347
  ```typescript
348
- import { MagentrixError } from 'magentrix-sdk'
348
+ import { MagentrixError } from '@magentrix-corp/magentrix-sdk'
349
349
 
350
350
  try {
351
351
  await client.createSession()
@@ -361,7 +361,7 @@ try {
361
361
  Database-specific errors with detailed error information.
362
362
 
363
363
  ```typescript
364
- import { DatabaseError } from 'magentrix-sdk'
364
+ import { DatabaseError } from '@magentrix-corp/magentrix-sdk'
365
365
 
366
366
  try {
367
367
  await client.create('Account', invalidData)
@@ -429,7 +429,7 @@ import {
429
429
  DatabaseError,
430
430
  RequestMethod,
431
431
  ContentType
432
- } from 'magentrix-sdk'
432
+ } from '@magentrix-corp/magentrix-sdk'
433
433
 
434
434
  const config: MagentrixConfig = {
435
435
  baseUrl: 'https://your-instance.magentrix.com',
@@ -493,7 +493,7 @@ The SDK provides a dedicated Vue 3 composable:
493
493
  ```vue
494
494
  <script setup>
495
495
  import { ref, onMounted } from 'vue'
496
- import { useMagentrixSdk } from 'magentrix-sdk/vue'
496
+ import { useMagentrixSdk } from '@magentrix-corp/magentrix-sdk/vue'
497
497
 
498
498
  const client = useMagentrixSdk({
499
499
  baseUrl: 'https://your-instance.magentrix.com',
@@ -543,7 +543,7 @@ onMounted(() => {
543
543
  ```vue
544
544
  <script setup>
545
545
  import { ref } from 'vue'
546
- import { useMagentrixSdk } from 'magentrix-sdk/vue'
546
+ import { useMagentrixSdk } from '@magentrix-corp/magentrix-sdk/vue'
547
547
 
548
548
  const client = useMagentrixSdk({
549
549
  baseUrl: 'https://your-instance.magentrix.com',
@@ -0,0 +1,2 @@
1
+ "use strict";var e,t;Object.defineProperty(exports,"__esModule",{value:!0}),exports.RequestMethod=void 0,(e=exports.RequestMethod||(exports.RequestMethod={})).get="GET",e.post="POST",e.put="PUT",e.patch="PATCH",e.delete="DELETE",exports.ContentType=void 0,(t=exports.ContentType||(exports.ContentType={})).json="application/json",t.form_url_encoded="application/x-www-form-urlencoded",t.xml="application/xml",t.text="text/plain";class s extends Error{constructor(e){super(e),this.name="MagentrixError",Object.setPrototypeOf(this,s.prototype)}}class r extends Error{errors;constructor(e,t=[]){super(e),this.name="DatabaseError",this.errors=t,Object.setPrototypeOf(this,r.prototype)}getErrors(){return this.errors}hasErrors(){return this.errors.length>0}}exports.DatabaseError=r,exports.MagentrixClient=class{config;sessionInfo=null;restVersion="3.0";constructor(e){this.config={baseUrl:e.baseUrl.replace(/\/$/,""),refreshToken:e.refreshToken,isDevMode:e.isDevMode,onSessionExpired:e.onSessionExpired,onError:e.onError}}async createSession(e){const t=e||this.config.refreshToken;if(!t)throw new s("Refresh token is required to create a session");const r=`${this.config.baseUrl}/api/${this.restVersion}/token`,i={grant_type:"refresh_token",refresh_token:t},o=await fetch(r,{method:"POST",headers:{"Content-Type":exports.ContentType.json},body:JSON.stringify(i)}),n=await o.json();if(!o.ok||!1===n.success){if(n.errors&&n.errors.length>0){const e=n.errors[0].message||"Failed to create session";throw new s(e)}throw new s(n.message||"Failed to create session")}if(!n.token||!n.validUntil)throw new s("Invalid session response: missing token or validUntil");const a=Date.parse(n.validUntil),h=Date.parse((new Date).toUTCString()),d=Math.floor((a-h)/1e3);return this.sessionInfo={token:n.token,expires_in:d},this.sessionInfo}async query(e){if(!e)throw new s("Query is required");const t={query:e,permissions:null},r=this.convertToEncodedKeyValuePairs(t);return this.postData("/iris/query",r,exports.ContentType.form_url_encoded)}async execute(e,t=null,r=exports.RequestMethod.post){if(!e)throw new s("Endpoint path is required");if(r===exports.RequestMethod.get&&t)throw new s("GET requests cannot have a request body");if(r===exports.RequestMethod.get)return this.getData(e);{const s=t?this.convertToEncodedKeyValuePairs(t):null;return this.postData(e,s,exports.ContentType.form_url_encoded)}}async retrieve(e){if(!e)throw new s("ID is required");const t={id:e,permissions:null},r=`/iris/retrieve?${this.convertToEncodedKeyValuePairs(t)}`;return this.getData(r)}async create(e,t){if(!e)throw new s("Entity name is required");if(!t)throw new s("Data is required");const r=`/api/${this.restVersion}/entity/${e}`;return this.postData(r,t)}async edit(e,t){if(!e)throw new s("Entity name is required");if(!t)throw new s("Data is required");const r=`/api/${this.restVersion}/entity/${e}`;return this.patchData(r,t)}async upsert(e,t){if(!e)throw new s("Entity name is required");if(!t)throw new s("Data is required");const r=`/api/${this.restVersion}/entity/${e}`;return this.putData(r,t)}async delete(e,t,r=!1){if(!t)throw new s("ID is required");if(!e)throw new s("Entity name is required");const i=`/api/${this.restVersion}/entity/${e}/${t}?isPermanent=${r}`;return this.deleteData(i)}async deleteMany(e,t,r=!1){if(!t||0===t.length)throw new s("IDs are required");if(!e)throw new s("Entity name is required");const i=`/api/${this.restVersion}/entity/${e}?isPermanent=${r}`;return this.deleteData(i,t)}convertToEncodedKeyValuePairs(e){let t="";for(const[s,r]of Object.entries(e)){let e;e=null==r?"":"object"==typeof r?JSON.stringify(r):r.toString(),t+=`${s}=${encodeURIComponent(e)}&`}return t.endsWith("&")&&(t=t.substring(0,t.length-1)),t}async getData(e){await this.ensureValidSession();const t=this.getFullUrl(e),s=this.getRequestOptions(),r=await fetch(t,s);if(await this.handleAuthError(r))return this.getData(e);const i=await r.json();return r.ok||this.throwError(i),i}async postData(e,t,s=exports.ContentType.json){await this.ensureValidSession();const r=this.getFullUrl(e),i={...this.getRequestOptions(exports.RequestMethod.post,s),body:s===exports.ContentType.json?JSON.stringify(t):t},o=await fetch(r,i);if(await this.handleAuthError(o))return this.postData(e,t,s);const n=await o.json();return o.ok||this.throwError(n),this.fillIdsOnCreate(t,n),t?.hasOwnProperty("ModifiedOn")&&(t.ModifiedOn=(new Date).toISOString().slice(0,-1)),n}async patchData(e,t){await this.ensureValidSession();const s=this.getFullUrl(e),r={...this.getRequestOptions(exports.RequestMethod.patch),body:JSON.stringify(t)},i=await fetch(s,r);if(await this.handleAuthError(i))return this.patchData(e,t);const o=await i.json();return i.ok||this.throwError(o),t?.hasOwnProperty("ModifiedOn")&&(t.ModifiedOn=(new Date).toISOString().slice(0,-1)),o}async putData(e,t){await this.ensureValidSession();const s=this.getFullUrl(e),r={...this.getRequestOptions(exports.RequestMethod.put),body:JSON.stringify(t)},i=await fetch(s,r);if(await this.handleAuthError(i))return this.putData(e,t);const o=await i.json();return i.ok||this.throwError(o),t.Id||this.fillIdsOnCreate(t,o),t?.hasOwnProperty("ModifiedOn")&&(t.ModifiedOn=(new Date).toISOString().slice(0,-1)),o}async deleteData(e,t=null){await this.ensureValidSession();const s=this.getFullUrl(e),r={...this.getRequestOptions(exports.RequestMethod.delete),body:t?JSON.stringify(t):null},i=await fetch(s,r);if(await this.handleAuthError(i))return this.deleteData(e,t);const o=await i.json();return i.ok||this.throwError(o),o}getRequestOptions(e=exports.RequestMethod.get,t=exports.ContentType.json,s=exports.ContentType.json){const r={method:e,headers:{"Content-Type":t,"MAG-StrictMode":"false",Accept:s}};return this.config.isDevMode&&this.sessionInfo?.token&&(r.headers.Authorization=`Bearer ${this.sessionInfo.token}`),r}async handleAuthError(e){return!(this.config.isDevMode||!this.isForbidden(e))||!(401!==e.status&&403!==e.status||!this.config.onSessionExpired)&&(await this.config.onSessionExpired(),!0)}getFullUrl(e){return e.startsWith("http://")||e.startsWith("https://")?e:`${this.config.baseUrl}${e.startsWith("/")?e:"/"+e}`}fillIdsOnCreate(e,t){if(null==e)return;if(Array.isArray(e)){const s=e.length;if(0===s)return;for(let r=0;r<s;r++)void 0===e[r].Id&&t[r].Id&&(e[r].Id=t[r].Id)}else void 0===e.Id&&t.Id&&(e.Id=t.Id)}throwError(e){throw this.config.onError&&this.config.onError(e),"string"==typeof e?new s(e):e.hasOwnProperty("message")?new s(e.message):e.hasOwnProperty("errors")?new r("Database Error",e.errors):new s("Unknown error!")}isForbidden(e){if(!window.top)return!1;if(!(e.ok&&e.redirected&&e.url.toLowerCase().includes("/user/login")))return!1;let t=this.config.baseUrl+"/user/login",s=window.top.location.pathname+window.top.location.search;return"/"==s&&(s=""),s&&(t+="?returnurl="+encodeURIComponent(s)),window.location.replace(t),!0}isValidSession(){return!this.config.isDevMode||!!this.sessionInfo&&this.sessionInfo.expires_in>30}async ensureValidSession(){if(this.config.isDevMode&&!this.isValidSession()){if(!this.config.refreshToken)throw new s("Session expired and no refresh token available");await this.createSession()}}},exports.MagentrixError=s;
2
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/helpers/enums.ts","../src/helpers/errors.ts","../src/helpers/MagentrixClient.ts"],"sourcesContent":["export enum RequestMethod {\r\n get = 'GET',\r\n post = 'POST',\r\n put = 'PUT',\r\n patch = 'PATCH',\r\n delete = 'DELETE'\r\n}\r\n\r\nexport enum ContentType {\r\n json = 'application/json',\r\n form_url_encoded = 'application/x-www-form-urlencoded',\r\n xml = 'application/xml',\r\n text = 'text/plain'\r\n}\r\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 refreshToken: config.refreshToken,\r\n isDevMode: config.isDevMode,\r\n onSessionExpired: config.onSessionExpired,\r\n onError: config.onError\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 const sessionData = await response.json()\r\n\r\n // Check if the response indicates failure\r\n if (!response.ok || sessionData.success === false) {\r\n if (sessionData.errors && sessionData.errors.length > 0) {\r\n const errorMessage = sessionData.errors[0].message || 'Failed to create session'\r\n throw new MagentrixError(errorMessage)\r\n }\r\n throw new MagentrixError(sessionData.message || 'Failed to create session')\r\n }\r\n\r\n // Validate that we have a valid token and validUntil\r\n if (!sessionData.token || !sessionData.validUntil) {\r\n throw new MagentrixError('Invalid session response: missing token or validUntil')\r\n }\r\n\r\n const validUntil = Date.parse(sessionData.validUntil)\r\n const now = Date.parse((new Date()).toUTCString())\r\n const expires_in = Math.floor((validUntil - now) / 1000)\r\n\r\n this.sessionInfo = {\r\n token: sessionData.token,\r\n expires_in: expires_in\r\n }\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 // Only add bearer token if in dev mode\r\n if (this.config.isDevMode && 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 not in dev mode, check for ASP.NET form authorization redirect\r\n if (!this.config.isDevMode) {\r\n if (this.isForbidden(response)) {\r\n return true\r\n }\r\n }\r\n\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 private isForbidden(response: any): boolean {\r\n if (!window.top)\r\n return false\r\n\r\n const result = response.ok && response.redirected && response.url.toLowerCase().includes('/user/login')\r\n\r\n if (!result)\r\n return false\r\n\r\n let url = this.config.baseUrl + '/user/login'\r\n let returnUrl = window.top.location.pathname + window.top.location.search\r\n\r\n if (returnUrl == '/')\r\n returnUrl = ''\r\n\r\n if (returnUrl)\r\n url += '?returnurl=' + encodeURIComponent(returnUrl)\r\n\r\n window.location.replace(url)\r\n\r\n return true\r\n }\r\n\r\n private isValidSession(): boolean {\r\n // If not in dev mode, always return true (no session validation needed)\r\n if (!this.config.isDevMode)\r\n return true\r\n\r\n if (!this.sessionInfo)\r\n return false\r\n\r\n return this.sessionInfo.expires_in > 30\r\n }\r\n\r\n private async ensureValidSession(): Promise<void> {\r\n // If in dev mode, always refresh the token\r\n if (this.config.isDevMode) { \r\n if (!this.isValidSession()) {\r\n if (!this.config.refreshToken)\r\n throw new MagentrixError('Session expired and no refresh token available')\r\n\r\n await this.createSession()\r\n }\r\n }\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","refreshToken","isDevMode","onSessionExpired","onError","createSession","token","url","body","grant_type","refresh_token","response","fetch","method","headers","json","JSON","stringify","sessionData","ok","success","errorMessage","validUntil","Date","parse","now","toUTCString","expires_in","Math","floor","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","ensureValidSession","getFullUrl","options","getRequestOptions","handleAuthError","throwError","contentType","fillIdsOnCreate","hasOwnProperty","ModifiedOn","toISOString","slice","patch","put","Id","delete","acceptType","Accept","Authorization","isForbidden","status","startsWith","Array","isArray","count","i","undefined","error","window","top","redirected","toLowerCase","includes","returnUrl","location","pathname","search","isValidSession"],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ var e,t;!function(e){e.get="GET",e.post="POST",e.put="PUT",e.patch="PATCH",e.delete="DELETE"}(e||(e={})),function(e){e.json="application/json",e.form_url_encoded="application/x-www-form-urlencoded",e.xml="application/xml",e.text="text/plain"}(t||(t={}));class r extends Error{constructor(e){super(e),this.name="MagentrixError",Object.setPrototypeOf(this,r.prototype)}}class s extends Error{errors;constructor(e,t=[]){super(e),this.name="DatabaseError",this.errors=t,Object.setPrototypeOf(this,s.prototype)}getErrors(){return this.errors}hasErrors(){return this.errors.length>0}}class i{config;sessionInfo=null;restVersion="3.0";constructor(e){this.config={baseUrl:e.baseUrl.replace(/\/$/,""),refreshToken:e.refreshToken,isDevMode:e.isDevMode,onSessionExpired:e.onSessionExpired,onError:e.onError}}async createSession(e){const s=e||this.config.refreshToken;if(!s)throw new r("Refresh token is required to create a session");const i=`${this.config.baseUrl}/api/${this.restVersion}/token`,n={grant_type:"refresh_token",refresh_token:s},o=await fetch(i,{method:"POST",headers:{"Content-Type":t.json},body:JSON.stringify(n)}),a=await o.json();if(!o.ok||!1===a.success){if(a.errors&&a.errors.length>0){const e=a.errors[0].message||"Failed to create session";throw new r(e)}throw new r(a.message||"Failed to create session")}if(!a.token||!a.validUntil)throw new r("Invalid session response: missing token or validUntil");const h=Date.parse(a.validUntil),d=Date.parse((new Date).toUTCString()),c=Math.floor((h-d)/1e3);return this.sessionInfo={token:a.token,expires_in:c},this.sessionInfo}async query(e){if(!e)throw new r("Query is required");const s={query:e,permissions:null},i=this.convertToEncodedKeyValuePairs(s);return this.postData("/iris/query",i,t.form_url_encoded)}async execute(s,i=null,n=e.post){if(!s)throw new r("Endpoint path is required");if(n===e.get&&i)throw new r("GET requests cannot have a request body");if(n===e.get)return this.getData(s);{const e=i?this.convertToEncodedKeyValuePairs(i):null;return this.postData(s,e,t.form_url_encoded)}}async retrieve(e){if(!e)throw new r("ID is required");const t={id:e,permissions:null},s=`/iris/retrieve?${this.convertToEncodedKeyValuePairs(t)}`;return this.getData(s)}async create(e,t){if(!e)throw new r("Entity name is required");if(!t)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${e}`;return this.postData(s,t)}async edit(e,t){if(!e)throw new r("Entity name is required");if(!t)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${e}`;return this.patchData(s,t)}async upsert(e,t){if(!e)throw new r("Entity name is required");if(!t)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${e}`;return this.putData(s,t)}async delete(e,t,s=!1){if(!t)throw new r("ID is required");if(!e)throw new r("Entity name is required");const i=`/api/${this.restVersion}/entity/${e}/${t}?isPermanent=${s}`;return this.deleteData(i)}async deleteMany(e,t,s=!1){if(!t||0===t.length)throw new r("IDs are required");if(!e)throw new r("Entity name is required");const i=`/api/${this.restVersion}/entity/${e}?isPermanent=${s}`;return this.deleteData(i,t)}convertToEncodedKeyValuePairs(e){let t="";for(const[r,s]of Object.entries(e)){let e;e=null==s?"":"object"==typeof s?JSON.stringify(s):s.toString(),t+=`${r}=${encodeURIComponent(e)}&`}return t.endsWith("&")&&(t=t.substring(0,t.length-1)),t}async getData(e){await this.ensureValidSession();const t=this.getFullUrl(e),r=this.getRequestOptions(),s=await fetch(t,r);if(await this.handleAuthError(s))return this.getData(e);const i=await s.json();return s.ok||this.throwError(i),i}async postData(r,s,i=t.json){await this.ensureValidSession();const n=this.getFullUrl(r),o={...this.getRequestOptions(e.post,i),body:i===t.json?JSON.stringify(s):s},a=await fetch(n,o);if(await this.handleAuthError(a))return this.postData(r,s,i);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(t,r){await this.ensureValidSession();const s=this.getFullUrl(t),i={...this.getRequestOptions(e.patch),body:JSON.stringify(r)},n=await fetch(s,i);if(await this.handleAuthError(n))return this.patchData(t,r);const o=await n.json();return n.ok||this.throwError(o),r?.hasOwnProperty("ModifiedOn")&&(r.ModifiedOn=(new Date).toISOString().slice(0,-1)),o}async putData(t,r){await this.ensureValidSession();const s=this.getFullUrl(t),i={...this.getRequestOptions(e.put),body:JSON.stringify(r)},n=await fetch(s,i);if(await this.handleAuthError(n))return this.putData(t,r);const o=await n.json();return n.ok||this.throwError(o),r.Id||this.fillIdsOnCreate(r,o),r?.hasOwnProperty("ModifiedOn")&&(r.ModifiedOn=(new Date).toISOString().slice(0,-1)),o}async deleteData(t,r=null){await this.ensureValidSession();const s=this.getFullUrl(t),i={...this.getRequestOptions(e.delete),body:r?JSON.stringify(r):null},n=await fetch(s,i);if(await this.handleAuthError(n))return this.deleteData(t,r);const o=await n.json();return n.ok||this.throwError(o),o}getRequestOptions(r=e.get,s=t.json,i=t.json){const n={method:r,headers:{"Content-Type":s,"MAG-StrictMode":"false",Accept:i}};return this.config.isDevMode&&this.sessionInfo?.token&&(n.headers.Authorization=`Bearer ${this.sessionInfo.token}`),n}async handleAuthError(e){return!(this.config.isDevMode||!this.isForbidden(e))||!(401!==e.status&&403!==e.status||!this.config.onSessionExpired)&&(await this.config.onSessionExpired(),!0)}getFullUrl(e){return e.startsWith("http://")||e.startsWith("https://")?e:`${this.config.baseUrl}${e.startsWith("/")?e:"/"+e}`}fillIdsOnCreate(e,t){if(null==e)return;if(Array.isArray(e)){const r=e.length;if(0===r)return;for(let s=0;s<r;s++)void 0===e[s].Id&&t[s].Id&&(e[s].Id=t[s].Id)}else void 0===e.Id&&t.Id&&(e.Id=t.Id)}throwError(e){throw this.config.onError&&this.config.onError(e),"string"==typeof e?new r(e):e.hasOwnProperty("message")?new r(e.message):e.hasOwnProperty("errors")?new s("Database Error",e.errors):new r("Unknown error!")}isForbidden(e){if(!window.top)return!1;if(!(e.ok&&e.redirected&&e.url.toLowerCase().includes("/user/login")))return!1;let t=this.config.baseUrl+"/user/login",r=window.top.location.pathname+window.top.location.search;return"/"==r&&(r=""),r&&(t+="?returnurl="+encodeURIComponent(r)),window.location.replace(t),!0}isValidSession(){return!this.config.isDevMode||!!this.sessionInfo&&this.sessionInfo.expires_in>30}async ensureValidSession(){if(this.config.isDevMode&&!this.isValidSession()){if(!this.config.refreshToken)throw new r("Session expired and no refresh token available");await this.createSession()}}}export{t as ContentType,s as DatabaseError,i as MagentrixClient,r as MagentrixError,e as RequestMethod};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/helpers/enums.ts","../src/helpers/errors.ts","../src/helpers/MagentrixClient.ts"],"sourcesContent":["export enum RequestMethod {\r\n get = 'GET',\r\n post = 'POST',\r\n put = 'PUT',\r\n patch = 'PATCH',\r\n delete = 'DELETE'\r\n}\r\n\r\nexport enum ContentType {\r\n json = 'application/json',\r\n form_url_encoded = 'application/x-www-form-urlencoded',\r\n xml = 'application/xml',\r\n text = 'text/plain'\r\n}\r\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 refreshToken: config.refreshToken,\r\n isDevMode: config.isDevMode,\r\n onSessionExpired: config.onSessionExpired,\r\n onError: config.onError\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 const sessionData = await response.json()\r\n\r\n // Check if the response indicates failure\r\n if (!response.ok || sessionData.success === false) {\r\n if (sessionData.errors && sessionData.errors.length > 0) {\r\n const errorMessage = sessionData.errors[0].message || 'Failed to create session'\r\n throw new MagentrixError(errorMessage)\r\n }\r\n throw new MagentrixError(sessionData.message || 'Failed to create session')\r\n }\r\n\r\n // Validate that we have a valid token and validUntil\r\n if (!sessionData.token || !sessionData.validUntil) {\r\n throw new MagentrixError('Invalid session response: missing token or validUntil')\r\n }\r\n\r\n const validUntil = Date.parse(sessionData.validUntil)\r\n const now = Date.parse((new Date()).toUTCString())\r\n const expires_in = Math.floor((validUntil - now) / 1000)\r\n\r\n this.sessionInfo = {\r\n token: sessionData.token,\r\n expires_in: expires_in\r\n }\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 // Only add bearer token if in dev mode\r\n if (this.config.isDevMode && 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 not in dev mode, check for ASP.NET form authorization redirect\r\n if (!this.config.isDevMode) {\r\n if (this.isForbidden(response)) {\r\n return true\r\n }\r\n }\r\n\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 private isForbidden(response: any): boolean {\r\n if (!window.top)\r\n return false\r\n\r\n const result = response.ok && response.redirected && response.url.toLowerCase().includes('/user/login')\r\n\r\n if (!result)\r\n return false\r\n\r\n let url = this.config.baseUrl + '/user/login'\r\n let returnUrl = window.top.location.pathname + window.top.location.search\r\n\r\n if (returnUrl == '/')\r\n returnUrl = ''\r\n\r\n if (returnUrl)\r\n url += '?returnurl=' + encodeURIComponent(returnUrl)\r\n\r\n window.location.replace(url)\r\n\r\n return true\r\n }\r\n\r\n private isValidSession(): boolean {\r\n // If not in dev mode, always return true (no session validation needed)\r\n if (!this.config.isDevMode)\r\n return true\r\n\r\n if (!this.sessionInfo)\r\n return false\r\n\r\n return this.sessionInfo.expires_in > 30\r\n }\r\n\r\n private async ensureValidSession(): Promise<void> {\r\n // If in dev mode, always refresh the token\r\n if (this.config.isDevMode) { \r\n if (!this.isValidSession()) {\r\n if (!this.config.refreshToken)\r\n throw new MagentrixError('Session expired and no refresh token available')\r\n\r\n await this.createSession()\r\n }\r\n }\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","refreshToken","isDevMode","onSessionExpired","onError","createSession","token","url","body","grant_type","refresh_token","response","fetch","method","headers","json","JSON","stringify","sessionData","ok","success","errorMessage","validUntil","Date","parse","now","toUTCString","expires_in","Math","floor","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","ensureValidSession","getFullUrl","options","getRequestOptions","handleAuthError","throwError","contentType","fillIdsOnCreate","hasOwnProperty","ModifiedOn","toISOString","slice","patch","put","Id","delete","acceptType","Accept","Authorization","isForbidden","status","startsWith","Array","isArray","count","i","undefined","error","window","top","redirected","toLowerCase","includes","returnUrl","location","pathname","search","isValidSession"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ var e,t;!function(e){e.get="GET",e.post="POST",e.put="PUT",e.patch="PATCH",e.delete="DELETE"}(e||(e={})),function(e){e.json="application/json",e.form_url_encoded="application/x-www-form-urlencoded",e.xml="application/xml",e.text="text/plain"}(t||(t={}));class r extends Error{constructor(e){super(e),this.name="MagentrixError",Object.setPrototypeOf(this,r.prototype)}}class s extends Error{errors;constructor(e,t=[]){super(e),this.name="DatabaseError",this.errors=t,Object.setPrototypeOf(this,s.prototype)}getErrors(){return this.errors}hasErrors(){return this.errors.length>0}}class i{config;sessionInfo=null;restVersion="3.0";constructor(e){this.config={baseUrl:e.baseUrl.replace(/\/$/,""),refreshToken:e.refreshToken,isDevMode:e.isDevMode,onSessionExpired:e.onSessionExpired,onError:e.onError}}async createSession(e){const s=e||this.config.refreshToken;if(!s)throw new r("Refresh token is required to create a session");const i=`${this.config.baseUrl}/api/${this.restVersion}/token`,n={grant_type:"refresh_token",refresh_token:s},o=await fetch(i,{method:"POST",headers:{"Content-Type":t.json},body:JSON.stringify(n)}),a=await o.json();if(!o.ok||!1===a.success){if(a.errors&&a.errors.length>0){const e=a.errors[0].message||"Failed to create session";throw new r(e)}throw new r(a.message||"Failed to create session")}if(!a.token||!a.validUntil)throw new r("Invalid session response: missing token or validUntil");const h=Date.parse(a.validUntil),d=Date.parse((new Date).toUTCString()),c=Math.floor((h-d)/1e3);return this.sessionInfo={token:a.token,expires_in:c},this.sessionInfo}async query(e){if(!e)throw new r("Query is required");const s={query:e,permissions:null},i=this.convertToEncodedKeyValuePairs(s);return this.postData("/iris/query",i,t.form_url_encoded)}async execute(s,i=null,n=e.post){if(!s)throw new r("Endpoint path is required");if(n===e.get&&i)throw new r("GET requests cannot have a request body");if(n===e.get)return this.getData(s);{const e=i?this.convertToEncodedKeyValuePairs(i):null;return this.postData(s,e,t.form_url_encoded)}}async retrieve(e){if(!e)throw new r("ID is required");const t={id:e,permissions:null},s=`/iris/retrieve?${this.convertToEncodedKeyValuePairs(t)}`;return this.getData(s)}async create(e,t){if(!e)throw new r("Entity name is required");if(!t)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${e}`;return this.postData(s,t)}async edit(e,t){if(!e)throw new r("Entity name is required");if(!t)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${e}`;return this.patchData(s,t)}async upsert(e,t){if(!e)throw new r("Entity name is required");if(!t)throw new r("Data is required");const s=`/api/${this.restVersion}/entity/${e}`;return this.putData(s,t)}async delete(e,t,s=!1){if(!t)throw new r("ID is required");if(!e)throw new r("Entity name is required");const i=`/api/${this.restVersion}/entity/${e}/${t}?isPermanent=${s}`;return this.deleteData(i)}async deleteMany(e,t,s=!1){if(!t||0===t.length)throw new r("IDs are required");if(!e)throw new r("Entity name is required");const i=`/api/${this.restVersion}/entity/${e}?isPermanent=${s}`;return this.deleteData(i,t)}convertToEncodedKeyValuePairs(e){let t="";for(const[r,s]of Object.entries(e)){let e;e=null==s?"":"object"==typeof s?JSON.stringify(s):s.toString(),t+=`${r}=${encodeURIComponent(e)}&`}return t.endsWith("&")&&(t=t.substring(0,t.length-1)),t}async getData(e){await this.ensureValidSession();const t=this.getFullUrl(e),r=this.getRequestOptions(),s=await fetch(t,r);if(await this.handleAuthError(s))return this.getData(e);const i=await s.json();return s.ok||this.throwError(i),i}async postData(r,s,i=t.json){await this.ensureValidSession();const n=this.getFullUrl(r),o={...this.getRequestOptions(e.post,i),body:i===t.json?JSON.stringify(s):s},a=await fetch(n,o);if(await this.handleAuthError(a))return this.postData(r,s,i);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(t,r){await this.ensureValidSession();const s=this.getFullUrl(t),i={...this.getRequestOptions(e.patch),body:JSON.stringify(r)},n=await fetch(s,i);if(await this.handleAuthError(n))return this.patchData(t,r);const o=await n.json();return n.ok||this.throwError(o),r?.hasOwnProperty("ModifiedOn")&&(r.ModifiedOn=(new Date).toISOString().slice(0,-1)),o}async putData(t,r){await this.ensureValidSession();const s=this.getFullUrl(t),i={...this.getRequestOptions(e.put),body:JSON.stringify(r)},n=await fetch(s,i);if(await this.handleAuthError(n))return this.putData(t,r);const o=await n.json();return n.ok||this.throwError(o),r.Id||this.fillIdsOnCreate(r,o),r?.hasOwnProperty("ModifiedOn")&&(r.ModifiedOn=(new Date).toISOString().slice(0,-1)),o}async deleteData(t,r=null){await this.ensureValidSession();const s=this.getFullUrl(t),i={...this.getRequestOptions(e.delete),body:r?JSON.stringify(r):null},n=await fetch(s,i);if(await this.handleAuthError(n))return this.deleteData(t,r);const o=await n.json();return n.ok||this.throwError(o),o}getRequestOptions(r=e.get,s=t.json,i=t.json){const n={method:r,headers:{"Content-Type":s,"MAG-StrictMode":"false",Accept:i}};return this.config.isDevMode&&this.sessionInfo?.token&&(n.headers.Authorization=`Bearer ${this.sessionInfo.token}`),n}async handleAuthError(e){return!(this.config.isDevMode||!this.isForbidden(e))||!(401!==e.status&&403!==e.status||!this.config.onSessionExpired)&&(await this.config.onSessionExpired(),!0)}getFullUrl(e){return e.startsWith("http://")||e.startsWith("https://")?e:`${this.config.baseUrl}${e.startsWith("/")?e:"/"+e}`}fillIdsOnCreate(e,t){if(null==e)return;if(Array.isArray(e)){const r=e.length;if(0===r)return;for(let s=0;s<r;s++)void 0===e[s].Id&&t[s].Id&&(e[s].Id=t[s].Id)}else void 0===e.Id&&t.Id&&(e.Id=t.Id)}throwError(e){throw this.config.onError&&this.config.onError(e),"string"==typeof e?new r(e):e.hasOwnProperty("message")?new r(e.message):e.hasOwnProperty("errors")?new s("Database Error",e.errors):new r("Unknown error!")}isForbidden(e){if(!window.top)return!1;if(!(e.ok&&e.redirected&&e.url.toLowerCase().includes("/user/login")))return!1;let t=this.config.baseUrl+"/user/login",r=window.top.location.pathname+window.top.location.search;return"/"==r&&(r=""),r&&(t+="?returnurl="+encodeURIComponent(r)),window.location.replace(t),!0}isValidSession(){return!this.config.isDevMode||!!this.sessionInfo&&this.sessionInfo.expires_in>30}async ensureValidSession(){if(this.config.isDevMode&&!this.isValidSession()){if(!this.config.refreshToken)throw new r("Session expired and no refresh token available");await this.createSession()}}}function n(){return{getInstance:function(e){return new i(e)}}}export{n as useMagentrixSdk};
2
+ //# sourceMappingURL=useMagentrixSdk.js.map
@@ -0,0 +1 @@
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 {\r\n get = 'GET',\r\n post = 'POST',\r\n put = 'PUT',\r\n patch = 'PATCH',\r\n delete = 'DELETE'\r\n}\r\n\r\nexport enum ContentType {\r\n json = 'application/json',\r\n form_url_encoded = 'application/x-www-form-urlencoded',\r\n xml = 'application/xml',\r\n text = 'text/plain'\r\n}\r\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 refreshToken: config.refreshToken,\r\n isDevMode: config.isDevMode,\r\n onSessionExpired: config.onSessionExpired,\r\n onError: config.onError\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 const sessionData = await response.json()\r\n\r\n // Check if the response indicates failure\r\n if (!response.ok || sessionData.success === false) {\r\n if (sessionData.errors && sessionData.errors.length > 0) {\r\n const errorMessage = sessionData.errors[0].message || 'Failed to create session'\r\n throw new MagentrixError(errorMessage)\r\n }\r\n throw new MagentrixError(sessionData.message || 'Failed to create session')\r\n }\r\n\r\n // Validate that we have a valid token and validUntil\r\n if (!sessionData.token || !sessionData.validUntil) {\r\n throw new MagentrixError('Invalid session response: missing token or validUntil')\r\n }\r\n\r\n const validUntil = Date.parse(sessionData.validUntil)\r\n const now = Date.parse((new Date()).toUTCString())\r\n const expires_in = Math.floor((validUntil - now) / 1000)\r\n\r\n this.sessionInfo = {\r\n token: sessionData.token,\r\n expires_in: expires_in\r\n }\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 await this.ensureValidSession()\r\n\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 // Only add bearer token if in dev mode\r\n if (this.config.isDevMode && 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 not in dev mode, check for ASP.NET form authorization redirect\r\n if (!this.config.isDevMode) {\r\n if (this.isForbidden(response)) {\r\n return true\r\n }\r\n }\r\n\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 private isForbidden(response: any): boolean {\r\n if (!window.top)\r\n return false\r\n\r\n const result = response.ok && response.redirected && response.url.toLowerCase().includes('/user/login')\r\n\r\n if (!result)\r\n return false\r\n\r\n let url = this.config.baseUrl + '/user/login'\r\n let returnUrl = window.top.location.pathname + window.top.location.search\r\n\r\n if (returnUrl == '/')\r\n returnUrl = ''\r\n\r\n if (returnUrl)\r\n url += '?returnurl=' + encodeURIComponent(returnUrl)\r\n\r\n window.location.replace(url)\r\n\r\n return true\r\n }\r\n\r\n private isValidSession(): boolean {\r\n // If not in dev mode, always return true (no session validation needed)\r\n if (!this.config.isDevMode)\r\n return true\r\n\r\n if (!this.sessionInfo)\r\n return false\r\n\r\n return this.sessionInfo.expires_in > 30\r\n }\r\n\r\n private async ensureValidSession(): Promise<void> {\r\n // If in dev mode, always refresh the token\r\n if (this.config.isDevMode) { \r\n if (!this.isValidSession()) {\r\n if (!this.config.refreshToken)\r\n throw new MagentrixError('Session expired and no refresh token available')\r\n\r\n await this.createSession()\r\n }\r\n }\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","refreshToken","isDevMode","onSessionExpired","onError","createSession","token","url","body","grant_type","refresh_token","response","fetch","method","headers","json","JSON","stringify","sessionData","ok","success","errorMessage","validUntil","Date","parse","now","toUTCString","expires_in","Math","floor","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","ensureValidSession","getFullUrl","options","getRequestOptions","handleAuthError","throwError","contentType","fillIdsOnCreate","hasOwnProperty","ModifiedOn","toISOString","slice","patch","put","Id","delete","acceptType","Accept","Authorization","isForbidden","status","startsWith","Array","isArray","count","i","undefined","error","window","top","redirected","toLowerCase","includes","returnUrl","location","pathname","search","isValidSession","useMagentrixSdk","getInstance"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magentrix-corp/magentrix-sdk",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "TypeScript SDK for Magentrix APIs with dual authentication modes, automatic session management, CRUD operations, and Vue 3 integration",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.js",