@superleapai/flow-ui 2.5.13 → 2.5.15
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/core/bridge.js +24 -55
- package/core/crm.js +32 -27
- package/core/superleapClient.js +3 -77
- package/dist/superleap-flow.js +271 -2227
- package/dist/superleap-flow.js.map +1 -1
- package/dist/superleap-flow.min.js +2 -2
- package/index.js +37 -27
- package/package.json +1 -1
package/core/bridge.js
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
// Closure state (reset on each connect / disconnect cycle)
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
29
|
|
|
30
|
-
var
|
|
30
|
+
var _bridgeId = null;
|
|
31
31
|
var _nonce = null;
|
|
32
32
|
var _port = null; // MessagePort (iframe transport, post-handshake)
|
|
33
33
|
var _connected = false;
|
|
@@ -44,47 +44,6 @@
|
|
|
44
44
|
// Helpers – crypto
|
|
45
45
|
// ---------------------------------------------------------------------------
|
|
46
46
|
|
|
47
|
-
function generateUUID() {
|
|
48
|
-
// crypto.randomUUID where available (modern browsers)
|
|
49
|
-
if (
|
|
50
|
-
typeof crypto !== "undefined" &&
|
|
51
|
-
typeof crypto.randomUUID === "function"
|
|
52
|
-
) {
|
|
53
|
-
return crypto.randomUUID();
|
|
54
|
-
}
|
|
55
|
-
// Fallback: manual v4 UUID via getRandomValues or Math.random
|
|
56
|
-
var bytes;
|
|
57
|
-
if (
|
|
58
|
-
typeof crypto !== "undefined" &&
|
|
59
|
-
typeof crypto.getRandomValues === "function"
|
|
60
|
-
) {
|
|
61
|
-
bytes = new Uint8Array(16);
|
|
62
|
-
crypto.getRandomValues(bytes);
|
|
63
|
-
} else {
|
|
64
|
-
bytes = new Uint8Array(16);
|
|
65
|
-
for (var i = 0; i < 16; i++) {
|
|
66
|
-
bytes[i] = (Math.random() * 256) | 0;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4
|
|
70
|
-
bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 1
|
|
71
|
-
var hex = [];
|
|
72
|
-
for (var j = 0; j < 16; j++) {
|
|
73
|
-
hex.push(("0" + bytes[j].toString(16)).slice(-2));
|
|
74
|
-
}
|
|
75
|
-
return (
|
|
76
|
-
hex.slice(0, 4).join("") +
|
|
77
|
-
"-" +
|
|
78
|
-
hex.slice(4, 6).join("") +
|
|
79
|
-
"-" +
|
|
80
|
-
hex.slice(6, 8).join("") +
|
|
81
|
-
"-" +
|
|
82
|
-
hex.slice(8, 10).join("") +
|
|
83
|
-
"-" +
|
|
84
|
-
hex.slice(10).join("")
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
47
|
function generateNonce() {
|
|
89
48
|
var bytes;
|
|
90
49
|
if (
|
|
@@ -135,7 +94,7 @@
|
|
|
135
94
|
function createEnvelope(action, payload) {
|
|
136
95
|
return {
|
|
137
96
|
type: MESSAGE_TYPE,
|
|
138
|
-
|
|
97
|
+
bridgeId: _bridgeId,
|
|
139
98
|
action: action,
|
|
140
99
|
payload: payload || {},
|
|
141
100
|
};
|
|
@@ -185,8 +144,8 @@
|
|
|
185
144
|
function handleIncomingMessage(data, origin) {
|
|
186
145
|
// Ignore messages that aren't ours
|
|
187
146
|
if (!data || data.type !== MESSAGE_TYPE) return;
|
|
188
|
-
// Ignore messages for a different
|
|
189
|
-
if (data.
|
|
147
|
+
// Ignore messages for a different bridge
|
|
148
|
+
if (data.bridgeId && data.bridgeId !== _bridgeId) return;
|
|
190
149
|
|
|
191
150
|
var action = data.action;
|
|
192
151
|
|
|
@@ -319,7 +278,7 @@
|
|
|
319
278
|
if (_transport === "react-native" && global.__superleapBridge) {
|
|
320
279
|
delete global.__superleapBridge;
|
|
321
280
|
}
|
|
322
|
-
|
|
281
|
+
_bridgeId = null;
|
|
323
282
|
_nonce = null;
|
|
324
283
|
_connected = false;
|
|
325
284
|
_transport = null;
|
|
@@ -337,10 +296,10 @@
|
|
|
337
296
|
* Initiate a handshake with the host CRM.
|
|
338
297
|
*
|
|
339
298
|
* @param {Object} options
|
|
340
|
-
* @param {string} options.
|
|
341
|
-
* @param {string} [options.version]
|
|
299
|
+
* @param {string} [options.bridgeId] – explicit bridgeId (auto-read from URL if omitted)
|
|
300
|
+
* @param {string} [options.version] – library version (informational)
|
|
342
301
|
* @param {string} [options.crmOrigin] – expected CRM origin for validation
|
|
343
|
-
* @param {number} [options.timeout]
|
|
302
|
+
* @param {number} [options.timeout] – handshake timeout in ms (default 5000)
|
|
344
303
|
* @returns {Promise<Object>} resolves with the CRM's handshake-ack payload
|
|
345
304
|
*/
|
|
346
305
|
function connect(options) {
|
|
@@ -362,7 +321,18 @@
|
|
|
362
321
|
return;
|
|
363
322
|
}
|
|
364
323
|
|
|
365
|
-
|
|
324
|
+
// Read bridgeId from URL query param (set by CRM) or explicit option
|
|
325
|
+
var urlParams = new URLSearchParams(global.location.search);
|
|
326
|
+
_bridgeId = opts.bridgeId || urlParams.get("_bridgeId");
|
|
327
|
+
if (!_bridgeId) {
|
|
328
|
+
reject(
|
|
329
|
+
new Error(
|
|
330
|
+
"SuperleapBridge: No _bridgeId found in URL. Is this page embedded in the SuperLeap CRM?",
|
|
331
|
+
),
|
|
332
|
+
);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
366
336
|
_nonce = generateNonce();
|
|
367
337
|
_crmOrigin = opts.crmOrigin || null;
|
|
368
338
|
_pendingResolve = resolve;
|
|
@@ -409,9 +379,8 @@
|
|
|
409
379
|
|
|
410
380
|
// --- Send handshake-request ---
|
|
411
381
|
var envelope = createEnvelope("handshake-request", {
|
|
412
|
-
flowId: opts.flowId || "",
|
|
413
|
-
version: opts.version || "",
|
|
414
382
|
nonce: _nonce,
|
|
383
|
+
version: opts.version || "",
|
|
415
384
|
});
|
|
416
385
|
sendRaw(envelope);
|
|
417
386
|
|
|
@@ -500,8 +469,8 @@
|
|
|
500
469
|
/**
|
|
501
470
|
* @returns {string|null}
|
|
502
471
|
*/
|
|
503
|
-
function
|
|
504
|
-
return
|
|
472
|
+
function getBridgeId() {
|
|
473
|
+
return _bridgeId;
|
|
505
474
|
}
|
|
506
475
|
|
|
507
476
|
// ---------------------------------------------------------------------------
|
|
@@ -515,7 +484,7 @@
|
|
|
515
484
|
onMessage: onMessage,
|
|
516
485
|
offMessage: offMessage,
|
|
517
486
|
isConnected: isConnected,
|
|
518
|
-
|
|
487
|
+
getBridgeId: getBridgeId,
|
|
519
488
|
};
|
|
520
489
|
|
|
521
490
|
if (global) {
|
package/core/crm.js
CHANGED
|
@@ -10,18 +10,9 @@
|
|
|
10
10
|
* - Context management (orgId, userId, etc.)
|
|
11
11
|
* - Custom event send / listen with namespacing
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* flowId: 'my-onboarding-form',
|
|
17
|
-
* });
|
|
18
|
-
* // SDK is now initialized, context has orgId/userId/etc.
|
|
19
|
-
*
|
|
20
|
-
* SuperLeap.toast('Record saved!', 'success');
|
|
21
|
-
* SuperLeap.closeForm();
|
|
22
|
-
*
|
|
23
|
-
* SuperLeap.on('prefill', (data) => { ... });
|
|
24
|
-
* SuperLeap.send('form-submitted', { values });
|
|
13
|
+
* The library auto-connects when loaded inside a CRM iframe (bridgeId is
|
|
14
|
+
* read from the URL). User code should listen for the 'superleap-flow:ready'
|
|
15
|
+
* event — by the time it fires, the SDK is initialized and context is available.
|
|
25
16
|
*
|
|
26
17
|
* This extends the existing SuperLeap API from superleapClient.js which
|
|
27
18
|
* already has: init(), getSdk(), isAvailable(), getDefaultConfig().
|
|
@@ -38,6 +29,7 @@
|
|
|
38
29
|
var _config = null; // full config from CRM
|
|
39
30
|
var _bridge = null; // resolved reference to SuperleapBridge
|
|
40
31
|
var _connected = false;
|
|
32
|
+
var _connectPromise = null; // in-flight connect promise (deduplication)
|
|
41
33
|
|
|
42
34
|
// Library version — sent during handshake so the CRM knows what it's talking to
|
|
43
35
|
var LIB_VERSION = "2.1.0";
|
|
@@ -100,14 +92,27 @@
|
|
|
100
92
|
* credentials and context, and (by default) auto-initializes the
|
|
101
93
|
* SuperLeap SDK.
|
|
102
94
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* @param {
|
|
107
|
-
* @param {
|
|
95
|
+
* If already connected, silently resolves with the existing context/config.
|
|
96
|
+
* If a connection is in flight (e.g. auto-connect), returns the same promise.
|
|
97
|
+
*
|
|
98
|
+
* @param {Object} [options]
|
|
99
|
+
* @param {string} [options.bridgeId] – explicit bridgeId override (auto-read from URL)
|
|
100
|
+
* @param {string} [options.crmOrigin] – expected CRM origin for validation
|
|
101
|
+
* @param {boolean} [options.autoInit] – auto-call SuperLeap.init() (default true)
|
|
102
|
+
* @param {number} [options.timeout] – handshake timeout in ms (default 5000)
|
|
108
103
|
* @returns {Promise<{ context: Object, config: Object }>}
|
|
109
104
|
*/
|
|
110
105
|
function connect(options) {
|
|
106
|
+
// Already connected — silently resolve
|
|
107
|
+
if (_connected) {
|
|
108
|
+
return Promise.resolve({ context: _context, config: _config });
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Connection in flight (e.g. auto-connect started) — return same promise
|
|
112
|
+
if (_connectPromise) {
|
|
113
|
+
return _connectPromise;
|
|
114
|
+
}
|
|
115
|
+
|
|
111
116
|
var opts = options || {};
|
|
112
117
|
var bridge = getBridge();
|
|
113
118
|
|
|
@@ -117,17 +122,9 @@
|
|
|
117
122
|
);
|
|
118
123
|
}
|
|
119
124
|
|
|
120
|
-
|
|
121
|
-
return Promise.reject(
|
|
122
|
-
new Error(
|
|
123
|
-
"SuperleapCRM: Already connected. Call disconnect() first.",
|
|
124
|
-
),
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return bridge
|
|
125
|
+
_connectPromise = bridge
|
|
129
126
|
.connect({
|
|
130
|
-
|
|
127
|
+
bridgeId: opts.bridgeId,
|
|
131
128
|
version: LIB_VERSION,
|
|
132
129
|
crmOrigin: opts.crmOrigin,
|
|
133
130
|
timeout: opts.timeout,
|
|
@@ -146,6 +143,7 @@
|
|
|
146
143
|
}
|
|
147
144
|
|
|
148
145
|
_connected = true;
|
|
146
|
+
_connectPromise = null;
|
|
149
147
|
|
|
150
148
|
// Listen for context pushes from the CRM
|
|
151
149
|
bridge.onMessage("data:context", function (newCtx) {
|
|
@@ -169,7 +167,13 @@
|
|
|
169
167
|
}
|
|
170
168
|
|
|
171
169
|
return { context: _context, config: _config };
|
|
170
|
+
})
|
|
171
|
+
.catch(function (err) {
|
|
172
|
+
_connectPromise = null;
|
|
173
|
+
throw err;
|
|
172
174
|
});
|
|
175
|
+
|
|
176
|
+
return _connectPromise;
|
|
173
177
|
}
|
|
174
178
|
|
|
175
179
|
/**
|
|
@@ -190,6 +194,7 @@
|
|
|
190
194
|
_context = null;
|
|
191
195
|
_config = null;
|
|
192
196
|
_connected = false;
|
|
197
|
+
_connectPromise = null;
|
|
193
198
|
_bridge = null;
|
|
194
199
|
}
|
|
195
200
|
|
package/core/superleapClient.js
CHANGED
|
@@ -13,79 +13,15 @@
|
|
|
13
13
|
var _config = null;
|
|
14
14
|
var _sdkInstance = null;
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
* Default config merged with user config when calling init().
|
|
18
|
-
* Matches SuperLeapSDK constructor defaults (sdk.js).
|
|
19
|
-
*/
|
|
20
|
-
var DEFAULT_CONFIG = {
|
|
21
|
-
apiKey: "NWM2MGEZMDMTYME2YI0ZYZDHLTLKNWQTNDM3NDNIZDU3YTQ1",
|
|
22
|
-
baseUrl: "https://razorpay-sandbox.superleap.dev/api/v1",
|
|
23
|
-
clientId: "",
|
|
24
|
-
clientSecret: "",
|
|
25
|
-
cache: {
|
|
26
|
-
enabled: true,
|
|
27
|
-
maxSize: 1000,
|
|
28
|
-
defaultTTL: 5 * 60 * 1000,
|
|
29
|
-
ttl: {
|
|
30
|
-
schema: 30 * 60 * 1000,
|
|
31
|
-
records: 2 * 60 * 1000,
|
|
32
|
-
count: 60 * 1000,
|
|
33
|
-
user: 10 * 60 * 1000,
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Deep-merge source into target (only own enumerable properties; arrays replaced, not merged).
|
|
40
|
-
*/
|
|
41
|
-
function mergeConfig(target, source) {
|
|
42
|
-
if (!source || typeof source !== "object") return target;
|
|
43
|
-
var result = {};
|
|
44
|
-
var key;
|
|
45
|
-
for (key in target) {
|
|
46
|
-
if (Object.prototype.hasOwnProperty.call(target, key)) {
|
|
47
|
-
result[key] = target[key];
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
for (key in source) {
|
|
51
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
52
|
-
var s = source[key];
|
|
53
|
-
var t = result[key];
|
|
54
|
-
if (
|
|
55
|
-
t &&
|
|
56
|
-
s &&
|
|
57
|
-
typeof t === "object" &&
|
|
58
|
-
typeof s === "object" &&
|
|
59
|
-
!Array.isArray(t) &&
|
|
60
|
-
!Array.isArray(s)
|
|
61
|
-
) {
|
|
62
|
-
result[key] = mergeConfig(t, s);
|
|
63
|
-
} else {
|
|
64
|
-
result[key] = s;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return result;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
16
|
/**
|
|
72
17
|
* Initialize the client with API config. Call this before using record-select or other SDK-dependent components.
|
|
73
|
-
* Config is merged with defaults; you can pass only baseUrl and apiKey.
|
|
74
18
|
*
|
|
75
19
|
* @param {Object} config - Options passed to createSuperLeapSDK (same as SuperLeapSDK constructor in sdk.js)
|
|
76
|
-
* @param {string}
|
|
77
|
-
* @param {string}
|
|
20
|
+
* @param {string} config.apiKey - Bearer token for authentication
|
|
21
|
+
* @param {string} config.baseUrl - Base URL for API
|
|
78
22
|
* @param {string} [config.clientId] - Client ID (if using client credentials)
|
|
79
23
|
* @param {string} [config.clientSecret] - Client secret (if using client credentials)
|
|
80
24
|
* @param {Object} [config.cache] - Cache configuration
|
|
81
|
-
* @param {boolean} [config.cache.enabled] - Enable caching (default: true)
|
|
82
|
-
* @param {number} [config.cache.maxSize] - Max cache entries (default: 1000)
|
|
83
|
-
* @param {number} [config.cache.defaultTTL] - Default TTL in ms (default: 5 minutes)
|
|
84
|
-
* @param {Object} [config.cache.ttl] - TTL per operation
|
|
85
|
-
* @param {number} [config.cache.ttl.schema] - Schema cache TTL (default: 30 min)
|
|
86
|
-
* @param {number} [config.cache.ttl.records] - Record query cache TTL (default: 2 min)
|
|
87
|
-
* @param {number} [config.cache.ttl.count] - Count query cache TTL (default: 1 min)
|
|
88
|
-
* @param {number} [config.cache.ttl.user] - User/me cache TTL (default: 10 min)
|
|
89
25
|
*/
|
|
90
26
|
function init(config) {
|
|
91
27
|
if (config == null) {
|
|
@@ -94,7 +30,7 @@
|
|
|
94
30
|
return;
|
|
95
31
|
}
|
|
96
32
|
|
|
97
|
-
_config =
|
|
33
|
+
_config = config;
|
|
98
34
|
|
|
99
35
|
// Create SDK instance using the SDK factory if available
|
|
100
36
|
if (typeof global.createSuperLeapSDK === "function") {
|
|
@@ -128,15 +64,6 @@
|
|
|
128
64
|
return _config != null && _sdkInstance != null;
|
|
129
65
|
}
|
|
130
66
|
|
|
131
|
-
/**
|
|
132
|
-
* Return the default config object (for reference or to override specific keys).
|
|
133
|
-
*
|
|
134
|
-
* @returns {Object}
|
|
135
|
-
*/
|
|
136
|
-
function getDefaultConfig() {
|
|
137
|
-
return mergeConfig({}, DEFAULT_CONFIG);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
67
|
/**
|
|
141
68
|
* Return the current base URL (from merged config after init).
|
|
142
69
|
* Used by file-input and other components that build API URLs.
|
|
@@ -152,7 +79,6 @@
|
|
|
152
79
|
init: init,
|
|
153
80
|
getSdk: getSdk,
|
|
154
81
|
isAvailable: isAvailable,
|
|
155
|
-
getDefaultConfig: getDefaultConfig,
|
|
156
82
|
getBaseUrl: getBaseUrl,
|
|
157
83
|
};
|
|
158
84
|
|