cr-static-shared-components 9.9.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/src/network.js ADDED
@@ -0,0 +1,216 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Network & HTTP Utilities Module
5
+ * HTTP client helpers, retry logic, and network utilities
6
+ *
7
+ * @module network
8
+ */
9
+
10
+ const https = require('https');
11
+ const http = require('http');
12
+ const { URL } = require('url');
13
+
14
+ /**
15
+ * Make HTTP/HTTPS request with automatic protocol detection
16
+ */
17
+ function request(url, options = {}) {
18
+ return new Promise((resolve, reject) => {
19
+ const parsedUrl = new URL(url);
20
+ const client = parsedUrl.protocol === 'https:' ? https : http;
21
+
22
+ const req = client.request(url, options, (res) => {
23
+ let data = '';
24
+ res.on('data', (chunk) => data += chunk);
25
+ res.on('end', () => {
26
+ resolve({
27
+ statusCode: res.statusCode,
28
+ headers: res.headers,
29
+ body: data
30
+ });
31
+ });
32
+ });
33
+
34
+ req.on('error', reject);
35
+
36
+ if (options.body) {
37
+ req.write(options.body);
38
+ }
39
+
40
+ req.end();
41
+ });
42
+ }
43
+
44
+ /**
45
+ * GET request
46
+ */
47
+ function get(url, options = {}) {
48
+ return request(url, { ...options, method: 'GET' });
49
+ }
50
+
51
+ /**
52
+ * POST request
53
+ */
54
+ function post(url, body, options = {}) {
55
+ return request(url,{
56
+ ...options,
57
+ method: 'POST',
58
+ body: typeof body === 'string' ? body : JSON.stringify(body)
59
+ });
60
+ }
61
+
62
+ /**
63
+ * Retry a function with exponential backoff
64
+ */
65
+ async function retry(fn, options = {}) {
66
+ const {
67
+ retries = 3,
68
+ delay = 1000,
69
+ factor = 2,
70
+ maxDelay = 30000
71
+ } = options;
72
+
73
+ let lastError;
74
+ let currentDelay = delay;
75
+
76
+ for (let i = 0; i <= retries; i++) {
77
+ try {
78
+ return await fn();
79
+ } catch (error) {
80
+ lastError = error;
81
+
82
+ if (i < retries) {
83
+ await sleep(currentDelay);
84
+ currentDelay = Math.min(currentDelay * factor, maxDelay);
85
+ }
86
+ }
87
+ }
88
+
89
+ throw lastError;
90
+ }
91
+
92
+ /**
93
+ * Sleep helper
94
+ */
95
+ function sleep(ms) {
96
+ return new Promise(resolve => setTimeout(resolve, ms));
97
+ }
98
+
99
+ /**
100
+ * Parse query string
101
+ */
102
+ function parseQueryString(query) {
103
+ return query
104
+ .replace(/^\?/, '')
105
+ .split('&')
106
+ .filter(Boolean)
107
+ .reduce((acc, pair) => {
108
+ const [key, value] = pair.split('=');
109
+ acc[decodeURIComponent(key)] = decodeURIComponent(value || '');
110
+ return acc;
111
+ }, {});
112
+ }
113
+
114
+ /**
115
+ * Build query string
116
+ */
117
+ function buildQueryString(params) {
118
+ return Object.entries(params)
119
+ .filter(([, value]) => value != null)
120
+ .map(([key, value]) =>
121
+ `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
122
+ )
123
+ .join('&');
124
+ }
125
+
126
+ /**
127
+ * Parse URL with validation
128
+ */
129
+ function parseURL(urlString) {
130
+ try {
131
+ const url = new URL(urlString);
132
+ return {
133
+ protocol: url.protocol,
134
+ hostname: url.hostname,
135
+ port: url.port,
136
+ pathname: url.pathname,
137
+ search: url.search,
138
+ hash: url.hash,
139
+ query: parseQueryString(url.search)
140
+ };
141
+ } catch (error) {
142
+ throw new Error(`Invalid URL: ${urlString}`);
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Check if URL is absolute
148
+ */
149
+ function isAbsoluteURL(url) {
150
+ return /^https?:\/\//i.test(url);
151
+ }
152
+
153
+ /**
154
+ * Join URL paths
155
+ */
156
+ function joinURL(base, ...paths) {
157
+ const url = base.replace(/\/+$/, '');
158
+ const path = paths
159
+ .map(p => p.replace(/^\/+|\/+$/g, ''))
160
+ .filter(Boolean)
161
+ .join('/');
162
+ return path ? `${url}/${path}` : url;
163
+ }
164
+
165
+ /**
166
+ * Timeout wrapper for promises
167
+ */
168
+ function timeout(promise, ms) {
169
+ return Promise.race([
170
+ promise,
171
+ new Promise((_, reject) =>
172
+ setTimeout(() => reject(new Error('Timeout')), ms)
173
+ )
174
+ ]);
175
+ }
176
+
177
+ /**
178
+ * Parallel request limiter
179
+ */
180
+ async function parallel(urls, options = {}) {
181
+ const { concurrency = 5 } = options;
182
+ const results = [];
183
+ const queue = [...urls];
184
+
185
+ async function worker() {
186
+ while (queue.length > 0) {
187
+ const url = queue.shift();
188
+ try {
189
+ const result = await get(url, options);
190
+ results.push({ url, success: true, data: result });
191
+ } catch (error) {
192
+ results.push({ url, success: false, error: error.message });
193
+ }
194
+ }
195
+ }
196
+
197
+ const workers = Array(concurrency).fill(null).map(() => worker());
198
+ await Promise.all(workers);
199
+
200
+ return results;
201
+ }
202
+
203
+ module.exports = {
204
+ request,
205
+ get,
206
+ post,
207
+ retry,
208
+ sleep,
209
+ parseQueryString,
210
+ buildQueryString,
211
+ parseURL,
212
+ isAbsoluteURL,
213
+ joinURL,
214
+ timeout,
215
+ parallel
216
+ };
@@ -0,0 +1,273 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Transformation Module
5
+ * Provides functional programming utilities for data transformation
6
+ *
7
+ * @module transformation
8
+ */
9
+
10
+ /**
11
+ * Compose functions into a pipeline
12
+ */
13
+ function pipe(...fns) {
14
+ return (value) => {
15
+ return fns.reduce((acc, fn) => fn(acc), value);
16
+ };
17
+ }
18
+
19
+ /**
20
+ * Map transformation
21
+ */
22
+ function map(fn) {
23
+ return (array) => {
24
+ if (!Array.isArray(array)) {
25
+ throw new Error('map() requires an array');
26
+ }
27
+ return array.map(fn);
28
+ };
29
+ }
30
+
31
+ /**
32
+ * Filter transformation
33
+ */
34
+ function filter(predicate) {
35
+ return (array) => {
36
+ if (!Array.isArray(array)) {
37
+ throw new Error('filter() requires an array');
38
+ }
39
+ return array.filter(predicate);
40
+ };
41
+ }
42
+
43
+ /**
44
+ * Reduce transformation
45
+ */
46
+ function reduce(fn, initial) {
47
+ return (array) => {
48
+ if (!Array.isArray(array)) {
49
+ throw new Error('reduce() requires an array');
50
+ }
51
+ return array.reduce(fn, initial);
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Sort transformation
57
+ */
58
+ function sort(compareFn = null) {
59
+ return (array) => {
60
+ if (!Array.isArray(array)) {
61
+ throw new Error('sort() requires an array');
62
+ }
63
+ const copy = [...array];
64
+ return compareFn ? copy.sort(compareFn) : copy.sort();
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Unique/distinct values
70
+ */
71
+ function unique() {
72
+ return (array) => {
73
+ if (!Array.isArray(array)) {
74
+ throw new Error('unique() requires an array');
75
+ }
76
+ return [...new Set(array)];
77
+ };
78
+ }
79
+
80
+ /**
81
+ * Chunk array into smaller arrays
82
+ */
83
+ function chunk(size) {
84
+ return (array) => {
85
+ if (!Array.isArray(array)) {
86
+ throw new Error('chunk() requires an array');
87
+ }
88
+
89
+ const result = [];
90
+ for (let i = 0; i < array.length; i += size) {
91
+ result.push(array.slice(i, i + size));
92
+ }
93
+ return result;
94
+ };
95
+ }
96
+
97
+ /**
98
+ * Flatten nested arrays
99
+ */
100
+ function flatten(depth = Infinity) {
101
+ return (array) => {
102
+ if (!Array.isArray(array)) {
103
+ throw new Error('flatten() requires an array');
104
+ }
105
+ return array.flat(depth);
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Group by key
111
+ */
112
+ function groupBy(keyFn) {
113
+ return (array) => {
114
+ if (!Array.isArray(array)) {
115
+ throw new Error('groupBy() requires an array');
116
+ }
117
+
118
+ return array.reduce((acc, item) => {
119
+ const key = keyFn(item);
120
+ if (!acc[key]) {
121
+ acc[key] = [];
122
+ }
123
+ acc[key].push(item);
124
+ return acc;
125
+ }, {});
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Partition array based on predicate
131
+ */
132
+ function partition(predicate) {
133
+ return (array) => {
134
+ if (!Array.isArray(array)) {
135
+ throw new Error('partition() requires an array');
136
+ }
137
+
138
+ return array.reduce((acc, item) => {
139
+ acc[predicate(item) ? 0 : 1].push(item);
140
+ return acc;
141
+ }, [[], []]);
142
+ };
143
+ }
144
+
145
+ /**
146
+ * Take first N elements
147
+ */
148
+ function take(n) {
149
+ return (array) => {
150
+ if (!Array.isArray(array)) {
151
+ throw new Error('take() requires an array');
152
+ }
153
+ return array.slice(0, n);
154
+ };
155
+ }
156
+
157
+ /**
158
+ * Drop first N elements
159
+ */
160
+ function drop(n) {
161
+ return (array) => {
162
+ if (!Array.isArray(array)) {
163
+ throw new Error('drop() requires an array');
164
+ }
165
+ return array.slice(n);
166
+ };
167
+ }
168
+
169
+ /**
170
+ * Zip multiple arrays
171
+ */
172
+ function zip(...arrays) {
173
+ const maxLength = Math.max(...arrays.map(arr => arr.length));
174
+ const result = [];
175
+
176
+ for (let i = 0; i < maxLength; i++) {
177
+ result.push(arrays.map(arr => arr[i]));
178
+ }
179
+
180
+ return result;
181
+ }
182
+
183
+ /**
184
+ * Object transformation: pick keys
185
+ */
186
+ function pick(keys) {
187
+ return (obj) => {
188
+ if (typeof obj !== 'object' || obj === null) {
189
+ throw new Error('pick() requires an object');
190
+ }
191
+
192
+ return keys.reduce((acc, key) => {
193
+ if (key in obj) {
194
+ acc[key] = obj[key];
195
+ }
196
+ return acc;
197
+ }, {});
198
+ };
199
+ }
200
+
201
+ /**
202
+ * Object transformation: omit keys
203
+ */
204
+ function omit(keys) {
205
+ return (obj) => {
206
+ if (typeof obj !== 'object' || obj === null) {
207
+ throw new Error('omit() requires an object');
208
+ }
209
+
210
+ const result = { ...obj };
211
+ keys.forEach(key => delete result[key]);
212
+ return result;
213
+ };
214
+ }
215
+
216
+ /**
217
+ * Deep clone
218
+ */
219
+ function clone(obj) {
220
+ if (obj === null || typeof obj !== 'object') {
221
+ return obj;
222
+ }
223
+
224
+ if (Array.isArray(obj)) {
225
+ return obj.map(clone);
226
+ }
227
+
228
+ return Object.keys(obj).reduce((acc, key) => {
229
+ acc[key] = clone(obj[key]);
230
+ return acc;
231
+ }, {});
232
+ }
233
+
234
+ /**
235
+ * Merge objects deeply
236
+ */
237
+ function merge(...objects) {
238
+ const result = {};
239
+
240
+ for (const obj of objects) {
241
+ for (const key in obj) {
242
+ if (obj.hasOwnProperty(key)) {
243
+ if (typeof obj[key] === 'object' && !Array.isArray(obj[key]) && obj[key] !== null) {
244
+ result[key] = merge(result[key] || {}, obj[key]);
245
+ } else {
246
+ result[key] = obj[key];
247
+ }
248
+ }
249
+ }
250
+ }
251
+
252
+ return result;
253
+ }
254
+
255
+ module.exports = {
256
+ pipe,
257
+ map,
258
+ filter,
259
+ reduce,
260
+ sort,
261
+ unique,
262
+ chunk,
263
+ flatten,
264
+ groupBy,
265
+ partition,
266
+ take,
267
+ drop,
268
+ zip,
269
+ pick,
270
+ omit,
271
+ clone,
272
+ merge
273
+ };