@karpeleslab/klbfw 0.1.12 → 0.2.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/CLAUDE.md +50 -0
- package/README.md +199 -35
- package/cookies.js +107 -41
- package/coverage/clover.xml +835 -0
- package/coverage/coverage-final.json +9 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/cookies.js.html +334 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/fw-wrapper.js.html +163 -0
- package/coverage/lcov-report/index.html +131 -0
- package/coverage/lcov-report/index.js.html +196 -0
- package/coverage/lcov-report/internal.js.html +604 -0
- package/coverage/lcov-report/klbfw/cookies.js.html +490 -0
- package/coverage/lcov-report/klbfw/fw-wrapper.js.html +745 -0
- package/coverage/lcov-report/klbfw/index.html +206 -0
- package/coverage/lcov-report/klbfw/index.js.html +235 -0
- package/coverage/lcov-report/klbfw/internal.js.html +811 -0
- package/coverage/lcov-report/klbfw/rest.js.html +565 -0
- package/coverage/lcov-report/klbfw/test/index.html +116 -0
- package/coverage/lcov-report/klbfw/test/setup.js.html +1105 -0
- package/coverage/lcov-report/klbfw/upload.js.html +3487 -0
- package/coverage/lcov-report/klbfw/util.js.html +388 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/rest.js.html +472 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov-report/upload.js.html +1789 -0
- package/coverage/lcov-report/util.js.html +313 -0
- package/coverage/lcov.info +1617 -0
- package/fw-wrapper.js +221 -26
- package/index.js +16 -2
- package/internal.js +186 -102
- package/package.json +21 -3
- package/rest.js +129 -81
- package/test/README.md +62 -0
- package/test/api.test.js +102 -0
- package/test/cookies.test.js +65 -0
- package/test/integration.test.js +481 -0
- package/test/rest.test.js +93 -0
- package/test/setup.js +341 -0
- package/test/upload.test.js +689 -0
- package/test/util.test.js +46 -0
- package/upload.js +1012 -442
- package/util.js +59 -21
package/fw-wrapper.js
CHANGED
|
@@ -1,26 +1,221 @@
|
|
|
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
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Framework wrapper for KLB Frontend Framework
|
|
4
|
+
*
|
|
5
|
+
* This module provides a wrapper around the global FW object,
|
|
6
|
+
* providing safe access to its properties with fallbacks for
|
|
7
|
+
* environments where FW is not available.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Gets a property from the global FW object with fallback
|
|
12
|
+
* @private
|
|
13
|
+
* @param {string} property - FW property to retrieve
|
|
14
|
+
* @param {*} fallback - Fallback value if property is not available
|
|
15
|
+
* @returns {*} The property value or fallback
|
|
16
|
+
*/
|
|
17
|
+
const getFWProperty = (property, fallback) => {
|
|
18
|
+
if (typeof FW === "undefined") return fallback;
|
|
19
|
+
|
|
20
|
+
// Handle nested properties (e.g., "Context.c")
|
|
21
|
+
if (property.includes('.')) {
|
|
22
|
+
const parts = property.split('.');
|
|
23
|
+
let obj = FW;
|
|
24
|
+
|
|
25
|
+
for (const part of parts) {
|
|
26
|
+
if (obj === undefined || obj === null) return fallback;
|
|
27
|
+
obj = obj[part];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return obj !== undefined ? obj : fallback;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return FW[property] !== undefined ? FW[property] : fallback;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Gets the site prefix
|
|
38
|
+
* @returns {string} Site prefix
|
|
39
|
+
*/
|
|
40
|
+
const getPrefix = () => getFWProperty('prefix', '');
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Gets site settings
|
|
44
|
+
* @returns {Object} Site settings
|
|
45
|
+
*/
|
|
46
|
+
const getSettings = () => getFWProperty('settings', {});
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Gets realm information
|
|
50
|
+
* @returns {Object} Realm information
|
|
51
|
+
*/
|
|
52
|
+
const getRealm = () => getFWProperty('Realm', {});
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Gets the current locale
|
|
56
|
+
* @returns {string} Current locale
|
|
57
|
+
*/
|
|
58
|
+
const getLocale = () => getFWProperty('Locale', 'en-US');
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Gets the current path
|
|
62
|
+
* @returns {string} Current path
|
|
63
|
+
*/
|
|
64
|
+
const getPath = () => {
|
|
65
|
+
if (typeof FW !== "undefined") return FW.path;
|
|
66
|
+
if (typeof window !== "undefined") return window.location.pathname;
|
|
67
|
+
return '/';
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Gets the current hostname
|
|
72
|
+
* @returns {string} Current hostname
|
|
73
|
+
*/
|
|
74
|
+
const getHostname = () => {
|
|
75
|
+
if (typeof FW !== "undefined") return FW.hostname;
|
|
76
|
+
if (typeof window !== "undefined") return window.location.hostname;
|
|
77
|
+
return '';
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Gets the current currency
|
|
82
|
+
* @returns {string} Current currency code
|
|
83
|
+
*/
|
|
84
|
+
const getCurrency = () => getFWProperty('Context.c', 'USD');
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Gets a copy of the current context
|
|
88
|
+
* @returns {Object} Current context
|
|
89
|
+
*/
|
|
90
|
+
const getContext = () => {
|
|
91
|
+
if (typeof FW !== "undefined" && FW.Context) {
|
|
92
|
+
return Object.assign({}, FW.Context);
|
|
93
|
+
}
|
|
94
|
+
return {};
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Sets a value in the context
|
|
99
|
+
* @param {string} key - Context key
|
|
100
|
+
* @param {*} value - Value to set
|
|
101
|
+
*/
|
|
102
|
+
const setContext = (key, value) => {
|
|
103
|
+
if (typeof FW !== "undefined" && FW.Context) {
|
|
104
|
+
FW.Context[key] = value;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Gets the current authentication token
|
|
110
|
+
* @returns {string|undefined} Authentication token
|
|
111
|
+
*/
|
|
112
|
+
const getToken = () => getFWProperty('token', undefined);
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Gets the registry
|
|
116
|
+
* @returns {Object|undefined} Registry object
|
|
117
|
+
*/
|
|
118
|
+
const getRegistry = () => getFWProperty('Registry', undefined);
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Gets URL information
|
|
122
|
+
* @returns {Object} URL information
|
|
123
|
+
*/
|
|
124
|
+
const getUrl = () => {
|
|
125
|
+
if (typeof FW !== "undefined") return FW.URL;
|
|
126
|
+
if (typeof window !== "undefined") {
|
|
127
|
+
return {
|
|
128
|
+
path: window.location.pathname,
|
|
129
|
+
full: window.location.href
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return { path: '/', full: '/' };
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Gets site static flag
|
|
137
|
+
* @returns {boolean} Whether site is static
|
|
138
|
+
*/
|
|
139
|
+
const getSiteStatic = () => getFWProperty('site_static', true);
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Gets the API call URL prefix
|
|
143
|
+
* @returns {string} API call URL prefix
|
|
144
|
+
*/
|
|
145
|
+
const getCallUrlPrefix = () => getFWProperty('call_url_prefix', 'https://hub.atonline.com');
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Gets the site UUID
|
|
149
|
+
* @returns {string|undefined} Site UUID
|
|
150
|
+
*/
|
|
151
|
+
const getUuid = () => getFWProperty('uuid', undefined);
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Gets the initial state
|
|
155
|
+
* @returns {Object|undefined} Initial state
|
|
156
|
+
*/
|
|
157
|
+
const getInitialState = () => getFWProperty('initial', undefined);
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Checks if the framework is supported
|
|
161
|
+
* @returns {boolean} Whether the framework is supported
|
|
162
|
+
*/
|
|
163
|
+
const supported = () => true;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Gets the current GET parameters
|
|
167
|
+
* @returns {Object} GET parameters
|
|
168
|
+
*/
|
|
169
|
+
const getGET = () => getFWProperty('GET', {});
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Gets a specific GET parameter
|
|
173
|
+
* @param {string} key - Parameter key
|
|
174
|
+
* @returns {string|undefined} Parameter value
|
|
175
|
+
*/
|
|
176
|
+
const getParam = (key) => {
|
|
177
|
+
if (key === undefined) {
|
|
178
|
+
return getGET();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const params = getGET();
|
|
182
|
+
return params[key];
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Flushes GET parameters
|
|
187
|
+
*/
|
|
188
|
+
const flushGet = () => {
|
|
189
|
+
if (typeof FW !== "undefined") {
|
|
190
|
+
FW.GET = {};
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Gets the current mode
|
|
196
|
+
* @returns {string} Current mode
|
|
197
|
+
*/
|
|
198
|
+
const getMode = () => getFWProperty('mode', 'offline');
|
|
199
|
+
|
|
200
|
+
// Export functions
|
|
201
|
+
module.exports.getPrefix = getPrefix;
|
|
202
|
+
module.exports.getSettings = getSettings;
|
|
203
|
+
module.exports.getRealm = getRealm;
|
|
204
|
+
module.exports.getLocale = getLocale;
|
|
205
|
+
module.exports.getPath = getPath;
|
|
206
|
+
module.exports.getHostname = getHostname;
|
|
207
|
+
module.exports.getCurrency = getCurrency;
|
|
208
|
+
module.exports.getContext = getContext;
|
|
209
|
+
module.exports.setContext = setContext;
|
|
210
|
+
module.exports.getToken = getToken;
|
|
211
|
+
module.exports.getRegistry = getRegistry;
|
|
212
|
+
module.exports.getUrl = getUrl;
|
|
213
|
+
module.exports.getSiteStatic = getSiteStatic;
|
|
214
|
+
module.exports.getCallUrlPrefix = getCallUrlPrefix;
|
|
215
|
+
module.exports.getUuid = getUuid;
|
|
216
|
+
module.exports.getInitialState = getInitialState;
|
|
217
|
+
module.exports.supported = supported;
|
|
218
|
+
module.exports.GET = getGET();
|
|
219
|
+
module.exports.Get = getParam;
|
|
220
|
+
module.exports.flushGet = flushGet;
|
|
221
|
+
module.exports.getMode = getMode;
|
package/index.js
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Main entry point for KLB Frontend Framework
|
|
4
|
+
*
|
|
5
|
+
* This module exports all public API functions from the framework's
|
|
6
|
+
* individual modules.
|
|
7
|
+
*/
|
|
8
|
+
|
|
2
9
|
const internalFW = require('./fw-wrapper');
|
|
3
10
|
const rest = require('./rest');
|
|
4
11
|
const upload = require('./upload');
|
|
5
12
|
const util = require('./util');
|
|
6
13
|
const cookies = require('./cookies');
|
|
7
14
|
|
|
15
|
+
// Framework wrapper exports
|
|
8
16
|
module.exports.GET = internalFW.GET;
|
|
9
17
|
module.exports.Get = internalFW.Get;
|
|
10
18
|
module.exports.flushGet = internalFW.flushGet;
|
|
@@ -24,14 +32,20 @@ module.exports.getUrl = internalFW.getUrl;
|
|
|
24
32
|
module.exports.getPath = internalFW.getPath;
|
|
25
33
|
module.exports.getUuid = internalFW.getUuid;
|
|
26
34
|
module.exports.getInitialState = internalFW.getInitialState;
|
|
35
|
+
|
|
36
|
+
// Cookie handling exports
|
|
27
37
|
module.exports.getCookie = cookies.getCookie;
|
|
28
38
|
module.exports.hasCookie = cookies.hasCookie;
|
|
29
39
|
module.exports.setCookie = cookies.setCookie;
|
|
30
40
|
|
|
41
|
+
// REST API exports
|
|
31
42
|
module.exports.rest = rest.rest;
|
|
32
|
-
module.exports.rest_get = rest.rest_get;
|
|
43
|
+
module.exports.rest_get = rest.rest_get; // Backward compatibility
|
|
44
|
+
module.exports.restGet = rest.restGet; // New camelCase name
|
|
33
45
|
|
|
46
|
+
// Upload module exports
|
|
34
47
|
module.exports.upload = upload.upload;
|
|
35
48
|
|
|
49
|
+
// Utility exports
|
|
36
50
|
module.exports.getI18N = util.getI18N;
|
|
37
|
-
module.exports.trimPrefix = util.trimPrefix;
|
|
51
|
+
module.exports.trimPrefix = util.trimPrefix;
|
package/internal.js
CHANGED
|
@@ -1,88 +1,166 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Internal helpers for the KLB Frontend Framework
|
|
4
|
+
*
|
|
5
|
+
* This module provides internal utility functions for REST API interactions,
|
|
6
|
+
* timezone handling, and response parsing.
|
|
7
|
+
*/
|
|
3
8
|
|
|
4
|
-
|
|
9
|
+
const fwWrapper = require('./fw-wrapper');
|
|
5
10
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Pads a number with leading zeros
|
|
13
|
+
* @param {number} number - The number to pad
|
|
14
|
+
* @param {number} length - The desired length of the result
|
|
15
|
+
* @returns {string} The padded number
|
|
16
|
+
*/
|
|
17
|
+
const padNumber = (number, length) => {
|
|
18
|
+
let str = String(number);
|
|
19
|
+
while (str.length < length) {
|
|
9
20
|
str = '0' + str;
|
|
21
|
+
}
|
|
10
22
|
return str;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Gets timezone data in a format suitable for API calls
|
|
27
|
+
* @returns {string} Formatted timezone string
|
|
28
|
+
*/
|
|
29
|
+
const getTimezoneData = () => {
|
|
30
|
+
// Grab current offset value & build string
|
|
31
|
+
const offset = new Date().getTimezoneOffset();
|
|
32
|
+
const sign = offset < 0 ? '+' : '-'; // Note the reversed sign!
|
|
33
|
+
const formattedOffset = sign +
|
|
34
|
+
padNumber(parseInt(Math.abs(offset / 60)), 2) +
|
|
35
|
+
padNumber(Math.abs(offset % 60), 2);
|
|
36
|
+
|
|
37
|
+
// Check if we have Intl info
|
|
38
|
+
if (typeof Intl !== 'undefined' && Intl.DateTimeFormat !== undefined) {
|
|
39
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone + ";" + formattedOffset;
|
|
24
40
|
}
|
|
25
41
|
|
|
26
|
-
return
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
return formattedOffset;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Constructs a REST API URL
|
|
47
|
+
* @param {string} path - API endpoint path
|
|
48
|
+
* @param {boolean} withToken - Whether to include authentication token
|
|
49
|
+
* @param {Object} context - Context object with additional parameters
|
|
50
|
+
* @returns {string} Constructed URL
|
|
51
|
+
*/
|
|
52
|
+
const buildRestUrl = (path, withToken, context) => {
|
|
53
|
+
if (!withToken) {
|
|
54
|
+
if (fwWrapper.getCallUrlPrefix()) return fwWrapper.getCallUrlPrefix() + "/_rest/" + path;
|
|
55
|
+
return "/_rest/" + path;
|
|
33
56
|
}
|
|
57
|
+
|
|
34
58
|
context = context || {};
|
|
35
|
-
|
|
36
|
-
|
|
59
|
+
let glue = '?';
|
|
60
|
+
|
|
61
|
+
let callUrl;
|
|
37
62
|
if (fwWrapper.getSiteStatic()) {
|
|
38
|
-
|
|
63
|
+
callUrl = "/_rest/" + path + "?static";
|
|
39
64
|
glue = '&';
|
|
40
65
|
} else {
|
|
41
|
-
|
|
66
|
+
callUrl = "/_rest/" + path;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (fwWrapper.getCallUrlPrefix()) {
|
|
70
|
+
callUrl = fwWrapper.getCallUrlPrefix() + callUrl;
|
|
42
71
|
}
|
|
43
|
-
if (fwWrapper.getCallUrlPrefix()) call_url = fwWrapper.getCallUrlPrefix() + call_url;
|
|
44
72
|
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
for (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
73
|
+
// Copy context, proceed with overload then add to url
|
|
74
|
+
const ctxFinal = fwWrapper.getContext();
|
|
75
|
+
for (const key in context) {
|
|
76
|
+
ctxFinal[key] = context[key];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const key in ctxFinal) {
|
|
80
|
+
if (key === "_") continue;
|
|
81
|
+
callUrl = callUrl + glue + "_ctx[" + key + "]=" + encodeURIComponent(ctxFinal[key]);
|
|
51
82
|
glue = '&';
|
|
52
83
|
}
|
|
53
|
-
|
|
54
|
-
|
|
84
|
+
|
|
85
|
+
return callUrl;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Checks if the environment supports required features
|
|
90
|
+
* @returns {boolean} Whether the environment is supported
|
|
91
|
+
*/
|
|
92
|
+
const checkSupport = () => {
|
|
93
|
+
const missingFeatures = [];
|
|
94
|
+
|
|
95
|
+
if (typeof fetch === "undefined") {
|
|
96
|
+
missingFeatures.push("fetch API");
|
|
97
|
+
}
|
|
55
98
|
|
|
56
|
-
|
|
99
|
+
if (!fwWrapper.supported()) {
|
|
100
|
+
missingFeatures.push("Framework wrapper");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (missingFeatures.length > 0) {
|
|
104
|
+
console.error("Missing required features: " + missingFeatures.join(", "));
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return true;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Makes an internal REST API call
|
|
113
|
+
* @param {string} name - API endpoint name
|
|
114
|
+
* @param {string} verb - HTTP method (GET, POST, etc.)
|
|
115
|
+
* @param {Object|string} params - Request parameters
|
|
116
|
+
* @param {Object} context - Context object with additional parameters
|
|
117
|
+
* @returns {Promise} Fetch promise
|
|
118
|
+
*/
|
|
119
|
+
const internalRest = (name, verb, params, context) => {
|
|
57
120
|
verb = verb || "GET";
|
|
58
121
|
params = params || {};
|
|
59
122
|
context = context || {};
|
|
60
123
|
|
|
61
124
|
if (typeof window !== "undefined") {
|
|
62
|
-
context['t'] =
|
|
125
|
+
context['t'] = getTimezoneData();
|
|
63
126
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
127
|
+
|
|
128
|
+
const callUrl = buildRestUrl(name, true, context);
|
|
129
|
+
const headers = {};
|
|
130
|
+
|
|
131
|
+
if (fwWrapper.getToken() !== '') {
|
|
132
|
+
headers['Authorization'] = 'Session ' + fwWrapper.getToken();
|
|
69
133
|
}
|
|
70
134
|
|
|
71
|
-
|
|
135
|
+
// Handle GET requests
|
|
136
|
+
if (verb === "GET") {
|
|
72
137
|
if (params) {
|
|
73
|
-
//
|
|
138
|
+
// Check if params is a JSON string, or if it needs encoding
|
|
74
139
|
if (typeof params === "string") {
|
|
75
|
-
|
|
140
|
+
return fetch(callUrl + "&_=" + encodeURIComponent(params), {
|
|
141
|
+
method: verb,
|
|
142
|
+
credentials: 'include',
|
|
143
|
+
headers: headers
|
|
144
|
+
});
|
|
76
145
|
} else {
|
|
77
|
-
|
|
146
|
+
return fetch(callUrl + "&_=" + encodeURIComponent(JSON.stringify(params)), {
|
|
147
|
+
method: verb,
|
|
148
|
+
credentials: 'include',
|
|
149
|
+
headers: headers
|
|
150
|
+
});
|
|
78
151
|
}
|
|
79
152
|
}
|
|
80
|
-
|
|
81
|
-
return fetch(
|
|
153
|
+
|
|
154
|
+
return fetch(callUrl, {
|
|
155
|
+
method: verb,
|
|
156
|
+
credentials: 'include',
|
|
157
|
+
headers: headers
|
|
158
|
+
});
|
|
82
159
|
}
|
|
83
160
|
|
|
84
|
-
|
|
85
|
-
|
|
161
|
+
// Handle FormData
|
|
162
|
+
if (typeof FormData !== "undefined" && (params instanceof FormData)) {
|
|
163
|
+
return fetch(callUrl, {
|
|
86
164
|
method: verb,
|
|
87
165
|
credentials: 'include',
|
|
88
166
|
body: params,
|
|
@@ -90,70 +168,76 @@ function internal_rest(name, verb, params, context) {
|
|
|
90
168
|
});
|
|
91
169
|
}
|
|
92
170
|
|
|
171
|
+
// Handle JSON requests
|
|
93
172
|
headers['Content-Type'] = 'application/json; charset=utf-8';
|
|
94
|
-
|
|
95
|
-
return fetch(
|
|
173
|
+
|
|
174
|
+
return fetch(callUrl, {
|
|
96
175
|
method: verb,
|
|
97
176
|
credentials: 'include',
|
|
98
177
|
body: JSON.stringify(params),
|
|
99
178
|
headers: headers
|
|
100
179
|
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Parses API response and resolves/rejects accordingly
|
|
184
|
+
* @param {Response} response - Fetch Response object
|
|
185
|
+
* @param {Function} resolve - Promise resolve function
|
|
186
|
+
* @param {Function} reject - Promise reject function
|
|
187
|
+
*/
|
|
188
|
+
const responseParse = (response, resolve, reject) => {
|
|
189
|
+
// Check if response is ok (status 200-299)
|
|
190
|
+
if (!response.ok) {
|
|
191
|
+
reject({
|
|
192
|
+
message: `HTTP Error: ${response.status} ${response.statusText}`,
|
|
193
|
+
status: response.status,
|
|
194
|
+
headers: response.headers
|
|
195
|
+
});
|
|
196
|
+
return;
|
|
113
197
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
reject
|
|
126
|
-
).catch(reject);
|
|
127
|
-
|
|
198
|
+
|
|
199
|
+
const contentType = response.headers.get("content-type");
|
|
200
|
+
if (!contentType || contentType.indexOf("application/json") === -1) {
|
|
201
|
+
response.text()
|
|
202
|
+
.then(text => {
|
|
203
|
+
reject({
|
|
204
|
+
message: "Not JSON",
|
|
205
|
+
body: text,
|
|
206
|
+
headers: response.headers
|
|
207
|
+
});
|
|
208
|
+
})
|
|
209
|
+
.catch(error => reject(error));
|
|
128
210
|
return;
|
|
129
211
|
}
|
|
130
212
|
|
|
131
|
-
response.json()
|
|
132
|
-
|
|
133
|
-
//
|
|
134
|
-
if (
|
|
135
|
-
json.gtag.map(
|
|
213
|
+
response.json()
|
|
214
|
+
.then(json => {
|
|
215
|
+
// Check for gtag
|
|
216
|
+
if (json.gtag && typeof window !== "undefined" && window.gtag) {
|
|
217
|
+
json.gtag.map(item => window.gtag.apply(null, item));
|
|
136
218
|
}
|
|
137
|
-
|
|
138
|
-
|
|
219
|
+
|
|
220
|
+
// Check for result
|
|
221
|
+
if (json.result !== "success" && json.result !== "redirect") {
|
|
139
222
|
json.headers = response.headers;
|
|
140
223
|
reject(json);
|
|
141
224
|
} else {
|
|
142
225
|
resolve(json);
|
|
143
226
|
}
|
|
144
|
-
}
|
|
145
|
-
reject
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
module.exports.get_tz_pad =
|
|
150
|
-
|
|
151
|
-
module.exports.
|
|
152
|
-
|
|
153
|
-
module.exports.rest_url = rest_url;
|
|
154
|
-
|
|
155
|
-
module.exports.internal_rest = internal_rest;
|
|
156
|
-
|
|
227
|
+
})
|
|
228
|
+
.catch(error => reject(error));
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// Backward compatibility aliases
|
|
232
|
+
module.exports.get_tz_pad = padNumber;
|
|
233
|
+
module.exports.get_timezone_data = getTimezoneData;
|
|
234
|
+
module.exports.rest_url = buildRestUrl;
|
|
235
|
+
module.exports.internal_rest = internalRest;
|
|
157
236
|
module.exports.checkSupport = checkSupport;
|
|
158
|
-
|
|
159
237
|
module.exports.responseParse = responseParse;
|
|
238
|
+
|
|
239
|
+
// New exports with camelCase naming
|
|
240
|
+
module.exports.padNumber = padNumber;
|
|
241
|
+
module.exports.getTimezoneData = getTimezoneData;
|
|
242
|
+
module.exports.buildRestUrl = buildRestUrl;
|
|
243
|
+
module.exports.internalRest = internalRest;
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@karpeleslab/klbfw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Frontend Framework",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "
|
|
7
|
+
"test": "jest",
|
|
8
|
+
"test:watch": "jest --watch",
|
|
9
|
+
"test:integration": "RUN_INTEGRATION_TESTS=true jest test/integration.test.js --env=node",
|
|
10
|
+
"test:coverage": "jest --coverage"
|
|
8
11
|
},
|
|
9
12
|
"repository": {
|
|
10
13
|
"type": "git",
|
|
@@ -17,6 +20,21 @@
|
|
|
17
20
|
},
|
|
18
21
|
"homepage": "https://github.com/KarpelesLab/klbfw#readme",
|
|
19
22
|
"dependencies": {
|
|
20
|
-
"js-sha256": "^0.
|
|
23
|
+
"js-sha256": "^0.11.0"
|
|
24
|
+
},
|
|
25
|
+
"optionalDependencies": {
|
|
26
|
+
"node-fetch": "^2.7.0",
|
|
27
|
+
"xmldom": "^0.6.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"jest": "^29.7.0",
|
|
31
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
32
|
+
"node-fetch": "^2.7.0",
|
|
33
|
+
"xmldom": "^0.6.0"
|
|
34
|
+
},
|
|
35
|
+
"jest": {
|
|
36
|
+
"testEnvironment": "jsdom",
|
|
37
|
+
"collectCoverage": true,
|
|
38
|
+
"coverageDirectory": "coverage"
|
|
21
39
|
}
|
|
22
40
|
}
|