@qelos/sdk 3.8.1 → 3.8.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.
@@ -9,6 +9,7 @@ import QlAdminWorkspaces from './workspaces';
9
9
  import QlManageBlueprints from './manage-blueprints';
10
10
  import { QlRoles } from './roles';
11
11
  import QlIntegrationSources from './integration-sources';
12
+ import QlManagePlugins from './manage-plugins';
12
13
  export default class QelosAdministratorSDK<T = any> extends QelosSDK {
13
14
  users: QlUsers<T>;
14
15
  manageLayouts: QlManageLayouts;
@@ -19,6 +20,7 @@ export default class QelosAdministratorSDK<T = any> extends QelosSDK {
19
20
  adminWorkspaces: QlAdminWorkspaces;
20
21
  roles: QlRoles;
21
22
  integrationSources: QlIntegrationSources;
23
+ managePlugins: QlManagePlugins;
22
24
  constructor(options: QelosSDKOptions);
23
25
  impersonateUser(userId: string, workspaceId?: string): void;
24
26
  clearImpersonation(): void;
@@ -8,6 +8,7 @@ import QlAdminWorkspaces from './workspaces';
8
8
  import QlManageBlueprints from './manage-blueprints';
9
9
  import { QlRoles } from './roles';
10
10
  import QlIntegrationSources from './integration-sources';
11
+ import QlManagePlugins from './manage-plugins';
11
12
  export default class QelosAdministratorSDK extends QelosSDK {
12
13
  users;
13
14
  manageLayouts;
@@ -18,6 +19,7 @@ export default class QelosAdministratorSDK extends QelosSDK {
18
19
  adminWorkspaces;
19
20
  roles;
20
21
  integrationSources;
22
+ managePlugins;
21
23
  constructor(options) {
22
24
  super(options);
23
25
  this.users = new QlUsers(options);
@@ -29,6 +31,7 @@ export default class QelosAdministratorSDK extends QelosSDK {
29
31
  this.adminWorkspaces = new QlAdminWorkspaces(options);
30
32
  this.roles = new QlRoles(options);
31
33
  this.integrationSources = new QlIntegrationSources(options);
34
+ this.managePlugins = new QlManagePlugins(options);
32
35
  if (!options.extraQueryParams) {
33
36
  options.extraQueryParams = () => ({
34
37
  bypassAdmin: 'true'
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/administrator/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,eAAe,MAAM,kBAAkB,CAAC;AAC/C,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,sBAAsB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,iBAAiB,MAAM,cAAc,CAAC;AAC7C,OAAO,kBAAkB,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,oBAAoB,MAAM,uBAAuB,CAAC;AAEzD,MAAM,CAAC,OAAO,OAAO,qBAA+B,SAAQ,QAAQ;IAClE,KAAK,CAAa;IAClB,aAAa,CAAkB;IAC/B,oBAAoB,CAAyB;IAC7C,gBAAgB,CAAqB;IACrC,MAAM,CAAW;IACjB,MAAM,CAAW;IACjB,eAAe,CAAoB;IACnC,KAAK,CAAU;IACf,kBAAkB,CAAuB;IAEzC,YAAY,OAAwB;QAClC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,IAAI,OAAO,CAAI,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,aAAa,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,oBAAoB,GAAG,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAChE,IAAI,CAAC,gBAAgB,GAAG,IAAI,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,eAAe,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,kBAAkB,GAAG,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAE5D,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE;YAC7B,OAAO,CAAC,gBAAgB,GAAG,GAAG,EAAE,CAAC,CAAC;gBAChC,WAAW,EAAE,MAAM;aACpB,CAAC,CAAA;SACH;IACH,CAAC;IAED,eAAe,CAAC,MAAc,EAAE,WAAoB;QAClD,IAAI,CAAC,eAAe,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACnD,IAAI,WAAW,EAAE;YACf,IAAI,CAAC,eAAe,CAAC,yBAAyB,EAAE,WAAW,CAAC,CAAC;SAC9D;IACH,CAAC;IAED,kBAAkB;QAChB,IAAI,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;QAC9C,IAAI,CAAC,kBAAkB,CAAC,yBAAyB,CAAC,CAAC;IACrD,CAAC;CACF"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/administrator/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,eAAe,MAAM,kBAAkB,CAAC;AAC/C,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,sBAAsB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,iBAAiB,MAAM,cAAc,CAAC;AAC7C,OAAO,kBAAkB,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,oBAAoB,MAAM,uBAAuB,CAAC;AACzD,OAAO,eAAe,MAAM,kBAAkB,CAAC;AAE/C,MAAM,CAAC,OAAO,OAAO,qBAA+B,SAAQ,QAAQ;IAClE,KAAK,CAAa;IAClB,aAAa,CAAkB;IAC/B,oBAAoB,CAAyB;IAC7C,gBAAgB,CAAqB;IACrC,MAAM,CAAW;IACjB,MAAM,CAAW;IACjB,eAAe,CAAoB;IACnC,KAAK,CAAU;IACf,kBAAkB,CAAuB;IACzC,aAAa,CAAkB;IAE/B,YAAY,OAAwB;QAClC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,IAAI,OAAO,CAAI,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,aAAa,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,oBAAoB,GAAG,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAChE,IAAI,CAAC,gBAAgB,GAAG,IAAI,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,eAAe,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,kBAAkB,GAAG,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAC5D,IAAI,CAAC,aAAa,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;QAElD,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE;YAC7B,OAAO,CAAC,gBAAgB,GAAG,GAAG,EAAE,CAAC,CAAC;gBAChC,WAAW,EAAE,MAAM;aACpB,CAAC,CAAA;SACH;IACH,CAAC;IAED,eAAe,CAAC,MAAc,EAAE,WAAoB;QAClD,IAAI,CAAC,eAAe,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACnD,IAAI,WAAW,EAAE;YACf,IAAI,CAAC,eAAe,CAAC,yBAAyB,EAAE,WAAW,CAAC,CAAC;SAC9D;IACH,CAAC;IAED,kBAAkB;QAChB,IAAI,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;QAC9C,IAAI,CAAC,kBAAkB,CAAC,yBAAyB,CAAC,CAAC;IACrD,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ import BaseSDK from '../base-sdk';
2
+ import { QelosSDKOptions } from '../types';
3
+ import { IPlugin, IEventSubscriber, IMicroFrontend, IPluginCrud, IInjectable, INavbarGroup } from '@qelos/global-types';
4
+ type ServerManagedPluginFields = 'tenant' | 'user' | 'token' | 'auth' | '_id' | 'id' | 'createdAt' | 'updatedAt';
5
+ export type IPluginCreateParams = Omit<IPlugin, ServerManagedPluginFields | 'subscribedEvents' | 'microFrontends' | 'cruds' | 'injectables' | 'navBarGroups'> & {
6
+ subscribedEvents?: Partial<IEventSubscriber>[];
7
+ microFrontends?: Partial<IMicroFrontend>[];
8
+ cruds?: Partial<IPluginCrud>[];
9
+ injectables?: Partial<IInjectable>[];
10
+ navBarGroups?: Partial<INavbarGroup>[];
11
+ version?: string;
12
+ url?: string;
13
+ proxyUrl?: string;
14
+ };
15
+ export type IPluginUpdateParams = Partial<Omit<IPlugin, ServerManagedPluginFields>>;
16
+ export default class QlManagePlugins extends BaseSDK {
17
+ private relativePath;
18
+ constructor(options: QelosSDKOptions);
19
+ create(pluginData: IPluginCreateParams): Promise<IPlugin>;
20
+ update(pluginId: string, pluginData: IPluginUpdateParams): Promise<IPlugin>;
21
+ remove(pluginId: string): Promise<void>;
22
+ getList(): Promise<IPlugin[]>;
23
+ getById(pluginId: string): Promise<IPlugin>;
24
+ }
25
+ export {};
@@ -0,0 +1,33 @@
1
+ import BaseSDK from '../base-sdk';
2
+ export default class QlManagePlugins extends BaseSDK {
3
+ relativePath = '/api/plugins'; // Please confirm/adjust this path
4
+ constructor(options) {
5
+ super(options);
6
+ }
7
+ async create(pluginData) {
8
+ return this.callJsonApi(this.relativePath, {
9
+ method: 'POST',
10
+ headers: { 'content-type': 'application/json' },
11
+ body: JSON.stringify(pluginData),
12
+ });
13
+ }
14
+ async update(pluginId, pluginData) {
15
+ return this.callJsonApi(`${this.relativePath}/${pluginId}`, {
16
+ method: 'PUT',
17
+ headers: { 'content-type': 'application/json' },
18
+ body: JSON.stringify(pluginData),
19
+ });
20
+ }
21
+ async remove(pluginId) {
22
+ // callApi usually doesn't expect a JSON response, so no <void> generic needed for it.
23
+ // It will throw on non-2xx responses.
24
+ await this.callApi(`${this.relativePath}/${pluginId}`, { method: 'DELETE' });
25
+ }
26
+ async getList() {
27
+ return this.callJsonApi(this.relativePath);
28
+ }
29
+ async getById(pluginId) {
30
+ return this.callJsonApi(`${this.relativePath}/${pluginId}`);
31
+ }
32
+ }
33
+ //# sourceMappingURL=manage-plugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manage-plugins.js","sourceRoot":"","sources":["../../src/administrator/manage-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,aAAa,CAAC;AAqBlC,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,OAAO;IAC1C,YAAY,GAAG,cAAc,CAAC,CAAC,kCAAkC;IAEzE,YAAY,OAAwB;QAClC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,UAA+B;QAC1C,OAAO,IAAI,CAAC,WAAW,CAAU,IAAI,CAAC,YAAY,EAAE;YAClD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,UAA+B;QAC5D,OAAO,IAAI,CAAC,WAAW,CAAU,GAAG,IAAI,CAAC,YAAY,IAAI,QAAQ,EAAE,EAAE;YACnE,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAgB;QAC3B,sFAAsF;QACtF,sCAAsC;QACtC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,YAAY,IAAI,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,CAAC,WAAW,CAAY,IAAI,CAAC,YAAY,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAgB;QAC5B,OAAO,IAAI,CAAC,WAAW,CAAU,GAAG,IAAI,CAAC,YAAY,IAAI,QAAQ,EAAE,CAAC,CAAC;IACvE,CAAC;CACF"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import * as assert from 'node:assert/strict';
2
+ import { QlRoles } from '../roles';
3
+ const { describe, beforeEach, test } = require('node:test');
4
+ describe('QlRoles', () => {
5
+ let options;
6
+ beforeEach(() => {
7
+ // Initialize SDK with the mocked fetch function and mock authentication
8
+ options = {
9
+ appUrl: 'http://localhost:3000',
10
+ fetch: () => null,
11
+ extraHeaders: async () => ({}),
12
+ refreshToken: 'mock-refresh-token' // Ensure a mock refresh token is set
13
+ };
14
+ });
15
+ test('should instantiate the roles property', () => {
16
+ const rolesSdk = new QlRoles(options);
17
+ assert.ok(rolesSdk);
18
+ });
19
+ test('should fetch roles successfully', async () => {
20
+ // Mock fetch to return a valid JSON response
21
+ options.fetch = async () => {
22
+ const res = new Response(JSON.stringify(['admin', 'user', 'plugin']));
23
+ res.headers.set('Content-Type', 'application/json');
24
+ return res;
25
+ };
26
+ const rolesSdk = new QlRoles(options);
27
+ // Call the function and verify results
28
+ const roles = await rolesSdk.getExistingRoles();
29
+ assert.deepEqual(roles, ['admin', 'user', 'plugin']);
30
+ });
31
+ });
32
+ //# sourceMappingURL=roles.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles.test.js","sourceRoot":"","sources":["../../../src/administrator/tests/roles.test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;AAE3D,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,IAAI,OAAwB,CAAA;IAE5B,UAAU,CAAC,GAAG,EAAE;QACd,wEAAwE;QACxE,OAAO,GAAG;YACR,MAAM,EAAE,uBAAuB;YAC/B,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI;YACjB,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;YAC9B,YAAY,EAAE,oBAAoB,CAAC,qCAAqC;SACzE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uCAAuC,EAAE,GAAG,EAAE;QACjD,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QACjD,6CAA6C;QAC7C,OAAO,CAAC,KAAK,GAAG,KAAK,IAAI,EAAE;YACzB,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;YACrE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YACpD,OAAO,GAAG,CAAC;QACb,CAAC,CAAA;QAED,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;QAEtC,uCAAuC;QACvC,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,CAAC;QAChD,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -4,6 +4,9 @@ export default class BaseSDK {
4
4
  private qlOptions;
5
5
  constructor(qlOptions: QelosSDKOptions);
6
6
  callApi(relativeUrl: string, data?: RequestInit): Promise<Response>;
7
+ private handleFailedRefreshToken;
8
+ private getContentType;
9
+ private parseResponse;
7
10
  callJsonApi<T>(relativeUrl: string, data?: RequestInit): Promise<T>;
8
11
  getQueryParams(moreQuery?: Record<string, any>): string;
9
12
  }
package/dist/base-sdk.js CHANGED
@@ -1,48 +1,91 @@
1
+ const ERRORS = {
2
+ EXTRA_HEADERS: 'could not get extra headers',
3
+ FAILED_REFRESH_TOKEN: 'could not handle failed refresh token',
4
+ UNABLE_TO_REFRESH_TOKEN: 'could not able to refresh token'
5
+ };
1
6
  export default class BaseSDK {
2
7
  qlOptions;
3
8
  #appUrl;
4
9
  #fetch;
5
10
  constructor(qlOptions) {
6
11
  this.qlOptions = qlOptions;
7
- this.#appUrl = qlOptions.appUrl.endsWith('/') ? qlOptions.appUrl.slice(0, -1) : qlOptions.appUrl;
12
+ this.#appUrl = qlOptions.appUrl?.endsWith('/') ? qlOptions.appUrl.slice(0, -1) : qlOptions.appUrl;
8
13
  this.#fetch = qlOptions.fetch || globalThis.fetch;
9
14
  }
10
15
  async callApi(relativeUrl, data) {
11
16
  data = data || {};
12
17
  data.headers = data.headers || {};
13
- Object.assign(data.headers, await this.qlOptions.extraHeaders(relativeUrl));
18
+ if (this.qlOptions.extraHeaders) {
19
+ try {
20
+ const extraHeaders = await this.qlOptions.extraHeaders(relativeUrl);
21
+ Object.assign(data.headers, extraHeaders);
22
+ }
23
+ catch (e) {
24
+ throw new Error(ERRORS.EXTRA_HEADERS);
25
+ }
26
+ }
14
27
  return this.#fetch(this.#appUrl + relativeUrl, data);
15
28
  }
16
- callJsonApi(relativeUrl, data) {
17
- return this.callApi(relativeUrl, data).then(async (res) => {
29
+ async handleFailedRefreshToken() {
30
+ if (this.qlOptions.onFailedRefreshToken) {
31
+ try {
32
+ await this.qlOptions.onFailedRefreshToken();
33
+ }
34
+ catch (e) {
35
+ throw new Error(ERRORS.FAILED_REFRESH_TOKEN);
36
+ }
37
+ }
38
+ else {
39
+ throw new Error(ERRORS.UNABLE_TO_REFRESH_TOKEN);
40
+ }
41
+ }
42
+ getContentType(res) {
43
+ return res.headers.get('Content-Type') ||
44
+ res.headers.get('content-type') ||
45
+ res.headers.get('ContentType') ||
46
+ res.headers.get('contenttype') ||
47
+ res.headers.get('contentType') || 'text';
48
+ }
49
+ async parseResponse(res) {
50
+ const contentType = this.getContentType(res);
51
+ const isJson = contentType.includes('json');
52
+ const body = await (isJson ? res.json() : res.text());
53
+ if (!res.ok) {
54
+ throw (typeof body === 'string' ? new Error(body) : body);
55
+ }
56
+ return body;
57
+ }
58
+ async callJsonApi(relativeUrl, data) {
59
+ try {
60
+ let res = await this.callApi(relativeUrl, data);
61
+ // Handle token refresh if needed
18
62
  if (this.qlOptions.forceRefresh && res.status >= 400 && res.status < 500) {
19
- const headers = await this.qlOptions.extraHeaders(relativeUrl, true);
20
- if (!headers.authorization) {
21
- if (this.qlOptions.onFailedRefreshToken) {
22
- try {
23
- await this.qlOptions.onFailedRefreshToken();
24
- }
25
- catch (e) {
26
- throw new Error('could not handle failed refresh token');
27
- }
63
+ let headers = {};
64
+ if (this.qlOptions.extraHeaders) {
65
+ try {
66
+ headers = await this.qlOptions.extraHeaders(relativeUrl, true);
28
67
  }
29
- else {
30
- throw new Error('could not able to refresh token');
68
+ catch {
69
+ // Ignore error during refresh attempt
31
70
  }
32
71
  }
72
+ if (!headers?.authorization) {
73
+ await this.handleFailedRefreshToken();
74
+ }
33
75
  res = await this.callApi(relativeUrl, data);
34
76
  }
35
- const isJson = (res.headers.get('Content-Type') ||
36
- res.headers.get('content-type') ||
37
- res.headers.get('ContentType') ||
38
- res.headers.get('contenttype') ||
39
- res.headers.get('contentType') || 'text').includes('json');
40
- const body = await (isJson ? res.json() : res.text());
41
- if (!res.ok) {
42
- throw (typeof body === 'string' ? new Error(body) : body);
77
+ return this.parseResponse(res);
78
+ }
79
+ catch (err) {
80
+ // Type guard for Error objects
81
+ if (err instanceof Error && err.message === ERRORS.EXTRA_HEADERS) {
82
+ // Handle token refresh for EXTRA_HEADERS_ERROR
83
+ await this.handleFailedRefreshToken();
84
+ const res = await this.callApi(relativeUrl, data);
85
+ return this.parseResponse(res);
43
86
  }
44
- return body;
45
- });
87
+ throw err;
88
+ }
46
89
  }
47
90
  getQueryParams(moreQuery) {
48
91
  const qs = this.qlOptions.extraQueryParams ? { ...this.qlOptions.extraQueryParams(), ...(moreQuery || {}) } : moreQuery;
@@ -1 +1 @@
1
- {"version":3,"file":"base-sdk.js","sourceRoot":"","sources":["../src/base-sdk.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-sdk.js","sourceRoot":"","sources":["../src/base-sdk.ts"],"names":[],"mappings":"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"}
@@ -31,7 +31,7 @@ export default class QlWorkspaces extends BaseSDK {
31
31
  });
32
32
  }
33
33
  activate(workspaceId) {
34
- return this.callJsonApi(`${this.relativePath}/${workspaceId}`, {
34
+ return this.callJsonApi(`${this.relativePath}/${workspaceId}/activate`, {
35
35
  method: 'post',
36
36
  headers: { 'content-type': 'application/json' },
37
37
  });
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../src/workspaces.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,YAAY,CAAC;AA0BjC,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IACvC,YAAY,GAAG,iBAAiB,CAAC;IAEzC,YAAY,OAAwB;QAClC,KAAK,CAAC,OAAO,CAAC,CAAA;IAChB,CAAC;IAED,YAAY,CAAC,WAAmB;QAC9B,OAAO,IAAI,CAAC,WAAW,CAAa,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,EAAE,CAAC,CAAA;IAC5E,CAAC;IAED,UAAU,CAAC,WAAmB;QAC5B,OAAO,IAAI,CAAC,WAAW,CAAqB,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,UAAU,CAAC,CAAA;IAC5F,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,WAAW,CAAe,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,CAAC,WAAmB;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,EAAE,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAC,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,CAAC,WAAmB,EAAE,OAA4B;QACtD,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,EAAE,EACrC;YACE,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAC,cAAc,EAAE,kBAAkB,EAAC;YAC7C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CACF,CAAA;IACH,CAAC;IAED,MAAM,CAAC,SAAiD;QACtD,OAAO,IAAI,CAAC,WAAW,CAAa,IAAI,CAAC,YAAY,EAAE;YACrD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAC,cAAc,EAAE,kBAAkB,EAAC;YAC7C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;SAChC,CAAC,CAAA;IACJ,CAAC;IAED,QAAQ,CAAC,WAAmB;QAC1B,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,EAAE,EACrC;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAC,cAAc,EAAE,kBAAkB,EAAC;SAC9C,CACF,CAAA;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../src/workspaces.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,YAAY,CAAC;AA0BjC,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IACvC,YAAY,GAAG,iBAAiB,CAAC;IAEzC,YAAY,OAAwB;QAClC,KAAK,CAAC,OAAO,CAAC,CAAA;IAChB,CAAC;IAED,YAAY,CAAC,WAAmB;QAC9B,OAAO,IAAI,CAAC,WAAW,CAAa,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,EAAE,CAAC,CAAA;IAC5E,CAAC;IAED,UAAU,CAAC,WAAmB;QAC5B,OAAO,IAAI,CAAC,WAAW,CAAqB,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,UAAU,CAAC,CAAA;IAC5F,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,WAAW,CAAe,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,CAAC,WAAmB;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,EAAE,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAC,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,CAAC,WAAmB,EAAE,OAA4B;QACtD,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,EAAE,EACrC;YACE,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAC,cAAc,EAAE,kBAAkB,EAAC;YAC7C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CACF,CAAA;IACH,CAAC;IAED,MAAM,CAAC,SAAiD;QACtD,OAAO,IAAI,CAAC,WAAW,CAAa,IAAI,CAAC,YAAY,EAAE;YACrD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAC,cAAc,EAAE,kBAAkB,EAAC;YAC7C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;SAChC,CAAC,CAAA;IACJ,CAAC;IAED,QAAQ,CAAC,WAAmB;QAC1B,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,WAAW,EAC9C;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAC,cAAc,EAAE,kBAAkB,EAAC;SAC9C,CACF,CAAA;IACH,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qelos/sdk",
3
- "version": "3.8.1",
3
+ "version": "3.8.3",
4
4
  "description": "SDK for Qelos API",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -13,11 +13,11 @@
13
13
  "access": "public"
14
14
  },
15
15
  "dependencies": {
16
- "@qelos/global-types": "^3.8.1"
16
+ "@qelos/global-types": "^3.8.3"
17
17
  },
18
18
  "devDependencies": {
19
- "tsx": "^3.12.7",
19
+ "tsx": "^4.19.4",
20
20
  "typescript": "^4.9.5"
21
21
  },
22
- "gitHead": "870f8846e1cdcc13af9327c6e70844a33a9f9cba"
22
+ "gitHead": "4f4acba1f01d2659431e3149cc6efa927926c5f1"
23
23
  }
@@ -9,6 +9,7 @@ import QlAdminWorkspaces from './workspaces';
9
9
  import QlManageBlueprints from './manage-blueprints';
10
10
  import { QlRoles } from './roles';
11
11
  import QlIntegrationSources from './integration-sources';
12
+ import QlManagePlugins from './manage-plugins';
12
13
 
13
14
  export default class QelosAdministratorSDK<T = any> extends QelosSDK {
14
15
  users: QlUsers<T>;
@@ -20,6 +21,7 @@ export default class QelosAdministratorSDK<T = any> extends QelosSDK {
20
21
  adminWorkspaces: QlAdminWorkspaces;
21
22
  roles: QlRoles;
22
23
  integrationSources: QlIntegrationSources;
24
+ managePlugins: QlManagePlugins;
23
25
 
24
26
  constructor(options: QelosSDKOptions) {
25
27
  super(options);
@@ -32,6 +34,7 @@ export default class QelosAdministratorSDK<T = any> extends QelosSDK {
32
34
  this.adminWorkspaces = new QlAdminWorkspaces(options);
33
35
  this.roles = new QlRoles(options);
34
36
  this.integrationSources = new QlIntegrationSources(options);
37
+ this.managePlugins = new QlManagePlugins(options);
35
38
 
36
39
  if (!options.extraQueryParams) {
37
40
  options.extraQueryParams = () => ({
@@ -0,0 +1,58 @@
1
+ import BaseSDK from '../base-sdk';
2
+ import { QelosSDKOptions } from '../types';
3
+ import { IPlugin, IEventSubscriber, IMicroFrontend, IPluginCrud, IInjectable, INavbarGroup } from '@qelos/global-types';
4
+
5
+ // Fields that are typically set by the server or not directly updatable by admin
6
+ type ServerManagedPluginFields = 'tenant' | 'user' | 'token' | 'auth' | '_id' | 'id' | 'createdAt' | 'updatedAt';
7
+
8
+ export type IPluginCreateParams = Omit<IPlugin, ServerManagedPluginFields | 'subscribedEvents' | 'microFrontends' | 'cruds' | 'injectables' | 'navBarGroups'> & {
9
+ // Make optional arrays explicitly optional for creation if they can be omitted
10
+ subscribedEvents?: Partial<IEventSubscriber>[];
11
+ microFrontends?: Partial<IMicroFrontend>[];
12
+ cruds?: Partial<IPluginCrud>[];
13
+ injectables?: Partial<IInjectable>[];
14
+ navBarGroups?: Partial<INavbarGroup>[];
15
+ version?: string; // Add version if it's part of creation payload
16
+ url?: string; // Add url if it's part of creation payload (often same as appUrl)
17
+ proxyUrl?: string; // Allow setting proxyUrl during creation
18
+ };
19
+
20
+ export type IPluginUpdateParams = Partial<Omit<IPlugin, ServerManagedPluginFields>>;
21
+
22
+ export default class QlManagePlugins extends BaseSDK {
23
+ private relativePath = '/api/plugins'; // Please confirm/adjust this path
24
+
25
+ constructor(options: QelosSDKOptions) {
26
+ super(options);
27
+ }
28
+
29
+ async create(pluginData: IPluginCreateParams): Promise<IPlugin> {
30
+ return this.callJsonApi<IPlugin>(this.relativePath, {
31
+ method: 'POST',
32
+ headers: { 'content-type': 'application/json' },
33
+ body: JSON.stringify(pluginData),
34
+ });
35
+ }
36
+
37
+ async update(pluginId: string, pluginData: IPluginUpdateParams): Promise<IPlugin> {
38
+ return this.callJsonApi<IPlugin>(`${this.relativePath}/${pluginId}`, {
39
+ method: 'PUT',
40
+ headers: { 'content-type': 'application/json' },
41
+ body: JSON.stringify(pluginData),
42
+ });
43
+ }
44
+
45
+ async remove(pluginId: string): Promise<void> {
46
+ // callApi usually doesn't expect a JSON response, so no <void> generic needed for it.
47
+ // It will throw on non-2xx responses.
48
+ await this.callApi(`${this.relativePath}/${pluginId}`, { method: 'DELETE' });
49
+ }
50
+
51
+ async getList(): Promise<IPlugin[]> {
52
+ return this.callJsonApi<IPlugin[]>(this.relativePath);
53
+ }
54
+
55
+ async getById(pluginId: string): Promise<IPlugin> {
56
+ return this.callJsonApi<IPlugin>(`${this.relativePath}/${pluginId}`);
57
+ }
58
+ }
package/src/base-sdk.ts CHANGED
@@ -1,49 +1,105 @@
1
1
  import { FetchLike, QelosSDKOptions } from './types';
2
2
 
3
+ const ERRORS = {
4
+ EXTRA_HEADERS: 'could not get extra headers',
5
+ FAILED_REFRESH_TOKEN: 'could not handle failed refresh token',
6
+ UNABLE_TO_REFRESH_TOKEN: 'could not able to refresh token'
7
+ }
8
+
3
9
  export default class BaseSDK {
4
10
  #appUrl: string;
5
11
  #fetch: FetchLike;
6
12
 
7
13
  constructor(private qlOptions: QelosSDKOptions) {
8
- this.#appUrl = qlOptions.appUrl.endsWith('/') ? qlOptions.appUrl.slice(0, -1) : qlOptions.appUrl;
14
+ this.#appUrl = qlOptions.appUrl?.endsWith('/') ? qlOptions.appUrl.slice(0, -1) : qlOptions.appUrl;
9
15
  this.#fetch = qlOptions.fetch || globalThis.fetch;
10
16
  }
11
17
 
12
18
  async callApi(relativeUrl: string, data?: RequestInit) {
13
19
  data = data || {};
14
20
  data.headers = data.headers || {};
15
- Object.assign(data.headers, await this.qlOptions.extraHeaders(relativeUrl));
21
+
22
+ if (this.qlOptions.extraHeaders) {
23
+ try {
24
+ const extraHeaders = await this.qlOptions.extraHeaders(relativeUrl);
25
+ Object.assign(data.headers, extraHeaders);
26
+ } catch (e) {
27
+ throw new Error(ERRORS.EXTRA_HEADERS);
28
+ }
29
+ }
30
+
16
31
  return this.#fetch(this.#appUrl + relativeUrl, data);
17
32
  }
18
33
 
19
- callJsonApi<T>(relativeUrl: string, data?: RequestInit): Promise<T> {
20
- return this.callApi(relativeUrl, data).then(async res => {
34
+ private async handleFailedRefreshToken(): Promise<void> {
35
+ if (this.qlOptions.onFailedRefreshToken) {
36
+ try {
37
+ await this.qlOptions.onFailedRefreshToken();
38
+ } catch (e) {
39
+ throw new Error(ERRORS.FAILED_REFRESH_TOKEN);
40
+ }
41
+ } else {
42
+ throw new Error(ERRORS.UNABLE_TO_REFRESH_TOKEN);
43
+ }
44
+ }
45
+
46
+ private getContentType(res: Response): string {
47
+ return res.headers.get('Content-Type') ||
48
+ res.headers.get('content-type') ||
49
+ res.headers.get('ContentType') ||
50
+ res.headers.get('contenttype') ||
51
+ res.headers.get('contentType') || 'text';
52
+ }
53
+
54
+ private async parseResponse<T>(res: Response): Promise<T> {
55
+ const contentType = this.getContentType(res);
56
+ const isJson = contentType.includes('json');
57
+
58
+ const body = await (isJson ? res.json() : res.text());
59
+
60
+ if (!res.ok) {
61
+ throw (typeof body === 'string' ? new Error(body) : body);
62
+ }
63
+
64
+ return body;
65
+ }
66
+
67
+ async callJsonApi<T>(relativeUrl: string, data?: RequestInit): Promise<T> {
68
+ try {
69
+ let res = await this.callApi(relativeUrl, data);
70
+
71
+ // Handle token refresh if needed
21
72
  if (this.qlOptions.forceRefresh && res.status >= 400 && res.status < 500) {
22
- const headers = await this.qlOptions.extraHeaders(relativeUrl, true);
23
- if (!headers.authorization) {
24
- if (this.qlOptions.onFailedRefreshToken) {
25
- try {
26
- await this.qlOptions.onFailedRefreshToken();
27
- } catch (e) {
28
- throw new Error('could not handle failed refresh token');
29
- }
30
- } else {
31
- throw new Error('could not able to refresh token');
73
+ let headers: Record<string, string> = {};
74
+
75
+ if (this.qlOptions.extraHeaders) {
76
+ try {
77
+ headers = await this.qlOptions.extraHeaders(relativeUrl, true);
78
+ } catch {
79
+ // Ignore error during refresh attempt
32
80
  }
33
81
  }
82
+
83
+ if (!headers?.authorization) {
84
+ await this.handleFailedRefreshToken();
85
+ }
86
+
34
87
  res = await this.callApi(relativeUrl, data);
35
88
  }
36
- const isJson = (res.headers.get('Content-Type') ||
37
- res.headers.get('content-type') ||
38
- res.headers.get('ContentType') ||
39
- res.headers.get('contenttype') ||
40
- res.headers.get('contentType') || 'text').includes('json');
41
- const body = await (isJson ? res.json() : res.text());
42
- if (!res.ok) {
43
- throw (typeof body === 'string' ? new Error(body) : body);
89
+
90
+ return this.parseResponse<T>(res);
91
+ } catch (err: unknown) {
92
+ // Type guard for Error objects
93
+ if (err instanceof Error && err.message === ERRORS.EXTRA_HEADERS) {
94
+ // Handle token refresh for EXTRA_HEADERS_ERROR
95
+ await this.handleFailedRefreshToken();
96
+
97
+ const res = await this.callApi(relativeUrl, data);
98
+ return this.parseResponse<T>(res);
44
99
  }
45
- return body
46
- });
100
+
101
+ throw err;
102
+ }
47
103
  }
48
104
 
49
105
  getQueryParams(moreQuery?: Record<string, any>) {
package/src/workspaces.ts CHANGED
@@ -69,7 +69,7 @@ export default class QlWorkspaces extends BaseSDK {
69
69
 
70
70
  activate(workspaceId: string): Promise<IWorkspace> {
71
71
  return this.callJsonApi<IWorkspace>(
72
- `${this.relativePath}/${workspaceId}`,
72
+ `${this.relativePath}/${workspaceId}/activate`,
73
73
  {
74
74
  method: 'post',
75
75
  headers: {'content-type': 'application/json'},