@skyservice-developers/vue-dev-kit 2.5.6 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -31,6 +31,9 @@ import {
31
31
  SkyCheckboxFilter,
32
32
  // sdk
33
33
  navigate, SkyserviceAPI, isInsideIframe,
34
+ // sky-service-ui-components
35
+ NotificationElement,
36
+ notificationModule, globalStore,
34
37
  } from '@skyservice-developers/vue-dev-kit'
35
38
  ```
36
39
 
@@ -98,6 +101,10 @@ const tradepoints = await api.getTradepoints()
98
101
  const categories = await api.getCategoryTree(tradepointId)
99
102
  const products = await api.getProducts({ tradepointId })
100
103
 
104
+ // Права доступу
105
+ const canInventory = await api.getPerms('204') // → boolean
106
+ const allPerms = await api.getPerms() // → PermsMap { '204': true, ... }
107
+
101
108
  // Активація/деактивація міні-додатку
102
109
  await api.setAppActive({ isActive: true, title: 'Glovo', settings: { foo: 'bar' } })
103
110
  await api.setAppActive({ isActive: false, title: 'Glovo' })
@@ -108,6 +115,22 @@ await api.setAppActive({ isActive: false, title: 'Glovo' })
108
115
  > `deploymentId` + `appName` задані в конфізі — додатково шле `sendActiveApp`
109
116
  > postMessage в parent (Dashboard) з відповіддю сервера та новим станом.
110
117
 
118
+ #### Права доступу — `getPerms`
119
+
120
+ Повертає права поточного користувача. Джерело за пріоритетом:
121
+
122
+ 1. **Стор Dashboard** через iframe bridge (`store.perms`) — миттєво, без токена, працює всередині iframe;
123
+ 2. **HTTP fallback** `section=adminPanel&action=getStart` → `data.settings.perms` — поза iframe (standalone-сторінка, Node) або поки стор ще порожній.
124
+
125
+ ```ts
126
+ await api.getPerms('9006') // → boolean — чи надано право 9006
127
+ await api.getPerms() // → PermsMap: { '9006': true, '100': false, ... }
128
+ api.clearPermsCache() // скинути кеш (наступний getPerms перезапросить джерело)
129
+ ```
130
+
131
+ > Результат кешується на інстансі — повторні виклики не роблять зайвих запитів/postMessage.
132
+ > Значення нормалізуються в `boolean` (бек може віддавати `0/1`); відсутній код → `false`.
133
+
111
134
  ### Webview detection
112
135
 
113
136
  ```ts
@@ -704,6 +727,56 @@ Shell-контейнер для карток: ribbon / header / body / footer
704
727
 
705
728
  ---
706
729
 
730
+ ## sky-service-ui-components
731
+
732
+ Бібліотека re-export-ує весь публічний API пакета `sky-service-ui-components`. Окремо встановлювати його не потрібно — він вже входить у залежності `vue-dev-kit`.
733
+
734
+ ### NotificationElement (Web Component)
735
+
736
+ Кастомний HTML-елемент для відображення тостів. Реєструється автоматично при імпорті.
737
+
738
+ ```ts
739
+ import { NotificationElement } from '@skyservice-developers/vue-dev-kit'
740
+ ```
741
+
742
+ Додай елемент в `index.html` або кореневий компонент:
743
+
744
+ ```html
745
+ <notification-element id="my-notifications"></notification-element>
746
+ ```
747
+
748
+ ### notificationModule
749
+
750
+ Програмний API для показу тостів.
751
+
752
+ ```ts
753
+ import { notificationModule } from '@skyservice-developers/vue-dev-kit'
754
+
755
+ // Типи: default | success | error | warning | info | loading
756
+ await notificationModule.notify.success({ message: 'Збережено' })
757
+ await notificationModule.notify.error({ message: 'Помилка' })
758
+ await notificationModule.notify.warning({ message: 'Увага' })
759
+ await notificationModule.notify.info({ message: 'Підказка' })
760
+
761
+ const id = await notificationModule.notify.loading({ message: 'Завантаження...' })
762
+ // Прибрати конкретний тост
763
+ await notificationModule.notify.dismiss(id)
764
+ ```
765
+
766
+ Метод повертає `Promise<string | number | null>` — id тосту або `null` при помилці.
767
+
768
+ ### globalStore
769
+
770
+ Глобальний стор бібліотеки (Pinia store). Використовується внутрішньо `notificationModule`.
771
+
772
+ ```ts
773
+ import { globalStore } from '@skyservice-developers/vue-dev-kit'
774
+
775
+ const store = globalStore()
776
+ ```
777
+
778
+ ---
779
+
707
780
  ## Теміzація
