samandesk 1.2.0 → 2.0.0-beta2.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/dist/saman-desk.js +279 -196
- package/dist/saman-desk.umd.cjs +1 -1
- package/dist/src/adapters/react-native/index.d.ts +30 -0
- package/dist/src/adapters/web/index.d.ts +16 -0
- package/dist/src/core/index.d.ts +29 -0
- package/dist/src/core/types.d.ts +50 -0
- package/dist/src/index.d.ts +3 -53
- package/package.json +5 -4
- package/dist/src/data.d.ts +0 -60
- package/dist/src/events.d.ts +0 -21
- package/dist/src/interoperation.d.ts +0 -34
package/dist/saman-desk.js
CHANGED
|
@@ -1,229 +1,312 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
handledByInterOperation = true;
|
|
76
|
-
} catch (err) {
|
|
77
|
-
console.error("error while run event action");
|
|
78
|
-
}
|
|
79
|
-
const data = event.data;
|
|
80
|
-
const id = data.id;
|
|
81
|
-
const run2 = getRun();
|
|
82
|
-
if (id in run2.promises && run2.promises[id]) {
|
|
83
|
-
run2.promises[id](data);
|
|
84
|
-
delete run2.promises[id];
|
|
85
|
-
} else if (!handledByInterOperation) {
|
|
86
|
-
console.error("Message from outside of frame is invalid");
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
function resolveRun(id, data, action) {
|
|
91
|
-
var _a;
|
|
92
|
-
const postData = { from: "SamanDesk", action, data, id };
|
|
93
|
-
const frame2 = getFrame();
|
|
94
|
-
(_a = frame2.contentWindow) == null ? void 0 : _a.postMessage(postData, "*");
|
|
95
|
-
}
|
|
96
|
-
class InterOperation {
|
|
97
|
-
async init() {
|
|
98
|
-
handleEvents(this);
|
|
1
|
+
const __vite_import_meta_env__ = {};
|
|
2
|
+
class SamanDeskCore {
|
|
3
|
+
constructor(config) {
|
|
4
|
+
this.runPromises = {};
|
|
5
|
+
this.promiseCount = 0;
|
|
6
|
+
this.isReady = false;
|
|
7
|
+
this.config = {
|
|
8
|
+
siteUrl: this.defaultSiteUrl,
|
|
9
|
+
language: "fa",
|
|
10
|
+
theme: { darkMode: "light", color: "default" },
|
|
11
|
+
...config
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
get defaultSiteUrl() {
|
|
15
|
+
return (__vite_import_meta_env__ == null ? void 0 : __vite_import_meta_env__.VITE_DEV_MODE) === "1" ? "http://localhost:2525" : "https://samandesk.com";
|
|
16
|
+
}
|
|
17
|
+
getInitialUrl() {
|
|
18
|
+
if (this.config.verifiedToken) {
|
|
19
|
+
return `${this.config.siteUrl}/setup-interoperation/${this.config.verifiedToken}`;
|
|
20
|
+
}
|
|
21
|
+
return `${this.config.siteUrl}/guest-login/${this.config.workspaceID}`;
|
|
22
|
+
}
|
|
23
|
+
getOpenUrl(link) {
|
|
24
|
+
return link || `${this.config.siteUrl}/department-selection?token=${this.token}`;
|
|
25
|
+
}
|
|
26
|
+
handleIncomingMessage(message) {
|
|
27
|
+
if (!message || message.from !== "SamanDesk") return;
|
|
28
|
+
const { action, id, data } = message;
|
|
29
|
+
if (id !== void 0 && this.runPromises[id]) {
|
|
30
|
+
this.runPromises[id](data);
|
|
31
|
+
delete this.runPromises[id];
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
switch (action) {
|
|
35
|
+
case "setToken":
|
|
36
|
+
this.handleSetToken(data);
|
|
37
|
+
break;
|
|
38
|
+
case "getConfig":
|
|
39
|
+
this.handleGetConfig(id);
|
|
40
|
+
break;
|
|
41
|
+
case "openLink":
|
|
42
|
+
this.handleOpenLink(data);
|
|
43
|
+
break;
|
|
44
|
+
case "setGuestReadyEvent":
|
|
45
|
+
this.handleSetGuestReadyEvent();
|
|
46
|
+
break;
|
|
47
|
+
case "close":
|
|
48
|
+
this.handleCloseFromInside();
|
|
49
|
+
break;
|
|
50
|
+
default:
|
|
51
|
+
console.warn(`[SamanDesk] Unhandled action: ${action}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
handleSetToken(data) {
|
|
55
|
+
if (data && data.token) {
|
|
56
|
+
this.token = data.token;
|
|
57
|
+
this.isReady = true;
|
|
58
|
+
if (this.config.onReady) {
|
|
59
|
+
this.config.onReady(this.token);
|
|
60
|
+
}
|
|
61
|
+
if (this.config.onTokenChange) {
|
|
62
|
+
this.config.onTokenChange(this.token);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
handleGetConfig(id) {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
if (id !== void 0) {
|
|
69
|
+
this.sendResponse(id, "getConfig", {
|
|
70
|
+
color: ((_a = this.config.theme) == null ? void 0 : _a.color) || "default",
|
|
71
|
+
theme: ((_b = this.config.theme) == null ? void 0 : _b.darkMode) || "light",
|
|
72
|
+
language: this.config.language || "fa"
|
|
73
|
+
});
|
|
74
|
+
}
|
|
99
75
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
76
|
+
handleOpenLink(data) {
|
|
77
|
+
if (this.config.linkHandler) {
|
|
78
|
+
this.config.linkHandler(data.link);
|
|
79
|
+
} else {
|
|
80
|
+
console.warn("[SamanDesk] openLink requested but no linkHandler configured.");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
handleSetGuestReadyEvent() {
|
|
84
|
+
this.isReady = true;
|
|
85
|
+
if (this.config.onGuestReady) {
|
|
86
|
+
this.config.onGuestReady();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
handleCloseFromInside() {
|
|
90
|
+
this.close();
|
|
105
91
|
}
|
|
106
|
-
|
|
92
|
+
// To be implemented by adapters
|
|
93
|
+
sendMessage(message) {
|
|
94
|
+
throw new Error("sendMessage not implemented");
|
|
95
|
+
}
|
|
96
|
+
// To be implemented by adapters
|
|
107
97
|
close() {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
backdrop2.onclick = null;
|
|
112
|
-
document.body.removeChild(getFrame());
|
|
113
|
-
window.dispatchEvent(getCloseEvent());
|
|
114
|
-
}
|
|
115
|
-
/** اطلاعات کتابخانه را به بیرون اطلاع میدهد */
|
|
116
|
-
getConfig(data) {
|
|
117
|
-
const themeData = getTheme();
|
|
118
|
-
const languageData = getLanguage();
|
|
119
|
-
resolveRun(data.id, { color: themeData.color, theme: themeData.theme, language: languageData.language }, data.action);
|
|
120
|
-
}
|
|
121
|
-
/** لینک موردنظر را به وسیلهی تابع از پیش تعریفشده باز میکند */
|
|
122
|
-
openLink(data) {
|
|
123
|
-
getOpenLinkFn()(data.data.link);
|
|
124
|
-
}
|
|
125
|
-
setGuestReadyEvent() {
|
|
126
|
-
window.dispatchEvent(setGuestReadyEvent());
|
|
98
|
+
if (this.config.onClose) {
|
|
99
|
+
this.config.onClose();
|
|
100
|
+
}
|
|
127
101
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
102
|
+
// To be implemented by adapters
|
|
103
|
+
open(link) {
|
|
104
|
+
if (this.config.onOpen) {
|
|
105
|
+
this.config.onOpen();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// To be implemented by adapters
|
|
109
|
+
destroy() {
|
|
110
|
+
}
|
|
111
|
+
post(action, data = {}) {
|
|
112
|
+
this.sendMessage({ from: "SamanDesk", action, data });
|
|
113
|
+
}
|
|
114
|
+
run(action, data = {}) {
|
|
115
|
+
const id = ++this.promiseCount;
|
|
116
|
+
this.sendMessage({ from: "SamanDesk", action, data, id });
|
|
117
|
+
return new Promise((resolve) => {
|
|
118
|
+
this.runPromises[id] = resolve;
|
|
142
119
|
});
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
this.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
document.body.appendChild(backdrop2);
|
|
155
|
-
document.body.appendChild(frame2);
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* استایل مربوط به آیفریم را تنظیم میکند
|
|
159
|
-
*
|
|
160
|
-
* @param fullScreen - تمام صفحه باز شود یا خیر
|
|
161
|
-
*
|
|
162
|
-
*/
|
|
163
|
-
setStyle() {
|
|
120
|
+
}
|
|
121
|
+
sendResponse(id, action, data) {
|
|
122
|
+
this.sendMessage({ from: "SamanDesk", action, data, id });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function createSamanDeskWeb(config, options = {}) {
|
|
126
|
+
const frame = document.createElement("iframe");
|
|
127
|
+
const backdrop = document.createElement("div");
|
|
128
|
+
let isFrameAttached = false;
|
|
129
|
+
const core = new SamanDeskCore(config);
|
|
130
|
+
const applyStyles = () => {
|
|
164
131
|
var _a, _b, _c, _d;
|
|
165
|
-
|
|
166
|
-
const backdrop2 = getBackdrop();
|
|
167
|
-
frame2.style.position = "fixed";
|
|
168
|
-
frame2.style.zIndex = "1000";
|
|
169
|
-
const backdropStyles = {
|
|
132
|
+
Object.assign(backdrop.style, {
|
|
170
133
|
position: "fixed",
|
|
171
134
|
top: "0",
|
|
172
135
|
bottom: "0",
|
|
173
136
|
left: "0",
|
|
174
137
|
right: "0",
|
|
175
138
|
backgroundColor: "rgba(0,0,0,0.5)",
|
|
176
|
-
zIndex: "1000"
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
139
|
+
zIndex: "1000",
|
|
140
|
+
display: "none"
|
|
141
|
+
});
|
|
142
|
+
Object.assign(frame.style, {
|
|
143
|
+
position: "fixed",
|
|
144
|
+
zIndex: "1000",
|
|
145
|
+
border: "none",
|
|
146
|
+
display: "none"
|
|
147
|
+
});
|
|
148
|
+
if (options.fullScreen) {
|
|
149
|
+
const marginTopVal = ((_a = options.style) == null ? void 0 : _a.marginTop) ?? 0;
|
|
150
|
+
const marginBottomVal = ((_b = options.style) == null ? void 0 : _b.marginBottom) ?? 0;
|
|
182
151
|
const totalMargin = marginTopVal + marginBottomVal;
|
|
183
|
-
Object.assign(
|
|
184
|
-
bottom:
|
|
152
|
+
Object.assign(frame.style, {
|
|
153
|
+
bottom: `${marginBottomVal}px`,
|
|
185
154
|
left: "0",
|
|
186
|
-
top:
|
|
155
|
+
top: `${marginTopVal}px`,
|
|
187
156
|
right: "0",
|
|
188
157
|
width: "100%",
|
|
189
158
|
height: `calc(100% - ${totalMargin}px)`
|
|
190
159
|
});
|
|
191
160
|
} else {
|
|
192
|
-
Object.assign(
|
|
161
|
+
Object.assign(frame.style, {
|
|
193
162
|
top: "50%",
|
|
194
163
|
left: "50%",
|
|
195
164
|
transform: "translate(-50%, -50%)",
|
|
196
|
-
width: "100%",
|
|
165
|
+
width: ((_c = options.style) == null ? void 0 : _c.width) || "100%",
|
|
197
166
|
maxWidth: "500px",
|
|
198
167
|
boxShadow: "0px 0px 100px 0px rgba(0,0,0,0.48)",
|
|
199
168
|
borderRadius: "24px",
|
|
200
|
-
height: "100%",
|
|
169
|
+
height: ((_d = options.style) == null ? void 0 : _d.height) || "100%",
|
|
201
170
|
maxHeight: "660px"
|
|
202
171
|
});
|
|
203
172
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
173
|
+
};
|
|
174
|
+
const attachFrame = () => {
|
|
175
|
+
if (!isFrameAttached) {
|
|
176
|
+
applyStyles();
|
|
177
|
+
document.body.appendChild(backdrop);
|
|
178
|
+
document.body.appendChild(frame);
|
|
179
|
+
backdrop.onclick = () => webApi.close();
|
|
180
|
+
window.addEventListener("message", handleMessage);
|
|
181
|
+
isFrameAttached = true;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
const detachFrame = () => {
|
|
185
|
+
if (isFrameAttached) {
|
|
186
|
+
document.body.removeChild(backdrop);
|
|
187
|
+
document.body.removeChild(frame);
|
|
188
|
+
window.removeEventListener("message", handleMessage);
|
|
189
|
+
isFrameAttached = false;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
const show = (src) => {
|
|
193
|
+
attachFrame();
|
|
194
|
+
frame.src = src;
|
|
195
|
+
frame.style.display = "block";
|
|
196
|
+
if (!options.fullScreen) {
|
|
197
|
+
backdrop.style.display = "block";
|
|
198
|
+
}
|
|
199
|
+
if (config.onOpen) config.onOpen();
|
|
200
|
+
};
|
|
201
|
+
const hide = () => {
|
|
202
|
+
frame.src = "about:blank";
|
|
203
|
+
frame.style.display = "none";
|
|
204
|
+
backdrop.style.display = "none";
|
|
205
|
+
if (config.onClose) config.onClose();
|
|
206
|
+
};
|
|
207
|
+
const handleMessage = (event) => {
|
|
208
|
+
core.handleIncomingMessage(event.data);
|
|
209
|
+
};
|
|
210
|
+
core.sendMessage = (message) => {
|
|
211
|
+
if (frame.contentWindow) {
|
|
212
|
+
frame.contentWindow.postMessage(message, config.siteUrl || "*");
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
const webApi = {
|
|
216
|
+
open: (link) => {
|
|
217
|
+
show(core.getOpenUrl(link));
|
|
218
|
+
},
|
|
219
|
+
close: () => {
|
|
220
|
+
hide();
|
|
221
|
+
},
|
|
222
|
+
destroy: () => {
|
|
223
|
+
hide();
|
|
224
|
+
detachFrame();
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
const initialSrc = core.getInitialUrl();
|
|
228
|
+
frame.src = initialSrc;
|
|
229
|
+
if (!config.verifiedToken) {
|
|
230
|
+
show(initialSrc);
|
|
231
|
+
} else {
|
|
232
|
+
attachFrame();
|
|
233
|
+
frame.style.width = "0";
|
|
234
|
+
frame.style.height = "0";
|
|
235
|
+
frame.style.display = "block";
|
|
209
236
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
close() {
|
|
223
|
-
var _a;
|
|
224
|
-
(_a = this.interoperation) == null ? void 0 : _a.close();
|
|
237
|
+
return webApi;
|
|
238
|
+
}
|
|
239
|
+
function createSamanDeskReactNative(config, options) {
|
|
240
|
+
class SamanDeskCoreReactNative extends SamanDeskCore {
|
|
241
|
+
sendMessage(message) {
|
|
242
|
+
const script = `
|
|
243
|
+
window.dispatchEvent(new MessageEvent('message', {
|
|
244
|
+
data: ${JSON.stringify(message)}
|
|
245
|
+
}));
|
|
246
|
+
`;
|
|
247
|
+
options.injectJavaScript(script);
|
|
248
|
+
}
|
|
225
249
|
}
|
|
250
|
+
const core = new SamanDeskCoreReactNative(config);
|
|
251
|
+
const updateState = (updater) => {
|
|
252
|
+
const newState = {
|
|
253
|
+
source: { uri: "" },
|
|
254
|
+
visible: false,
|
|
255
|
+
...updater(currentState)
|
|
256
|
+
};
|
|
257
|
+
currentState = newState;
|
|
258
|
+
options.onStateChange(currentState);
|
|
259
|
+
};
|
|
260
|
+
const initialUrl = core.getInitialUrl();
|
|
261
|
+
let currentState = {
|
|
262
|
+
source: { uri: initialUrl },
|
|
263
|
+
visible: !config.verifiedToken
|
|
264
|
+
};
|
|
265
|
+
const rnApi = {
|
|
266
|
+
getState: () => {
|
|
267
|
+
return currentState;
|
|
268
|
+
},
|
|
269
|
+
open: (link) => {
|
|
270
|
+
updateState((prev) => ({
|
|
271
|
+
...prev,
|
|
272
|
+
source: { uri: core.getOpenUrl(link) },
|
|
273
|
+
visible: true
|
|
274
|
+
}));
|
|
275
|
+
if (config.onOpen) config.onOpen();
|
|
276
|
+
},
|
|
277
|
+
close: () => {
|
|
278
|
+
updateState((prev) => ({
|
|
279
|
+
...prev,
|
|
280
|
+
visible: false,
|
|
281
|
+
source: { uri: "about:blank" }
|
|
282
|
+
}));
|
|
283
|
+
if (config.onClose) config.onClose();
|
|
284
|
+
},
|
|
285
|
+
destroy: () => {
|
|
286
|
+
rnApi.close();
|
|
287
|
+
},
|
|
288
|
+
getWebViewProps: () => ({
|
|
289
|
+
// source: currentState.source,
|
|
290
|
+
onMessage: (event) => {
|
|
291
|
+
try {
|
|
292
|
+
core.handleIncomingMessage(JSON.parse(event.nativeEvent.data));
|
|
293
|
+
} catch (error) {
|
|
294
|
+
console.error(
|
|
295
|
+
"[SamanDesk-RN] Error parsing incoming message:",
|
|
296
|
+
error
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// onLoadEnd: () => {
|
|
301
|
+
// // Potentially useful for signaling when the webview has loaded initial content
|
|
302
|
+
// },
|
|
303
|
+
// javaScriptEnabled: true,
|
|
304
|
+
// originWhitelist: ["*"], // Be more specific in production
|
|
305
|
+
})
|
|
306
|
+
};
|
|
307
|
+
return rnApi;
|
|
226
308
|
}
|
|
227
309
|
export {
|
|
228
|
-
|
|
310
|
+
createSamanDeskReactNative,
|
|
311
|
+
createSamanDeskWeb
|
|
229
312
|
};
|
package/dist/saman-desk.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,
|
|
1
|
+
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).SamanDesk={})}(this,(function(e){"use strict";const n={};class t{constructor(e){this.runPromises={},this.promiseCount=0,this.isReady=!1,this.config={siteUrl:this.defaultSiteUrl,language:"fa",theme:{darkMode:"light",color:"default"},...e}}get defaultSiteUrl(){return"1"===(null==n?void 0:n.VITE_DEV_MODE)?"http://localhost:2525":"https://samandesk.com"}getInitialUrl(){return this.config.verifiedToken?`${this.config.siteUrl}/setup-interoperation/${this.config.verifiedToken}`:`${this.config.siteUrl}/guest-login/${this.config.workspaceID}`}getOpenUrl(e){return e||`${this.config.siteUrl}/department-selection?token=${this.token}`}handleIncomingMessage(e){if(!e||"SamanDesk"!==e.from)return;const{action:n,id:t,data:s}=e;if(void 0!==t&&this.runPromises[t])return this.runPromises[t](s),void delete this.runPromises[t];switch(n){case"setToken":this.handleSetToken(s);break;case"getConfig":this.handleGetConfig(t);break;case"openLink":this.handleOpenLink(s);break;case"setGuestReadyEvent":this.handleSetGuestReadyEvent();break;case"close":this.handleCloseFromInside();break;default:console.warn(`[SamanDesk] Unhandled action: ${n}`)}}handleSetToken(e){e&&e.token&&(this.token=e.token,this.isReady=!0,this.config.onReady&&this.config.onReady(this.token),this.config.onTokenChange&&this.config.onTokenChange(this.token))}handleGetConfig(e){var n,t;void 0!==e&&this.sendResponse(e,"getConfig",{color:(null==(n=this.config.theme)?void 0:n.color)||"default",theme:(null==(t=this.config.theme)?void 0:t.darkMode)||"light",language:this.config.language||"fa"})}handleOpenLink(e){this.config.linkHandler?this.config.linkHandler(e.link):console.warn("[SamanDesk] openLink requested but no linkHandler configured.")}handleSetGuestReadyEvent(){this.isReady=!0,this.config.onGuestReady&&this.config.onGuestReady()}handleCloseFromInside(){this.close()}sendMessage(e){throw new Error("sendMessage not implemented")}close(){this.config.onClose&&this.config.onClose()}open(e){this.config.onOpen&&this.config.onOpen()}destroy(){}post(e,n={}){this.sendMessage({from:"SamanDesk",action:e,data:n})}run(e,n={}){const t=++this.promiseCount;return this.sendMessage({from:"SamanDesk",action:e,data:n,id:t}),new Promise((e=>{this.runPromises[t]=e}))}sendResponse(e,n,t){this.sendMessage({from:"SamanDesk",action:n,data:t,id:e})}}e.createSamanDeskReactNative=function(e,n){const s=new class extends t{sendMessage(e){const t=`\n window.dispatchEvent(new MessageEvent('message', {\n data: ${JSON.stringify(e)}\n }));\n `;n.injectJavaScript(t)}}(e),o=e=>{const t={source:{uri:""},visible:!1,...e(i)};i=t,n.onStateChange(i)};let i={source:{uri:s.getInitialUrl()},visible:!e.verifiedToken};const a={getState:()=>i,open:n=>{o((e=>({...e,source:{uri:s.getOpenUrl(n)},visible:!0}))),e.onOpen&&e.onOpen()},close:()=>{o((e=>({...e,visible:!1,source:{uri:"about:blank"}}))),e.onClose&&e.onClose()},destroy:()=>{a.close()},getWebViewProps:()=>({onMessage:e=>{try{s.handleIncomingMessage(JSON.parse(e.nativeEvent.data))}catch(n){console.error("[SamanDesk-RN] Error parsing incoming message:",n)}}})};return a},e.createSamanDeskWeb=function(e,n={}){const s=document.createElement("iframe"),o=document.createElement("div");let i=!1;const a=new t(e),l=()=>{i||((()=>{var e,t,i,a;if(Object.assign(o.style,{position:"fixed",top:"0",bottom:"0",left:"0",right:"0",backgroundColor:"rgba(0,0,0,0.5)",zIndex:"1000",display:"none"}),Object.assign(s.style,{position:"fixed",zIndex:"1000",border:"none",display:"none"}),n.fullScreen){const o=(null==(e=n.style)?void 0:e.marginTop)??0,i=(null==(t=n.style)?void 0:t.marginBottom)??0,a=o+i;Object.assign(s.style,{bottom:`${i}px`,left:"0",top:`${o}px`,right:"0",width:"100%",height:`calc(100% - ${a}px)`})}else Object.assign(s.style,{top:"50%",left:"50%",transform:"translate(-50%, -50%)",width:(null==(i=n.style)?void 0:i.width)||"100%",maxWidth:"500px",boxShadow:"0px 0px 100px 0px rgba(0,0,0,0.48)",borderRadius:"24px",height:(null==(a=n.style)?void 0:a.height)||"100%",maxHeight:"660px"})})(),document.body.appendChild(o),document.body.appendChild(s),o.onclick=()=>h.close(),window.addEventListener("message",c),i=!0)},r=t=>{l(),s.src=t,s.style.display="block",n.fullScreen||(o.style.display="block"),e.onOpen&&e.onOpen()},d=()=>{s.src="about:blank",s.style.display="none",o.style.display="none",e.onClose&&e.onClose()},c=e=>{a.handleIncomingMessage(e.data)};a.sendMessage=n=>{s.contentWindow&&s.contentWindow.postMessage(n,e.siteUrl||"*")};const h={open:e=>{r(a.getOpenUrl(e))},close:()=>{d()},destroy:()=>{d(),i&&(document.body.removeChild(o),document.body.removeChild(s),window.removeEventListener("message",c),i=!1)}},g=a.getInitialUrl();return s.src=g,e.verifiedToken?(l(),s.style.width="0",s.style.height="0",s.style.display="block"):r(g),h},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { SamanDeskConfig } from '../../core/types';
|
|
2
|
+
interface ReactNativeState {
|
|
3
|
+
source: {
|
|
4
|
+
uri: string;
|
|
5
|
+
};
|
|
6
|
+
visible: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface ReactNativeOptions {
|
|
9
|
+
onStateChange: (state: ReactNativeState) => void;
|
|
10
|
+
injectJavaScript: (script: string) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function createSamanDeskReactNative(config: SamanDeskConfig, options: ReactNativeOptions): {
|
|
13
|
+
getState: () => {
|
|
14
|
+
source: {
|
|
15
|
+
uri: string;
|
|
16
|
+
};
|
|
17
|
+
visible: boolean;
|
|
18
|
+
};
|
|
19
|
+
open: (link?: string) => void;
|
|
20
|
+
close: () => void;
|
|
21
|
+
destroy: () => void;
|
|
22
|
+
getWebViewProps: () => {
|
|
23
|
+
onMessage: (event: {
|
|
24
|
+
nativeEvent: {
|
|
25
|
+
data: string;
|
|
26
|
+
};
|
|
27
|
+
}) => void;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SamanDeskConfig } from '../../core/types';
|
|
2
|
+
interface WebOptions {
|
|
3
|
+
fullScreen?: boolean;
|
|
4
|
+
style?: {
|
|
5
|
+
marginTop?: number;
|
|
6
|
+
marginBottom?: number;
|
|
7
|
+
width?: string;
|
|
8
|
+
height?: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare function createSamanDeskWeb(config: SamanDeskConfig, options?: WebOptions): {
|
|
12
|
+
open: (link?: string) => void;
|
|
13
|
+
close: () => void;
|
|
14
|
+
destroy: () => void;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { SamanDeskConfig, OutgoingMessage } from './types';
|
|
2
|
+
export declare class SamanDeskCore {
|
|
3
|
+
config: SamanDeskConfig;
|
|
4
|
+
protected token?: string;
|
|
5
|
+
protected runPromises: Record<number, (data: any) => void>;
|
|
6
|
+
protected promiseCount: number;
|
|
7
|
+
isReady: boolean;
|
|
8
|
+
protected get defaultSiteUrl(): "http://localhost:2525" | "https://samandesk.com";
|
|
9
|
+
constructor(config: SamanDeskConfig);
|
|
10
|
+
getInitialUrl(): string;
|
|
11
|
+
getOpenUrl(link?: string): string;
|
|
12
|
+
handleIncomingMessage(message: any): void;
|
|
13
|
+
protected handleSetToken(data: {
|
|
14
|
+
token?: string;
|
|
15
|
+
}): void;
|
|
16
|
+
protected handleGetConfig(id?: number): void;
|
|
17
|
+
protected handleOpenLink(data: {
|
|
18
|
+
link: string;
|
|
19
|
+
}): void;
|
|
20
|
+
protected handleSetGuestReadyEvent(): void;
|
|
21
|
+
protected handleCloseFromInside(): void;
|
|
22
|
+
protected sendMessage(message: OutgoingMessage): void;
|
|
23
|
+
close(): void;
|
|
24
|
+
open(link?: string): void;
|
|
25
|
+
destroy(): void;
|
|
26
|
+
protected post(action: string, data?: object): void;
|
|
27
|
+
protected run<T>(action: string, data?: object): Promise<T>;
|
|
28
|
+
protected sendResponse(id: number, action: string, data: any): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Color } from '../../library-colors';
|
|
2
|
+
export type ProjectTheme = {
|
|
3
|
+
/** روشن یا تیرهبودن تم برنامه */
|
|
4
|
+
darkMode: 'light' | 'dark';
|
|
5
|
+
/** رنگ برنامه */
|
|
6
|
+
color: Color;
|
|
7
|
+
};
|
|
8
|
+
export interface SamanDeskConfig {
|
|
9
|
+
/** شناسه محیط کاری پروژه */
|
|
10
|
+
workspaceID?: string;
|
|
11
|
+
/** توکن وریفای شده */
|
|
12
|
+
verifiedToken?: string;
|
|
13
|
+
/** تم کتابخانه شامل :
|
|
14
|
+
* روشن یا تیره بودن کتابخانه
|
|
15
|
+
* رنگ تم کتابخانه
|
|
16
|
+
*/
|
|
17
|
+
theme?: Partial<ProjectTheme>;
|
|
18
|
+
/** زبان کتابخانه */
|
|
19
|
+
language?: 'fa' | 'en' | 'ar' | string;
|
|
20
|
+
/** آدرس سرور */
|
|
21
|
+
siteUrl?: string;
|
|
22
|
+
/** تابع مدیریتکنندهی لینکها */
|
|
23
|
+
linkHandler?: (link: string) => void;
|
|
24
|
+
/** زمانی که کتابخانه آماده شد */
|
|
25
|
+
onReady?: (token: string) => void;
|
|
26
|
+
/** وقتی که توکن عوض میشه */
|
|
27
|
+
onTokenChange?: (token: string) => void;
|
|
28
|
+
/** باز شدن کتابخانه */
|
|
29
|
+
onOpen?: () => void;
|
|
30
|
+
/** بسته شدن کتابخانه */
|
|
31
|
+
onClose?: () => void;
|
|
32
|
+
/** آماده شدن گست */
|
|
33
|
+
onGuestReady?: () => void;
|
|
34
|
+
/** هندل کردن ارور ها */
|
|
35
|
+
onError?: (error: Error) => void;
|
|
36
|
+
}
|
|
37
|
+
export type MessageData<T = {}> = {
|
|
38
|
+
/** شناسه داده */
|
|
39
|
+
id: number;
|
|
40
|
+
/** تابعی که داده برای آن ارسال شده است */
|
|
41
|
+
action: string;
|
|
42
|
+
/** داده موردنظر */
|
|
43
|
+
data: T;
|
|
44
|
+
};
|
|
45
|
+
export interface OutgoingMessage {
|
|
46
|
+
from: 'SamanDesk';
|
|
47
|
+
action: string;
|
|
48
|
+
data?: any;
|
|
49
|
+
id?: number;
|
|
50
|
+
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,53 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
* کتابخانه به صورت تمام صفحه باز شود یا خیر
|
|
5
|
-
*
|
|
6
|
-
* اگر تمام صفحه شود، از اطراف هیچ فضای خالیای وجود نخواهد داشت و در غیر اینصورت، در وسط صفحه قرار خواهدگرفت
|
|
7
|
-
* در این حالت یک overlay پشت کتابخانه قرار خواهد گرفت
|
|
8
|
-
*/
|
|
9
|
-
fullScreen: boolean;
|
|
10
|
-
/** تم کتابخانه شامل :
|
|
11
|
-
* روشن یا تیره بودن کتابخانه
|
|
12
|
-
* رنگ تم کتابخانه
|
|
13
|
-
*/
|
|
14
|
-
theme: Partial<ProjectTheme>;
|
|
15
|
-
/** زبان کتابیخانه */
|
|
16
|
-
language: string;
|
|
17
|
-
/** تابع مدیریتکنندهی لینکها */
|
|
18
|
-
linkHandler?: (link: string) => void;
|
|
19
|
-
/** شناسه محیط کاری پروژه */
|
|
20
|
-
workspaceID?: string;
|
|
21
|
-
style?: {
|
|
22
|
-
/** فاصله از بالا در حالت تمام صفحه */
|
|
23
|
-
marginTop?: number;
|
|
24
|
-
/** فاصله از پایین در حالت تمام صفحه */
|
|
25
|
-
marginBottom?: number;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
export declare class SamanDesk {
|
|
29
|
-
/**
|
|
30
|
-
* شیء کلاس InterOperation
|
|
31
|
-
*/
|
|
32
|
-
private interoperation?;
|
|
33
|
-
private config;
|
|
34
|
-
/**
|
|
35
|
-
* این تابع در ابتدا مقدار verifiedToken را دریافت کرده و سپس مقدار token را دریافت و سپس آن را ذخیره میکند
|
|
36
|
-
*/
|
|
37
|
-
init(config: OpenConfig, verifiedToken?: string): Promise<void>;
|
|
38
|
-
/**
|
|
39
|
-
* استایل مربوط به آیفریم را تنظیم میکند
|
|
40
|
-
*
|
|
41
|
-
* @param fullScreen - تمام صفحه باز شود یا خیر
|
|
42
|
-
*
|
|
43
|
-
*/
|
|
44
|
-
private setStyle;
|
|
45
|
-
/**
|
|
46
|
-
* این تابع آیفریم را باز میکند.
|
|
47
|
-
*/
|
|
48
|
-
open(link?: string): void;
|
|
49
|
-
/**
|
|
50
|
-
* بستن کتابخانه
|
|
51
|
-
*/
|
|
52
|
-
close(): void;
|
|
53
|
-
}
|
|
1
|
+
export * from './core/types';
|
|
2
|
+
export { createSamanDeskWeb } from './adapters/web';
|
|
3
|
+
export { createSamanDeskReactNative } from './adapters/react-native';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "samandesk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -11,19 +11,20 @@
|
|
|
11
11
|
"types": "./dist/src/index.d.ts",
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
+
"types": "./dist/src/index.d.ts",
|
|
14
15
|
"import": "./dist/saman-desk.js",
|
|
15
|
-
"require": "./dist/saman-desk.umd.cjs"
|
|
16
|
-
"types": "./dist/src/index.d.ts"
|
|
16
|
+
"require": "./dist/saman-desk.umd.cjs"
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
20
20
|
"start": "yarn link && cross-env VITE_DEV_MODE=1 yarn vite build --watch",
|
|
21
|
-
"prepublish": "vite build"
|
|
21
|
+
"prepublish": "cross-env VITE_DEV_MODE=0 vite build"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"cross-env": "^7.0.3",
|
|
25
25
|
"terser": "^5.39.0",
|
|
26
26
|
"typescript": "^5.8.3",
|
|
27
|
+
"uncrypto": "^0.1.3",
|
|
27
28
|
"utility-types": "^3.11.0",
|
|
28
29
|
"vite": "^6.3.3",
|
|
29
30
|
"vite-plugin-dts": "^4.5.3"
|
package/dist/src/data.d.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { Color } from '../library-colors';
|
|
2
|
-
export type ProjectTheme = {
|
|
3
|
-
/** روشن یا تیرهبودن تم برنامه */
|
|
4
|
-
darkMode: 'light' | 'dark';
|
|
5
|
-
/** رنگ برنامه */
|
|
6
|
-
color: Color;
|
|
7
|
-
};
|
|
8
|
-
export type GuestData = {
|
|
9
|
-
mobile: string;
|
|
10
|
-
name?: string;
|
|
11
|
-
family: string;
|
|
12
|
-
countryCode: string;
|
|
13
|
-
verifyToken: string;
|
|
14
|
-
workspaceID: string;
|
|
15
|
-
};
|
|
16
|
-
type PromiseMap = {
|
|
17
|
-
[key: number]: (data: any) => void;
|
|
18
|
-
};
|
|
19
|
-
/** آبجکت پرامیسهای منتظر اجرا */
|
|
20
|
-
export declare function getRun(): {
|
|
21
|
-
count: number;
|
|
22
|
-
promises: PromiseMap;
|
|
23
|
-
};
|
|
24
|
-
/** تنظیم تعداد پرامیسهای منتظر اجرا */
|
|
25
|
-
export declare function setRunCount(count: number): void;
|
|
26
|
-
/** تنظیم پرامیسهای منتظر اجرا */
|
|
27
|
-
export declare function setRunPromises(promises: PromiseMap): void;
|
|
28
|
-
/** تنظیم کردن توکن */
|
|
29
|
-
export declare function setToken(newToken: string): void;
|
|
30
|
-
/** توکن را بر میگرداند */
|
|
31
|
-
export declare function getToken(): string | undefined;
|
|
32
|
-
/** تگ iframe را حذف میکند */
|
|
33
|
-
export declare function clearFrame(): void;
|
|
34
|
-
/** مقدار src تگ iframe را براساس ورودی تنظیم میکند */
|
|
35
|
-
export declare function setFrameSrc(src: string): void;
|
|
36
|
-
/** تگ iframe را بر میگرداند */
|
|
37
|
-
export declare function getFrame(): HTMLIFrameElement;
|
|
38
|
-
export declare function setGuestData(data: GuestData): void;
|
|
39
|
-
export declare function getGuestData(): GuestData | undefined;
|
|
40
|
-
export declare function clearGuestData(): void;
|
|
41
|
-
/** تم و رنگ کتابخانه را بر میگرداند */
|
|
42
|
-
export declare function getTheme(): {
|
|
43
|
-
theme: "light" | "dark" | undefined;
|
|
44
|
-
color: Color;
|
|
45
|
-
};
|
|
46
|
-
/** زبان کتابخانه را بر میگرداند */
|
|
47
|
-
export declare function getLanguage(): {
|
|
48
|
-
language: string;
|
|
49
|
-
};
|
|
50
|
-
/** تم و رنگ جدید کتابخانه را تنظیم میکند */
|
|
51
|
-
export declare function setTheme(newTheme: ProjectTheme): void;
|
|
52
|
-
/** زبان جدید کتابخانه را تنظیم میکند */
|
|
53
|
-
export declare function setLanguage(newLanguage: string): void;
|
|
54
|
-
/** عنصر بکدراپ را برمیگرداند */
|
|
55
|
-
export declare function getBackdrop(): HTMLDivElement;
|
|
56
|
-
/** تابع مدیریتکنندهی لینکها را ست میکند */
|
|
57
|
-
export declare function setOpenLinkFn(fn?: (link: string) => void): void;
|
|
58
|
-
/** تابع مدیریتکنندهی لینکها را برمیگرداند */
|
|
59
|
-
export declare function getOpenLinkFn(): (link: string) => void;
|
|
60
|
-
export {};
|
package/dist/src/events.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { InterOperation } from './interoperation';
|
|
2
|
-
/**
|
|
3
|
-
* ایونت آمادهشدن توکن را بر میگرداند
|
|
4
|
-
*/
|
|
5
|
-
export declare function getReadyEvent(): Event;
|
|
6
|
-
/**
|
|
7
|
-
* ایونت بازشدن کتابخانه را بر میگرداند
|
|
8
|
-
*/
|
|
9
|
-
export declare function getOpenEvent(): Event;
|
|
10
|
-
/**
|
|
11
|
-
* ایونت بستهشدن کتابخانه را بر میگرداند
|
|
12
|
-
*/
|
|
13
|
-
export declare function getCloseEvent(): Event;
|
|
14
|
-
/**
|
|
15
|
-
* ایونت آمادهشدن حالت مهمان را بر میگرداند
|
|
16
|
-
*/
|
|
17
|
-
export declare function setGuestReadyEvent(): Event;
|
|
18
|
-
/**
|
|
19
|
-
* eventهایی که از بیرون به داخل میایند را اعتبار سنجی و سپس کار خواسته شده را انجام میدهد
|
|
20
|
-
*/
|
|
21
|
-
export declare function handleEvents(interoperation: InterOperation): void;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { FunctionKeys } from 'utility-types';
|
|
2
|
-
type MessageData<T = {}> = {
|
|
3
|
-
/** شناسه داده */
|
|
4
|
-
id: number;
|
|
5
|
-
/** تابعی که داده برای آن ارسال شده است */
|
|
6
|
-
action: string;
|
|
7
|
-
/** داده موردنظر */
|
|
8
|
-
data: T;
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* این تابع برای فراخوانی متدهاییست که مقداری بر نمیگردانند
|
|
12
|
-
*/
|
|
13
|
-
export declare function post(action: string, data?: object): void;
|
|
14
|
-
/**
|
|
15
|
-
* این تابع برای فراخوانی متدهاییست که مقدار بر میگردانند
|
|
16
|
-
*/
|
|
17
|
-
export declare function run<A extends FunctionKeys<InterOperation>>(action: A, data?: object): Promise<ReturnType<InterOperation[A]>>;
|
|
18
|
-
export declare class InterOperation {
|
|
19
|
-
init(): Promise<void>;
|
|
20
|
-
/** توکن را از میزبان دریافت کرده و آن را ذخیره میکند. سپس به میزبان اعلام میکند که آمادهی ادامهی کار است */
|
|
21
|
-
setToken(data: MessageData<{
|
|
22
|
-
token: string;
|
|
23
|
-
}>): void;
|
|
24
|
-
/** بستن کتابخانه */
|
|
25
|
-
close(): void;
|
|
26
|
-
/** اطلاعات کتابخانه را به بیرون اطلاع میدهد */
|
|
27
|
-
getConfig(data: MessageData): void;
|
|
28
|
-
/** لینک موردنظر را به وسیلهی تابع از پیش تعریفشده باز میکند */
|
|
29
|
-
openLink(data: MessageData<{
|
|
30
|
-
link: string;
|
|
31
|
-
}>): void;
|
|
32
|
-
setGuestReadyEvent(): void;
|
|
33
|
-
}
|
|
34
|
-
export {};
|