@superleapai/flow-ui 2.5.0 → 2.5.1
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/components/checkbox-group.js +209 -0
- package/components/file-input.js +26 -12
- package/core/flow.js +35 -76
- package/core/superleapClient.js +12 -0
- package/dist/output.css +1 -1
- package/dist/superleap-flow.js +681 -383
- package/dist/superleap-flow.js.map +1 -1
- package/dist/superleap-flow.min.js +2 -2
- package/index.d.ts +2 -0
- package/index.js +5 -1
- package/package.json +1 -1
- package/components/card-select.js +0 -283
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CheckboxGroup Component (vanilla JS)
|
|
3
|
+
* Multi-select via checkboxes; same API as MultiSelect (options, value array, onValuesChange).
|
|
4
|
+
* Uses input.js-style variants and sizes for the group wrapper.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
(function (global) {
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
// Wrapper classes aligned with input.js variants
|
|
11
|
+
var WRAPPER_CLASS = {
|
|
12
|
+
base:
|
|
13
|
+
"group flex flex-col border-1/2 border-border-primary rounded-4 text-typography-primary-text w-full transition-all ease-in-out group-has-[:disabled]:cursor-not-allowed group-has-[:disabled]:border-border-primary group-has-[:disabled]:bg-fill-tertiary-fill-light-gray group-has-[:disabled]:text-typography-quaternary-text",
|
|
14
|
+
default:
|
|
15
|
+
"bg-fill-quarternary-fill-white hover:border-primary-base focus-within:border-primary-base",
|
|
16
|
+
error:
|
|
17
|
+
"border-error-base bg-fill-quarternary-fill-white hover:border-error-base focus-within:border-error-base",
|
|
18
|
+
warning:
|
|
19
|
+
"border-warning-base bg-fill-quarternary-fill-white hover:border-warning-base focus-within:border-warning-base",
|
|
20
|
+
success:
|
|
21
|
+
"border-success-base bg-fill-quarternary-fill-white hover:border-success-base focus-within:border-success-base",
|
|
22
|
+
borderless:
|
|
23
|
+
"border-none shadow-none rounded-0 bg-fill-quarternary-fill-white",
|
|
24
|
+
inline:
|
|
25
|
+
"border-transparent shadow-none rounded-0 bg-fill-quarternary-fill-white hover:bg-fill-tertiary-fill-light-gray focus-within:border-transparent focus:bg-fill-tertiary-fill-light-gray focus-within:bg-fill-tertiary-fill-light-gray",
|
|
26
|
+
sizeDefault: "px-12 py-6 gap-6",
|
|
27
|
+
sizeLarge: "px-12 py-8 gap-8",
|
|
28
|
+
sizeSmall: "px-12 py-4 gap-4",
|
|
29
|
+
disabled:
|
|
30
|
+
"cursor-not-allowed border-border-primary bg-fill-tertiary-fill-light-gray text-typography-quaternary-text hover:border-border-primary",
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function join() {
|
|
34
|
+
return Array.prototype.filter.call(arguments, Boolean).join(" ");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getOptionValue(opt) {
|
|
38
|
+
return opt.value !== undefined && opt.value !== null
|
|
39
|
+
? opt.value
|
|
40
|
+
: opt.slug || opt.id;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getOptionLabel(opt) {
|
|
44
|
+
return opt.label || opt.name || opt.display_name || opt.value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getDep(name) {
|
|
48
|
+
if (typeof global.FlowUI !== "undefined" && typeof global.FlowUI._getComponent === "function") {
|
|
49
|
+
var c = global.FlowUI._getComponent(name);
|
|
50
|
+
if (c) return c;
|
|
51
|
+
}
|
|
52
|
+
return global[name];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create a checkbox group component (multiselect-like: multiple values, options array)
|
|
57
|
+
* @param {Object} config
|
|
58
|
+
* @param {string} [config.fieldId] - Field ID for state management
|
|
59
|
+
* @param {Array} config.options - Array of { value, label } or { slug, display_name }
|
|
60
|
+
* @param {Array} [config.value] - Current selected values (array)
|
|
61
|
+
* @param {Function} config.onValuesChange - Change handler (values: string[])
|
|
62
|
+
* @param {boolean} [config.disabled] - Whether all checkboxes are disabled
|
|
63
|
+
* @param {string} [config.variant] - 'default' | 'error' | 'warning' | 'success' | 'borderless' | 'inline'
|
|
64
|
+
* @param {string} [config.size] - 'default' | 'large' | 'small'
|
|
65
|
+
* @param {string} [config.layout] - 'vertical' | 'horizontal'
|
|
66
|
+
* @param {string} [config.className] - Extra class on wrapper
|
|
67
|
+
* @returns {HTMLElement} CheckboxGroup container element
|
|
68
|
+
*/
|
|
69
|
+
function createCheckboxGroup(config) {
|
|
70
|
+
var fieldId = config.fieldId;
|
|
71
|
+
var options = config.options || [];
|
|
72
|
+
var onValuesChange = config.onValuesChange;
|
|
73
|
+
var variant = config.variant || "default";
|
|
74
|
+
var size = config.size || "default";
|
|
75
|
+
var disabled = config.disabled === true;
|
|
76
|
+
var layout = config.layout || "vertical";
|
|
77
|
+
var className = config.className || "";
|
|
78
|
+
|
|
79
|
+
var values = Array.isArray(config.value)
|
|
80
|
+
? config.value.slice()
|
|
81
|
+
: Array.isArray(config.values)
|
|
82
|
+
? config.values.slice()
|
|
83
|
+
: [];
|
|
84
|
+
|
|
85
|
+
var Checkbox = getDep("Checkbox");
|
|
86
|
+
if (!Checkbox || typeof Checkbox.create !== "function") {
|
|
87
|
+
throw new Error("CheckboxGroup requires the Checkbox component. Load checkbox.js before checkbox-group.js.");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
var container = document.createElement("div");
|
|
91
|
+
container.setAttribute("role", "group");
|
|
92
|
+
container.setAttribute("aria-label", config.ariaLabel || "Checkbox group");
|
|
93
|
+
if (fieldId) container.setAttribute("data-field-id", fieldId);
|
|
94
|
+
|
|
95
|
+
var sizeClass = size === "large" ? WRAPPER_CLASS.sizeLarge : size === "small" ? WRAPPER_CLASS.sizeSmall : WRAPPER_CLASS.sizeDefault;
|
|
96
|
+
function applyWrapperClasses() {
|
|
97
|
+
container.className = join(
|
|
98
|
+
WRAPPER_CLASS.base,
|
|
99
|
+
disabled ? WRAPPER_CLASS.disabled : (WRAPPER_CLASS[variant] || WRAPPER_CLASS.default),
|
|
100
|
+
sizeClass,
|
|
101
|
+
layout === "horizontal" ? "flex-row flex-wrap" : "flex-col",
|
|
102
|
+
"custom-checkbox-group",
|
|
103
|
+
className
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
applyWrapperClasses();
|
|
107
|
+
container.setAttribute("data-checkbox-group-variant", variant);
|
|
108
|
+
|
|
109
|
+
function isSelected(optionValue) {
|
|
110
|
+
return values.some(function (v) {
|
|
111
|
+
return v === optionValue || String(v) === String(optionValue);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function toggleValue(optionValue) {
|
|
116
|
+
var idx = values.findIndex(function (v) {
|
|
117
|
+
return v === optionValue || String(v) === String(optionValue);
|
|
118
|
+
});
|
|
119
|
+
if (idx >= 0) {
|
|
120
|
+
values.splice(idx, 1);
|
|
121
|
+
} else {
|
|
122
|
+
values.push(optionValue);
|
|
123
|
+
}
|
|
124
|
+
if (onValuesChange) onValuesChange(values.slice());
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
var optionsContainer = document.createElement("div");
|
|
128
|
+
optionsContainer.className = join(
|
|
129
|
+
"flex gap-8",
|
|
130
|
+
layout === "horizontal" ? "flex-row flex-wrap" : "flex-col"
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
function buildOptions() {
|
|
134
|
+
optionsContainer.innerHTML = "";
|
|
135
|
+
if (options.length === 0) {
|
|
136
|
+
var empty = document.createElement("div");
|
|
137
|
+
empty.className = "!text-reg-13 text-typography-quaternary-text py-4";
|
|
138
|
+
empty.textContent = "No options available";
|
|
139
|
+
optionsContainer.appendChild(empty);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
options.forEach(function (opt, index) {
|
|
144
|
+
var optionValue = getOptionValue(opt);
|
|
145
|
+
var optionLabel = getOptionLabel(opt);
|
|
146
|
+
var optionDisabled = disabled || !!opt.disabled;
|
|
147
|
+
var checked = isSelected(optionValue);
|
|
148
|
+
|
|
149
|
+
var cb = Checkbox.create({
|
|
150
|
+
id: (fieldId || "cbg") + "-" + index,
|
|
151
|
+
name: fieldId ? fieldId + "[]" : "checkbox-group-" + index,
|
|
152
|
+
checked: checked,
|
|
153
|
+
disabled: optionDisabled,
|
|
154
|
+
label: optionLabel,
|
|
155
|
+
align: "left",
|
|
156
|
+
size: size === "large" ? "large" : size === "small" ? "small" : "default",
|
|
157
|
+
onChange: function (isChecked) {
|
|
158
|
+
if (optionDisabled) return;
|
|
159
|
+
if (isChecked) {
|
|
160
|
+
if (!values.some(function (v) { return v === optionValue || String(v) === String(optionValue); })) {
|
|
161
|
+
values.push(optionValue);
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
var idx = values.findIndex(function (v) {
|
|
165
|
+
return v === optionValue || String(v) === String(optionValue);
|
|
166
|
+
});
|
|
167
|
+
if (idx >= 0) values.splice(idx, 1);
|
|
168
|
+
}
|
|
169
|
+
if (onValuesChange) onValuesChange(values.slice());
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
optionsContainer.appendChild(cb);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
buildOptions();
|
|
177
|
+
container.appendChild(optionsContainer);
|
|
178
|
+
|
|
179
|
+
container.updateValues = function (newValues) {
|
|
180
|
+
values = Array.isArray(newValues) ? newValues.slice() : [];
|
|
181
|
+
buildOptions();
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
container.setDisabled = function (isDisabled) {
|
|
185
|
+
disabled = !!isDisabled;
|
|
186
|
+
applyWrapperClasses();
|
|
187
|
+
var wrappers = optionsContainer.querySelectorAll(":scope > div");
|
|
188
|
+
for (var i = 0; i < wrappers.length; i++) {
|
|
189
|
+
if (typeof wrappers[i].setDisabled === "function") wrappers[i].setDisabled(disabled);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
container.setVariant = function (v) {
|
|
194
|
+
variant = v;
|
|
195
|
+
container.setAttribute("data-checkbox-group-variant", v);
|
|
196
|
+
applyWrapperClasses();
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
container.getValues = function () {
|
|
200
|
+
return values.slice();
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
return container;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
global.CheckboxGroup = {
|
|
207
|
+
create: createCheckboxGroup,
|
|
208
|
+
};
|
|
209
|
+
})(typeof window !== "undefined" ? window : this);
|
package/components/file-input.js
CHANGED
|
@@ -40,6 +40,15 @@
|
|
|
40
40
|
return ICONS.file;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/** Resolve client: use FlowUI._getComponent when bundle has captured globals, else global.superleapClient (same as enum-select) */
|
|
44
|
+
function getClient() {
|
|
45
|
+
if (global.FlowUI && typeof global.FlowUI._getComponent === "function") {
|
|
46
|
+
var c = global.FlowUI._getComponent("superleapClient");
|
|
47
|
+
if (c) return c;
|
|
48
|
+
}
|
|
49
|
+
return global.superleapClient;
|
|
50
|
+
}
|
|
51
|
+
|
|
43
52
|
/**
|
|
44
53
|
* Upload file to S3
|
|
45
54
|
* @param {File} file - File to upload
|
|
@@ -51,26 +60,31 @@
|
|
|
51
60
|
formData.append("file", file, file.name);
|
|
52
61
|
formData.append("is_private", String(!!isPrivate));
|
|
53
62
|
|
|
54
|
-
// Get upload
|
|
63
|
+
// Get upload path - can be configured via global.S3_UPLOAD_URL
|
|
55
64
|
const uploadUrl = global.S3_UPLOAD_URL || "/org/file/upload";
|
|
56
|
-
const baseUrl = global.SUPERLEAP_BASE_URL || "https://app.superleap.com/api/v1";
|
|
57
|
-
const fullUrl = uploadUrl.startsWith("http") ? uploadUrl : `${baseUrl}${uploadUrl}`;
|
|
58
65
|
|
|
59
|
-
//
|
|
60
|
-
|
|
66
|
+
// Base URL and API key from superleapClient only (same pattern as enum-select)
|
|
67
|
+
var client = getClient();
|
|
68
|
+
var baseUrl = null;
|
|
69
|
+
var apiKey = null;
|
|
61
70
|
try {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
: global.superleapClient;
|
|
71
|
+
if (client && typeof client.getBaseUrl === "function") {
|
|
72
|
+
baseUrl = client.getBaseUrl();
|
|
73
|
+
}
|
|
66
74
|
if (client && typeof client.getSdk === "function") {
|
|
67
|
-
|
|
68
|
-
apiKey = sdk
|
|
75
|
+
var sdk = client.getSdk();
|
|
76
|
+
apiKey = sdk ? sdk.apiKey : null;
|
|
69
77
|
}
|
|
70
78
|
} catch (e) {
|
|
71
|
-
console.warn("[S3FileUpload] Could not get
|
|
79
|
+
console.warn("[S3FileUpload] Could not get client:", e);
|
|
72
80
|
}
|
|
73
81
|
|
|
82
|
+
if (!baseUrl) {
|
|
83
|
+
throw new Error("SuperLeap client not initialized. Call superleapClient.init({ baseUrl, apiKey }) first.");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const fullUrl = uploadUrl.startsWith("http") ? uploadUrl : baseUrl.replace(/\/$/, "") + (uploadUrl.startsWith("/") ? uploadUrl : "/" + uploadUrl);
|
|
87
|
+
|
|
74
88
|
const headers = {};
|
|
75
89
|
if (apiKey) {
|
|
76
90
|
headers.Authorization = `Bearer ${apiKey}`;
|
package/core/flow.js
CHANGED
|
@@ -591,81 +591,6 @@
|
|
|
591
591
|
return field;
|
|
592
592
|
}
|
|
593
593
|
|
|
594
|
-
/**
|
|
595
|
-
* Create a card select field (uses CardSelect component when available, else radio fallback)
|
|
596
|
-
* @param {Object} config - Configuration object
|
|
597
|
-
* @param {string} config.label - Field label
|
|
598
|
-
* @param {string} config.fieldId - State key for this field
|
|
599
|
-
* @param {Array} config.options - Array of { value, label, description?, icon?, disabled? }
|
|
600
|
-
* @param {boolean} [config.required] - Whether field is required
|
|
601
|
-
* @param {Function} [config.onChange] - Optional change handler (receives selected value)
|
|
602
|
-
* @param {string} [config.helpText] - Optional help text for tooltip
|
|
603
|
-
* @param {boolean} [config.disabled] - Whether all cards are disabled
|
|
604
|
-
* @param {string} [config.className] - Extra CSS class on card container
|
|
605
|
-
* @returns {HTMLElement} Field wrapper element
|
|
606
|
-
*/
|
|
607
|
-
function createCardSelect(config) {
|
|
608
|
-
const { label, fieldId, options = [], required = false, onChange, helpText = null, disabled = false, className } = config;
|
|
609
|
-
|
|
610
|
-
const field = createFieldWrapper(label, required, helpText);
|
|
611
|
-
|
|
612
|
-
if (getComponent("CardSelect") && getComponent("CardSelect").create) {
|
|
613
|
-
const currentValue = get(fieldId);
|
|
614
|
-
const cardSelectEl = getComponent("CardSelect").create({
|
|
615
|
-
name: fieldId,
|
|
616
|
-
options: options.map((opt) => ({
|
|
617
|
-
value: opt.value,
|
|
618
|
-
label: opt.label || opt.value,
|
|
619
|
-
description: opt.description,
|
|
620
|
-
icon: opt.icon,
|
|
621
|
-
disabled: opt.disabled,
|
|
622
|
-
})),
|
|
623
|
-
value: currentValue,
|
|
624
|
-
disabled,
|
|
625
|
-
className,
|
|
626
|
-
onChange: (value) => {
|
|
627
|
-
set(fieldId, value);
|
|
628
|
-
if (onChange) onChange(value);
|
|
629
|
-
},
|
|
630
|
-
});
|
|
631
|
-
cardSelectEl._fieldId = fieldId;
|
|
632
|
-
field.appendChild(cardSelectEl);
|
|
633
|
-
return field;
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
// Fallback: native radio buttons
|
|
637
|
-
const radioGroup = document.createElement("div");
|
|
638
|
-
radioGroup.className = "card-select-fallback";
|
|
639
|
-
|
|
640
|
-
options.forEach((opt) => {
|
|
641
|
-
const wrapper = document.createElement("div");
|
|
642
|
-
wrapper.className = "card-option";
|
|
643
|
-
|
|
644
|
-
const radio = document.createElement("input");
|
|
645
|
-
radio.type = "radio";
|
|
646
|
-
radio.name = fieldId;
|
|
647
|
-
radio.value = opt.value;
|
|
648
|
-
radio.id = `${fieldId}-${opt.value}`;
|
|
649
|
-
radio.checked = get(fieldId) === opt.value;
|
|
650
|
-
radio.disabled = disabled || !!opt.disabled;
|
|
651
|
-
radio.addEventListener("change", () => {
|
|
652
|
-
set(fieldId, opt.value);
|
|
653
|
-
if (onChange) { onChange(opt.value); }
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
const radioLabel = document.createElement("label");
|
|
657
|
-
radioLabel.htmlFor = `${fieldId}-${opt.value}`;
|
|
658
|
-
radioLabel.textContent = opt.label || opt.value;
|
|
659
|
-
|
|
660
|
-
wrapper.appendChild(radio);
|
|
661
|
-
wrapper.appendChild(radioLabel);
|
|
662
|
-
radioGroup.appendChild(wrapper);
|
|
663
|
-
});
|
|
664
|
-
|
|
665
|
-
field.appendChild(radioGroup);
|
|
666
|
-
return field;
|
|
667
|
-
}
|
|
668
|
-
|
|
669
594
|
/**
|
|
670
595
|
* Create a multi-select field (uses MultiSelect component when available, else checkbox group)
|
|
671
596
|
* @param {Object} config - Configuration object
|
|
@@ -1422,6 +1347,40 @@
|
|
|
1422
1347
|
return field;
|
|
1423
1348
|
}
|
|
1424
1349
|
|
|
1350
|
+
/**
|
|
1351
|
+
* Create a checkbox group field (multiselect-like: options array, value array, onValuesChange)
|
|
1352
|
+
* @param {Object} config - { label, fieldId, options, required, helpText, variant, size, layout, disabled, onChange }
|
|
1353
|
+
* @returns {HTMLElement} Field wrapper containing checkbox group
|
|
1354
|
+
*/
|
|
1355
|
+
function createCheckboxGroup(config) {
|
|
1356
|
+
const { label, fieldId, options = [], required = false, helpText = null, variant, size, layout = "vertical", disabled = false, onChange } = config;
|
|
1357
|
+
|
|
1358
|
+
const field = createFieldWrapper(label, required, helpText);
|
|
1359
|
+
field.setAttribute("data-field-id", fieldId);
|
|
1360
|
+
|
|
1361
|
+
if (getComponent("CheckboxGroup") && getComponent("CheckboxGroup").create) {
|
|
1362
|
+
const currentValues = get(fieldId) || [];
|
|
1363
|
+
const groupEl = getComponent("CheckboxGroup").create({
|
|
1364
|
+
fieldId,
|
|
1365
|
+
options,
|
|
1366
|
+
value: currentValues,
|
|
1367
|
+
variant: variant || "default",
|
|
1368
|
+
size: size || "default",
|
|
1369
|
+
layout,
|
|
1370
|
+
disabled,
|
|
1371
|
+
onValuesChange: (values) => {
|
|
1372
|
+
set(fieldId, values);
|
|
1373
|
+
if (onChange) onChange(values);
|
|
1374
|
+
},
|
|
1375
|
+
});
|
|
1376
|
+
groupEl._fieldId = fieldId;
|
|
1377
|
+
field.appendChild(groupEl);
|
|
1378
|
+
return field;
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
return field;
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1425
1384
|
// ============================================================================
|
|
1426
1385
|
// STEPPER COMPONENT
|
|
1427
1386
|
// ============================================================================
|
|
@@ -1816,7 +1775,6 @@
|
|
|
1816
1775
|
createTimePicker,
|
|
1817
1776
|
createDateTimePicker,
|
|
1818
1777
|
createRadioGroup,
|
|
1819
|
-
createCardSelect,
|
|
1820
1778
|
createMultiSelect,
|
|
1821
1779
|
createRecordSelect,
|
|
1822
1780
|
createRecordMultiSelect,
|
|
@@ -1828,6 +1786,7 @@
|
|
|
1828
1786
|
createCurrency,
|
|
1829
1787
|
createPhoneInput,
|
|
1830
1788
|
createCheckbox,
|
|
1789
|
+
createCheckboxGroup,
|
|
1831
1790
|
|
|
1832
1791
|
// Button (delegates to Button component when available; resolved at call time via getComponent)
|
|
1833
1792
|
createButton: function (config) {
|
package/core/superleapClient.js
CHANGED
|
@@ -137,11 +137,23 @@
|
|
|
137
137
|
return mergeConfig({}, DEFAULT_CONFIG);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Return the current base URL (from merged config after init).
|
|
142
|
+
* Used by file-input and other components that build API URLs.
|
|
143
|
+
*
|
|
144
|
+
* @returns {string|null} baseUrl or null if not initialized
|
|
145
|
+
*/
|
|
146
|
+
function getBaseUrl() {
|
|
147
|
+
if (_config && _config.baseUrl) return _config.baseUrl;
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
140
151
|
var superleapClient = {
|
|
141
152
|
init: init,
|
|
142
153
|
getSdk: getSdk,
|
|
143
154
|
isAvailable: isAvailable,
|
|
144
155
|
getDefaultConfig: getDefaultConfig,
|
|
156
|
+
getBaseUrl: getBaseUrl,
|
|
145
157
|
};
|
|
146
158
|
|
|
147
159
|
if (global) {
|