708
781
 
709
782
  Всі компоненти підтримують кастомізацію через CSS змінні. Перевизначайте їх глобально або локально:
@@ -788,7 +861,7 @@ src/
788
861
  │ ├── bridge.ts # iframe postMessage API
789
862
  │ ├── api.ts # SkyserviceAPI HTTP клієнт
790
863
  │ ├── webview.ts # детекція webview/iframe
791
- │ ├── types.ts # DTO типи (Tradepoint, Category, Product, AppIntegration)
864
+ │ ├── types.ts # DTO типи (Tradepoint, Category, Product, AppIntegration, PermsMap)
792
865
  │ └── index.ts
793
866
  └── styles/
794
867
  ```
@@ -1,142 +1,142 @@
1
- import S from "ua-parser-js";
2
- const l = "DASHBOARD", b = 5e3;
3
- let k = 0, u = null;
1
+ import b from "ua-parser-js";
2
+ const h = "DASHBOARD", k = 5e3;
3
+ let P = 0, u = null;
4
4
  function A() {
5
- return `sdk_${Date.now()}_${++k}`;
5
+ return `sdk_${Date.now()}_${++P}`;
6
6
  }
7
- function E() {
7
+ function C() {
8
8
  return "APP_" + Math.random().toString(36).slice(2, 10);
9
9
  }
10
- function N(t) {
10
+ function R(t) {
11
11
  u = t;
12
12
  }
13
- function g() {
14
- return u || (u = E()), u;
13
+ function m() {
14
+ return u || (u = C()), u;
15
15
  }
16
- function s(t) {
16
+ function o(t) {
17
17
  window.parent.postMessage(
18
18
  {
19
19
  ...t,
20
- sender: g(),
21
- target: t.target || l
20
+ sender: m(),
21
+ target: t.target || h
22
22
  },
23
23
  "*"
24
24
  );
25
25
  }
26
- function w(t, e, r = b) {
27
- return h() ? new Promise((n) => {
28
- const i = A(), a = g(), o = setTimeout(() => {
26
+ function w(t, e, r = k) {
27
+ return y() ? new Promise((n) => {
28
+ const a = A(), i = m(), s = setTimeout(() => {
29
29
  window.removeEventListener("message", d), n(null);
30
30
  }, r);
31
- function d(I) {
32
- const c = I.data;
33
- (c == null ? void 0 : c.type) === "DATA_RESPONSE" && (c == null ? void 0 : c.requestId) === i && (!c.target || c.target === a) && (clearTimeout(o), window.removeEventListener("message", d), n(c.data ?? null));
31
+ function d(S) {
32
+ const c = S.data;
33
+ (c == null ? void 0 : c.type) === "DATA_RESPONSE" && (c == null ? void 0 : c.requestId) === a && (!c.target || c.target === i) && (clearTimeout(s), window.removeEventListener("message", d), n(c.data ?? null));
34
34
  }
35
- window.addEventListener("message", d), s({ type: "DATA_REQUEST", requestId: i, source: t, key: e });
35
+ window.addEventListener("message", d), o({ type: "DATA_REQUEST", requestId: a, source: t, key: e });
36
36
  }) : Promise.resolve(null);
37
37
  }
38
- function R(t) {
39
- s({ type: "navigate", path: t });
38
+ function U(t) {
39
+ o({ type: "navigate", path: t });
40
40
  }
41
- function L() {
42
- s({ type: "exit" });
41
+ function E() {
42
+ o({ type: "exit" });
43
43
  }
44
- const U = L;
45
- function f(t) {
44
+ const $ = E;
45
+ function p(t) {
46
46
  return w("store", t);
47
47
  }
48
- function y(t) {
48
+ function g(t) {
49
49
  return w("localStorage", t);
50
50
  }
51
- function $(t) {
51
+ function O(t) {
52
52
  return w("window", t);
53
53
  }
54
- function O() {
55
- return f("company");
54
+ function j() {
55
+ return p("company");
56
56
  }
57
57
  function W() {
58
- return f("user");
58
+ return p("user");
59
59
  }
60
60
  function x() {
61
- return y("token");
61
+ return g("token");
62
62
  }
63
- function M() {
64
- return y("lang");
63
+ function B() {
64
+ return g("lang");
65
65
  }
66
- function j() {
67
- return f("productCategories");
66
+ function M() {
67
+ return p("productCategories");
68
68
  }
69
69
  function q(t, e) {
70
- s({ type: "setLocalStorage", key: t, value: e });
70
+ o({ type: "setLocalStorage", key: t, value: e });
71
71
  }
72
- function B(t) {
73
- s({ type: "setRocketMode", value: t });
72
+ function z(t) {
73
+ o({ type: "setRocketMode", value: t });
74
74
  }
75
75
  function G(t, e) {
76
- s({ type: "trackVisit", name: t, path: e });
76
+ o({ type: "trackVisit", name: t, path: e });
77
77
  }
78
- function z(t) {
79
- s({ type: "openExternalLink", url: t });
78
+ function F(t) {
79
+ o({ type: "openExternalLink", url: t });
80
80
  }
81
- function F() {
82
- s({ type: "openCrispChat" });
83
- }
84
- function H(t) {
85
- s({ type: "notification", text: t });
81
+ function H() {
82
+ o({ type: "openCrispChat" });
86
83
  }
87
84
  function Q(t) {
88
- s({ type: "notification", text: t, variant: "error" });
85
+ o({ type: "notification", text: t });
89
86
  }
90
87
  function V(t) {
91
- s({ type: "notification", text: t, variant: "warn" });
88
+ o({ type: "notification", text: t, variant: "error" });
89
+ }
90
+ function J(t) {
91
+ o({ type: "notification", text: t, variant: "warn" });
92
92
  }
93
- function h() {
93
+ function y() {
94
94
  try {
95
95
  return window.self !== window.top;
96
96
  } catch {
97
97
  return !0;
98
98
  }
99
99
  }
100
- const J = h;
101
- function K(t) {
100
+ const K = y;
101
+ function Y(t) {
102
102
  function e(r) {
103
103
  var n;
104
- ((n = r.data) == null ? void 0 : n.sender) === l && t(r.data);
104
+ ((n = r.data) == null ? void 0 : n.sender) === h && t(r.data);
105
105
  }
106
106
  return window.addEventListener("message", e), () => window.removeEventListener("message", e);
107
107
  }
108
- function p() {
108
+ function f() {
109
109
  if (typeof window > "u") return "browser";
110
110
  if (window.webkit != null && window.webkit.messageHandlers !== void 0)
111
111
  try {
112
- if (S(navigator.userAgent).browser.name === "WebKit") return "ios_webview";
112
+ if (b(navigator.userAgent).browser.name === "WebKit") return "ios_webview";
113
113
  } catch (t) {
114
114
  console.error(t);
115
115
  }
116
116
  return typeof Android < "u" ? "android_webview" : typeof window.cefQuery < "u" ? "cef_webview" : "browser";
117
117
  }
118
- function Y() {
119
- return p() === "ios_webview";
120
- }
121
118
  function X() {
122
- return p() === "android_webview";
119
+ return f() === "ios_webview";
123
120
  }
124
121
  function Z() {
125
- return p() === "cef_webview";
122
+ return f() === "android_webview";
126
123
  }
127
124
  function ee() {
128
- return p() !== "browser";
125
+ return f() === "cef_webview";
129
126
  }
130
- const P = "https://api.cabinet.developer.skyservice.online/index.php";
131
- class m {
127
+ function te() {
128
+ return f() !== "browser";
129
+ }
130
+ const L = "https://api.cabinet.developer.skyservice.online/index.php";
131
+ class v {
132
132
  constructor(e) {
133
- this.token = e.token, this.companyId = e.companyId, this.appId = e.appId, this.developerId = e.developerId, this.deploymentId = e.deploymentId, this.appName = e.appName;
133
+ this.permsCache = null, this.token = e.token, this.companyId = e.companyId, this.appId = e.appId, this.developerId = e.developerId, this.deploymentId = e.deploymentId, this.appName = e.appName;
134
134
  const r = e.domain.replace("dashboard", "api");
135
135
  this.baseUrl = r.startsWith("http") ? r : `https://${r}`;
136
136
  }
137
137
  /** Factory — create a new SkyserviceAPI instance. */
138
138
  static create(e) {
139
- return new m(e);
139
+ return new v(e);
140
140
  }
141
141
  // --- Low-level ---
142
142
  async get(e) {
@@ -147,26 +147,26 @@ class m {
147
147
  }), n = await fetch(`${this.baseUrl}/?${r}`);
148
148
  if (!n.ok)
149
149
  throw new Error(`Skyservice API error: ${n.status}`);
150
- const i = await n.json();
151
- if (i.status !== "done")
152
- throw new Error(`Skyservice API returned status: ${i.status}`);
153
- return i.data;
150
+ const a = await n.json();
151
+ if (a.status !== "done")
152
+ throw new Error(`Skyservice API returned status: ${a.status}`);
153
+ return a.data;
154
154
  }
155
155
  async post(e, r, n) {
156
- const i = new URLSearchParams({
156
+ const a = new URLSearchParams({
157
157
  token: this.token,
158
158
  ...r
159
- }), a = await fetch(`${e}?${i}`, {
159
+ }), i = await fetch(`${e}?${a}`, {
160
160
  method: "POST",
161
161
  headers: { "Content-Type": "application/json" },
162
162
  body: JSON.stringify(n)
163
163
  });
164
- if (!a.ok)
165
- throw new Error(`Skyservice API error: ${a.status}`);
166
- const o = await a.json();
167
- if (o.status !== "done")
168
- throw new Error(`Skyservice API returned status: ${o.status}`);
169
- return o.data;
164
+ if (!i.ok)
165
+ throw new Error(`Skyservice API error: ${i.status}`);
166
+ const s = await i.json();
167
+ if (s.status !== "done")
168
+ throw new Error(`Skyservice API returned status: ${s.status}`);
169
+ return s.data;
170
170
  }
171
171
  // --- Tradepoints ---
172
172
  /**
@@ -195,7 +195,7 @@ class m {
195
195
  action: "getCategories",
196
196
  ...e ? { tradepointId: String(e) } : {}
197
197
  });
198
- return v(r, e);
198
+ return I(r, e);
199
199
  }
200
200
  // --- Products ---
201
201
  /**
@@ -215,7 +215,7 @@ class m {
215
215
  of: "nomenclatureId",
216
216
  ...e != null && e.tradepointId ? { tradepointId: String(e.tradepointId) } : {}
217
217
  });
218
- return C(r.items, e == null ? void 0 : e.includeInactive);
218
+ return D(r.items, e == null ? void 0 : e.includeInactive);
219
219
  }
220
220
  // --- Integrations ---
221
221
  /**
@@ -235,49 +235,80 @@ class m {
235
235
  title: r,
236
236
  settings: n
237
237
  }) {
238
- const i = e ? "activateApp" : "deactivateApp", a = {
238
+ const a = e ? "activateApp" : "deactivateApp", i = {
239
239
  company_id: this.companyId,
240
240
  app_id: this.appId,
241
241
  ...this.developerId !== void 0 && { developer_id: this.developerId },
242
242
  ...e && n !== void 0 && { settings: n }
243
- }, o = await this.post(
244
- P,
245
- { section: "integrations", action: i },
246
- a
243
+ }, s = await this.post(
244
+ L,
245
+ { section: "integrations", action: a },
246
+ i
247
247
  );
248
248
  return this.deploymentId && this.appName && typeof window < "u" && window.self !== window.top && window.parent.postMessage(
249
249
  {
250
250
  type: "sendActiveApp",
251
- id: o.id,
251
+ id: s.id,
252
252
  is_active: e,
253
253
  deploymentId: this.deploymentId,
254
254
  appName: this.appName,
255
255
  title: r
256
256
  },
257
257
  "*"
258
- ), o;
258
+ ), s;
259
+ }
260
+ async getPerms(e) {
261
+ const r = await this.loadPerms();
262
+ return e === void 0 ? r : !!r[String(e)];
259
263
  }
264
+ /** Drop the cached permissions so the next {@link getPerms} call refetches. */
265
+ clearPermsCache() {
266
+ this.permsCache = null;
267
+ }
268
+ async loadPerms() {
269
+ var r;
270
+ if (this.permsCache) return this.permsCache;
271
+ if (typeof window < "u")
272
+ try {
273
+ const n = await p("perms");
274
+ if (n && Object.keys(n).length > 0)
275
+ return this.permsCache = l(n), this.permsCache;
276
+ } catch {
277
+ }
278
+ const e = await this.get({
279
+ section: "adminPanel",
280
+ action: "getStart"
281
+ });
282
+ return this.permsCache = l((r = e == null ? void 0 : e.settings) == null ? void 0 : r.perms), this.permsCache;
283
+ }
284
+ }
285
+ function l(t) {
286
+ const e = {};
287
+ if (!t || typeof t != "object") return e;
288
+ for (const [r, n] of Object.entries(t))
289
+ e[r] = !!n;
290
+ return e;
260
291
  }
261
- function v(t, e) {
262
- var n, i;
292
+ function I(t, e) {
293
+ var n, a;
263
294
  const r = [];
264
- for (const a of t) {
265
- if (e != null && !((n = a.tradepointShow) == null ? void 0 : n[String(e)]))
295
+ for (const i of t) {
296
+ if (e != null && !((n = i.tradepointShow) == null ? void 0 : n[String(e)]))
266
297
  continue;
267
- const o = {
268
- id: a.id,
269
- pid: a.pid,
270
- name: a.name,
271
- active: a.active,
272
- background: a.background,
273
- show: a.show
298
+ const s = {
299
+ id: i.id,
300
+ pid: i.pid,
301
+ name: i.name,
302
+ active: i.active,
303
+ background: i.background,
304
+ show: i.show
274
305
  };
275
- a.img && (o.img = a.img), (i = a.children) != null && i.length && (o.children = v(a.children, e)), r.push(o);
306
+ i.img && (s.img = i.img), (a = i.children) != null && a.length && (s.children = I(i.children, e)), r.push(s);
276
307
  }
277
308
  return r;
278
309
  }
279
310
  const _ = /* @__PURE__ */ new Set(["product", "techcard"]), T = "/img/no.png";
280
- function C(t, e) {
311
+ function D(t, e) {
281
312
  const r = [];
282
313
  for (const n of t)
283
314
  _.has(n.type) && (!e && !n.active || r.push({
@@ -294,34 +325,34 @@ function C(t, e) {
294
325
  return r;
295
326
  }
296
327
  export {
297
- N as A,
328
+ R as A,
298
329
  G as B,
299
- p as C,
300
- m as S,
301
- O as a,
302
- M as b,
303
- y as c,
304
- j as d,
305
- L as e,
306
- g as f,
307
- U as g,
308
- f as h,
330
+ f as C,
331
+ v as S,
332
+ j as a,
333
+ B as b,
334
+ g as c,
335
+ M as d,
336
+ E as e,
337
+ m as f,
338
+ $ as g,
339
+ p as h,
309
340
  x as i,
310
341
  W as j,
311
- $ as k,
312
- X as l,
313
- Z as m,
314
- J as n,
315
- h as o,
316
- Y as p,
317
- ee as q,
318
- R as r,
319
- H as s,
320
- Q as t,
321
- V as u,
322
- K as v,
323
- F as w,
324
- z as x,
342
+ O as k,
343
+ Z as l,
344
+ ee as m,
345
+ K as n,
346
+ y as o,
347
+ X as p,
348
+ te as q,
349
+ U as r,
350
+ Q as s,
351
+ V as t,
352
+ J as u,
353
+ Y as v,
354
+ H as w,
355
+ F as x,
325
356
  q as y,
326
- B as z
357
+ z
327
358
  };
@@ -0,0 +1 @@
1
+ "use strict";const k=require("ua-parser-js"),v="DASHBOARD",C=5e3;let P=0,f=null;function A(){return`sdk_${Date.now()}_${++P}`}function E(){return"APP_"+Math.random().toString(36).slice(2,10)}function L(t){f=t}function w(){return f||(f=E()),f}function s(t){window.parent.postMessage({...t,sender:w(),target:t.target||v},"*")}function g(t,e,r=C){return h()?new Promise(n=>{const o=A(),i=w(),a=setTimeout(()=>{window.removeEventListener("message",p),n(null)},r);function p(b){const c=b.data;(c==null?void 0:c.type)==="DATA_RESPONSE"&&(c==null?void 0:c.requestId)===o&&(!c.target||c.target===i)&&(clearTimeout(a),window.removeEventListener("message",p),n(c.data??null))}window.addEventListener("message",p),s({type:"DATA_REQUEST",requestId:o,source:t,key:e})}):Promise.resolve(null)}function T(t){s({type:"navigate",path:t})}function I(){s({type:"exit"})}const _=I;function d(t){return g("store",t)}function l(t){return g("localStorage",t)}function D(t){return g("window",t)}function W(){return d("company")}function R(){return d("user")}function U(){return l("token")}function N(){return l("lang")}function $(){return d("productCategories")}function O(t,e){s({type:"setLocalStorage",key:t,value:e})}function M(t){s({type:"setRocketMode",value:t})}function j(t,e){s({type:"trackVisit",name:t,path:e})}function x(t){s({type:"openExternalLink",url:t})}function B(){s({type:"openCrispChat"})}function q(t){s({type:"notification",text:t})}function G(t){s({type:"notification",text:t,variant:"error"})}function V(t){s({type:"notification",text:t,variant:"warn"})}function h(){try{return window.self!==window.top}catch{return!0}}const z=h;function F(t){function e(r){var n;((n=r.data)==null?void 0:n.sender)===v&&t(r.data)}return window.addEventListener("message",e),()=>window.removeEventListener("message",e)}function u(){if(typeof window>"u")return"browser";if(window.webkit!=null&&window.webkit.messageHandlers!==void 0)try{if(k(navigator.userAgent).browser.name==="WebKit")return"ios_webview"}catch(t){console.error(t)}return typeof Android<"u"?"android_webview":typeof window.cefQuery<"u"?"cef_webview":"browser"}function H(){return u()==="ios_webview"}function Q(){return u()==="android_webview"}function J(){return u()==="cef_webview"}function K(){return u()!=="browser"}const Y="https://api.cabinet.developer.skyservice.online/index.php";class m{constructor(e){this.permsCache=null,this.token=e.token,this.companyId=e.companyId,this.appId=e.appId,this.developerId=e.developerId,this.deploymentId=e.deploymentId,this.appName=e.appName;const r=e.domain.replace("dashboard","api");this.baseUrl=r.startsWith("http")?r:`https://${r}`}static create(e){return new m(e)}async get(e){const r=new URLSearchParams({token:this.token,companyId:this.companyId,...e}),n=await fetch(`${this.baseUrl}/?${r}`);if(!n.ok)throw new Error(`Skyservice API error: ${n.status}`);const o=await n.json();if(o.status!=="done")throw new Error(`Skyservice API returned status: ${o.status}`);return o.data}async post(e,r,n){const o=new URLSearchParams({token:this.token,...r}),i=await fetch(`${e}?${o}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!i.ok)throw new Error(`Skyservice API error: ${i.status}`);const a=await i.json();if(a.status!=="done")throw new Error(`Skyservice API returned status: ${a.status}`);return a.data}async getTradepoints(e){const r=await this.get({section:"tradepoints",action:"getTradepoints"});return e!=null&&e.includeDeleted?r.items:r.items.filter(n=>!n.deleted&&!n.frozen)}async getCategoryTree(e){const r=await this.get({section:"productCategory",action:"getCategories",...e?{tradepointId:String(e)}:{}});return S(r,e)}async getProducts(e){const r=await this.get({section:"products",action:"getProducts",pagelimit:"9999",ot:"desc",of:"nomenclatureId",...e!=null&&e.tradepointId?{tradepointId:String(e.tradepointId)}:{}});return ee(r.items,e==null?void 0:e.includeInactive)}async setAppActive({isActive:e,title:r,settings:n}){const o=e?"activateApp":"deactivateApp",i={company_id:this.companyId,app_id:this.appId,...this.developerId!==void 0&&{developer_id:this.developerId},...e&&n!==void 0&&{settings:n}},a=await this.post(Y,{section:"integrations",action:o},i);return this.deploymentId&&this.appName&&typeof window<"u"&&window.self!==window.top&&window.parent.postMessage({type:"sendActiveApp",id:a.id,is_active:e,deploymentId:this.deploymentId,appName:this.appName,title:r},"*"),a}async getPerms(e){const r=await this.loadPerms();return e===void 0?r:!!r[String(e)]}clearPermsCache(){this.permsCache=null}async loadPerms(){var r;if(this.permsCache)return this.permsCache;if(typeof window<"u")try{const n=await d("perms");if(n&&Object.keys(n).length>0)return this.permsCache=y(n),this.permsCache}catch{}const e=await this.get({section:"adminPanel",action:"getStart"});return this.permsCache=y((r=e==null?void 0:e.settings)==null?void 0:r.perms),this.permsCache}}function y(t){const e={};if(!t||typeof t!="object")return e;for(const[r,n]of Object.entries(t))e[r]=!!n;return e}function S(t,e){var n,o;const r=[];for(const i of t){if(e!=null&&!((n=i.tradepointShow)==null?void 0:n[String(e)]))continue;const a={id:i.id,pid:i.pid,name:i.name,active:i.active,background:i.background,show:i.show};i.img&&(a.img=i.img),(o=i.children)!=null&&o.length&&(a.children=S(i.children,e)),r.push(a)}return r}const X=new Set(["product","techcard"]),Z="/img/no.png";function ee(t,e){const r=[];for(const n of t)X.has(n.type)&&(!e&&!n.active||r.push({id:n.id,name:n.nomenclatureName,price:n.price,categoryId:n.categoryId,categoryName:n.categoryTitle||"",active:n.active,type:n.type,unit:n.unit,logo:n.logo&&n.logo!==Z?n.logo:""}));return r}exports.SkyserviceAPI=m;exports.exit=I;exports.getBack=_;exports.getCompany=W;exports.getLang=N;exports.getLocalStorageData=l;exports.getProductCategories=$;exports.getSenderId=w;exports.getStoreData=d;exports.getToken=U;exports.getUser=R;exports.getWindowData=D;exports.isAndroidWebview=Q;exports.isCefWebview=J;exports.isInIframe=z;exports.isInsideIframe=h;exports.isIosWebview=H;exports.isWebview=K;exports.navigate=T;exports.notify=q;exports.notifyError=G;exports.notifyWarn=V;exports.onMessage=F;exports.openCrispChat=B;exports.openExternalLink=x;exports.setLocalStorage=O;exports.setRocketMode=M;exports.setSenderId=L;exports.trackVisit=j;exports.webviewCheck=u;
package/dist/index.d.ts CHANGED
@@ -2,3 +2,5 @@
2
2
  export * from './shared/ui';
3
3
  export * from './features';
4
4
  export * from './sdk';
5
+ export * from 'sky-service-ui-components';
6
+ export * from 'sky-service-ui-components/modules';
package/dist/sdk/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Tradepoint, Category, Product, AppIntegration } from './types';
1
+ import { Tradepoint, Category, Product, AppIntegration, PermsMap } from './types';
2
2
 
3
3
  export interface SkyserviceAPIConfig {
4
4
  token: string;
@@ -33,6 +33,7 @@ export declare class SkyserviceAPI {
33
33
  private developerId;
34
34
  private deploymentId;
35
35
  private appName;
36
+ private permsCache;
36
37
  private constructor();
37
38
  /** Factory — create a new SkyserviceAPI instance. */
38
39
  static create(config: SkyserviceAPIConfig): SkyserviceAPI;
@@ -83,4 +84,29 @@ export declare class SkyserviceAPI {
83
84
  title?: string;
84
85
  settings?: Record<string, unknown>;
85
86
  }): Promise<AppIntegration>;
87
+ /**
88
+ * Get access permissions for the current user.
89
+ *
90
+ * Source priority:
91
+ * 1. Dashboard's Vuex store via iframe bridge (`getStoreData('perms')`) —
92
+ * instant, no token needed, includes Dashboard's computed perms. Used when
93
+ * running inside the Dashboard iframe.
94
+ * 2. HTTP fallback `section=adminPanel&action=getStart` → `data.settings.perms`
95
+ * — used outside the iframe (standalone page, Node) or while the store is
96
+ * still empty.
97
+ *
98
+ * The resolved map is cached on the instance — repeated calls don't re-request.
99
+ * Call {@link clearPermsCache} to force a refetch.
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * await api.getPerms('9006') // → boolean — is permission 9006 granted?
104
+ * await api.getPerms() // → { '9006': true, '100': false, ... }
105
+ * ```
106
+ */
107
+ getPerms(): Promise<PermsMap>;
108
+ getPerms(code: string | number): Promise<boolean>;
109
+ /** Drop the cached permissions so the next {@link getPerms} call refetches. */
110
+ clearPermsCache(): void;
111
+ private loadPerms;
86
112
  }
@@ -3,4 +3,4 @@ export { webviewCheck, isIosWebview, isAndroidWebview, isCefWebview, isWebview,
3
3
  export type { WebviewType } from './webview';
4
4
  export { SkyserviceAPI } from './api';
5
5
  export type { SkyserviceAPIConfig } from './api';
6
- export type { Tradepoint, TradepointWorkDay, Category, RawCategory, Product, RawProduct, AppIntegration, } from './types';
6
+ export type { Tradepoint, TradepointWorkDay, Category, RawCategory, Product, RawProduct, AppIntegration, PermsMap, } from './types';
@@ -12,6 +12,13 @@ export interface AppIntegration {
12
12
  created_at: string;
13
13
  updated_at: string;
14
14
  }
15
+ /**
16
+ * Access permissions map — access-code → granted.
17
+ *
18
+ * Mirrors Dashboard's `store.perms` (e.g. `{ '9006': true, '100': false }`).
19
+ * A missing code means "not granted". Returned by `SkyserviceAPI.getPerms()`.
20
+ */
21
+ export type PermsMap = Record<string, boolean>;
15
22
  export interface Tradepoint {
16
23
  tradepointId: number;
17
24
  tradepointName: string;
package/dist/sdk.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./api-lQ6dAmaI.cjs");exports.SkyserviceAPI=e.SkyserviceAPI;exports.exit=e.exit;exports.getBack=e.getBack;exports.getCompany=e.getCompany;exports.getLang=e.getLang;exports.getLocalStorageData=e.getLocalStorageData;exports.getProductCategories=e.getProductCategories;exports.getSenderId=e.getSenderId;exports.getStoreData=e.getStoreData;exports.getToken=e.getToken;exports.getUser=e.getUser;exports.getWindowData=e.getWindowData;exports.isAndroidWebview=e.isAndroidWebview;exports.isCefWebview=e.isCefWebview;exports.isInIframe=e.isInIframe;exports.isInsideIframe=e.isInsideIframe;exports.isIosWebview=e.isIosWebview;exports.isWebview=e.isWebview;exports.navigate=e.navigate;exports.notify=e.notify;exports.notifyError=e.notifyError;exports.notifyWarn=e.notifyWarn;exports.onMessage=e.onMessage;exports.openCrispChat=e.openCrispChat;exports.openExternalLink=e.openExternalLink;exports.setLocalStorage=e.setLocalStorage;exports.setRocketMode=e.setRocketMode;exports.setSenderId=e.setSenderId;exports.trackVisit=e.trackVisit;exports.webviewCheck=e.webviewCheck;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./api-DAgEQpwF.cjs");exports.SkyserviceAPI=e.SkyserviceAPI;exports.exit=e.exit;exports.getBack=e.getBack;exports.getCompany=e.getCompany;exports.getLang=e.getLang;exports.getLocalStorageData=e.getLocalStorageData;exports.getProductCategories=e.getProductCategories;exports.getSenderId=e.getSenderId;exports.getStoreData=e.getStoreData;exports.getToken=e.getToken;exports.getUser=e.getUser;exports.getWindowData=e.getWindowData;exports.isAndroidWebview=e.isAndroidWebview;exports.isCefWebview=e.isCefWebview;exports.isInIframe=e.isInIframe;exports.isInsideIframe=e.isInsideIframe;exports.isIosWebview=e.isIosWebview;exports.isWebview=e.isWebview;exports.navigate=e.navigate;exports.notify=e.notify;exports.notifyError=e.notifyError;exports.notifyWarn=e.notifyWarn;exports.onMessage=e.onMessage;exports.openCrispChat=e.openCrispChat;exports.openExternalLink=e.openExternalLink;exports.setLocalStorage=e.setLocalStorage;exports.setRocketMode=e.setRocketMode;exports.setSenderId=e.setSenderId;exports.trackVisit=e.trackVisit;exports.webviewCheck=e.webviewCheck;
package/dist/sdk.js CHANGED
@@ -1,4 +1,4 @@
1
- import { S as s, e as t, g as i, a as o, b as r, c as n, d as g, f as d, h as c, i as f, j as k, k as v, l as w, m as I, n as C, o as S, p as b, q as p, r as y, s as W, t as m, u as l, v as x, w as L, x as h, y as A, z as D, A as u, B, C as E } from "./api-AhLH5w3p.js";
1
+ import { S as s, e as t, g as i, a as o, b as r, c as n, d as g, f as d, h as c, i as f, j as k, k as v, l as w, m as I, n as C, o as S, p as b, q as p, r as y, s as W, t as m, u as l, v as x, w as L, x as h, y as A, z as D, A as u, B, C as E } from "./api-C6FKIf2t.js";
2
2
  export {
3
3
  s as SkyserviceAPI,
4
4
  t as exit,