@walkeros/server-core 0.0.7 → 0.1.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/README.md +245 -48
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,74 +1,271 @@
|
|
|
1
1
|
<p align="left">
|
|
2
2
|
<a href="https://elbwalker.com">
|
|
3
|
-
<img title="elbwalker" src=
|
|
3
|
+
<img title="elbwalker" src="https://www.elbwalker.com/img/elbwalker_logo.png" width="256px"/>
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
# Server Core Utilities for walkerOS
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
platform-agnostic Core package with Node.js-specific functionality for server
|
|
12
|
-
environment detection, request handling, and server-side event processing.
|
|
9
|
+
[Source Code](https://github.com/elbwalker/walkerOS/tree/main/packages/server/core)
|
|
10
|
+
• [NPM Package](https://www.npmjs.com/package/@walkeros/server-core)
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
Server core utilities are Node.js-specific functions designed for server-side
|
|
13
|
+
walkerOS implementations. These utilities handle server communication,
|
|
14
|
+
cryptographic hashing, and other backend operations.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Import server utilities from the `@walkeros/server-core` package:
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- **Destinations**: Send processed events to analytics platforms (GA4, Meta,
|
|
22
|
-
custom APIs)
|
|
20
|
+
```ts
|
|
21
|
+
import { sendServer, getHashServer } from '@walkeros/server-core';
|
|
22
|
+
```
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
and destinations, providing essential Node.js utilities, request handling, and
|
|
26
|
-
server-specific event processing capabilities.
|
|
24
|
+
## Server Communication
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
### sendServer
|
|
27
|
+
|
|
28
|
+
`sendServer(url: string, data?: SendDataValue, options?: SendServerOptions): Promise<SendResponse>`
|
|
29
|
+
sends HTTP requests using Node.js built-in modules (`http`/`https`).
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
// Simple POST request
|
|
33
|
+
const response = await sendServer('https://api.example.com/events', {
|
|
34
|
+
name: 'page view',
|
|
35
|
+
data: { url: '/home' },
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// With custom options
|
|
39
|
+
const response = await sendServer(url, data, {
|
|
40
|
+
method: 'PUT',
|
|
41
|
+
headers: {
|
|
42
|
+
Authorization: 'Bearer token',
|
|
43
|
+
'Content-Type': 'application/json',
|
|
44
|
+
},
|
|
45
|
+
timeout: 10000, // 10 seconds
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (response.ok) {
|
|
49
|
+
console.log('Data sent successfully:', response.data);
|
|
50
|
+
} else {
|
|
51
|
+
console.error('Send failed:', response.error);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### SendServerOptions
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
interface SendServerOptions {
|
|
59
|
+
headers?: Record<string, string>; // Custom HTTP headers
|
|
60
|
+
method?: string; // HTTP method (default: 'POST')
|
|
61
|
+
timeout?: number; // Request timeout in milliseconds (default: 5000)
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### SendResponse
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
interface SendResponse {
|
|
69
|
+
ok: boolean; // Indicates if the request was successful (2xx status)
|
|
70
|
+
data?: unknown; // Parsed response data (if available)
|
|
71
|
+
error?: string; // Error message (if request failed)
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Cryptographic Operations
|
|
76
|
+
|
|
77
|
+
### getHashServer
|
|
78
|
+
|
|
79
|
+
`getHashServer(str: string, length?: number): Promise<string>` generates SHA-256
|
|
80
|
+
hashes using Node.js crypto module.
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
// Generate full SHA-256 hash
|
|
84
|
+
const fullHash = await getHashServer('user123@example.com');
|
|
85
|
+
// Returns full 64-character hash
|
|
86
|
+
|
|
87
|
+
// Generate shortened hash for anonymization
|
|
88
|
+
const userFingerprint = await getHashServer(
|
|
89
|
+
userAgent + language + ipAddress + date.getDate(),
|
|
90
|
+
16,
|
|
91
|
+
);
|
|
92
|
+
// Returns 16-character hash like '47e0bdd10f04ef13'
|
|
93
|
+
|
|
94
|
+
// User identification while preserving privacy
|
|
95
|
+
const anonymousId = await getHashServer(`${userEmail}${deviceId}${salt}`, 12);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This function is commonly used for:
|
|
99
|
+
|
|
100
|
+
- **User Anonymization**: Creating privacy-safe user identifiers
|
|
101
|
+
- **Fingerprinting**: Generating device/session fingerprints
|
|
102
|
+
- **Data Deduplication**: Creating consistent identifiers
|
|
103
|
+
- **Privacy Compliance**: Hashing PII for GDPR/CCPA compliance
|
|
104
|
+
|
|
105
|
+
## Usage Examples
|
|
106
|
+
|
|
107
|
+
### Event Processing Pipeline
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
import { sendServer, getHashServer } from '@walkeros/server-core';
|
|
111
|
+
|
|
112
|
+
async function processUserEvent(event, userInfo) {
|
|
113
|
+
// Anonymize user identification
|
|
114
|
+
const anonymousUserId = await getHashServer(
|
|
115
|
+
`${userInfo.email}${userInfo.deviceId}`,
|
|
116
|
+
16,
|
|
117
|
+
);
|
|
29
118
|
|
|
30
|
-
|
|
31
|
-
|
|
119
|
+
// Prepare event with anonymized data
|
|
120
|
+
const processedEvent = {
|
|
121
|
+
...event,
|
|
122
|
+
user: {
|
|
123
|
+
...event.user,
|
|
124
|
+
id: anonymousUserId,
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// Send to analytics service
|
|
129
|
+
const result = await sendServer(
|
|
130
|
+
'https://analytics.example.com/collect',
|
|
131
|
+
processedEvent,
|
|
132
|
+
{
|
|
133
|
+
headers: {
|
|
134
|
+
'X-API-Key': process.env.ANALYTICS_API_KEY,
|
|
135
|
+
},
|
|
136
|
+
timeout: 8000,
|
|
137
|
+
},
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Privacy-Safe Session Tracking
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
async function createSessionId(request) {
|
|
148
|
+
const fingerprint = [
|
|
149
|
+
request.headers['user-agent'],
|
|
150
|
+
request.ip.replace(/\.\d+$/, '.0'), // Anonymize IP
|
|
151
|
+
new Date().toDateString(), // Daily rotation
|
|
152
|
+
].join('|');
|
|
153
|
+
|
|
154
|
+
return await getHashServer(fingerprint, 20);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Error Handling
|
|
159
|
+
|
|
160
|
+
Server utilities include comprehensive error handling:
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
try {
|
|
164
|
+
const response = await sendServer(url, data, { timeout: 5000 });
|
|
165
|
+
|
|
166
|
+
if (response.ok) {
|
|
167
|
+
// Success - response.data contains the result
|
|
168
|
+
console.log('Success:', response.data);
|
|
169
|
+
} else {
|
|
170
|
+
// Request completed but with error status
|
|
171
|
+
console.warn('Request failed:', response.error);
|
|
172
|
+
}
|
|
173
|
+
} catch (error) {
|
|
174
|
+
// Network error, timeout, or other exception
|
|
175
|
+
console.error('Network error:', error.message);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Performance Considerations
|
|
180
|
+
|
|
181
|
+
### Timeout Configuration
|
|
182
|
+
|
|
183
|
+
Configure appropriate timeouts based on your use case:
|
|
184
|
+
|
|
185
|
+
```js
|
|
186
|
+
// Fast analytics endpoint
|
|
187
|
+
await sendServer(url, data, { timeout: 2000 });
|
|
188
|
+
|
|
189
|
+
// Critical business data
|
|
190
|
+
await sendServer(url, data, { timeout: 15000 });
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Batch Processing
|
|
194
|
+
|
|
195
|
+
For high-volume scenarios, consider batching:
|
|
196
|
+
|
|
197
|
+
```js
|
|
198
|
+
const events = [
|
|
199
|
+
/* ... multiple events ... */
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
const response = await sendServer(
|
|
203
|
+
'/api/events/batch',
|
|
204
|
+
{
|
|
205
|
+
events,
|
|
206
|
+
timestamp: Date.now(),
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
timeout: 10000,
|
|
210
|
+
},
|
|
211
|
+
);
|
|
32
212
|
```
|
|
33
213
|
|
|
34
|
-
|
|
214
|
+
### Connection Reuse
|
|
35
215
|
|
|
36
|
-
The
|
|
216
|
+
The underlying Node.js HTTP agent automatically reuses connections for better
|
|
217
|
+
performance with multiple requests to the same host.
|
|
37
218
|
|
|
38
|
-
|
|
39
|
-
import {
|
|
40
|
-
// Server utilities
|
|
41
|
-
getHashServer,
|
|
42
|
-
sendServer,
|
|
219
|
+
## Security Notes
|
|
43
220
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
221
|
+
- **HTTPS Only**: Use HTTPS URLs in production for encrypted transmission
|
|
222
|
+
- **API Keys**: Store sensitive credentials in environment variables
|
|
223
|
+
- **Timeout Limits**: Set reasonable timeouts to prevent hanging requests
|
|
224
|
+
- **Hash Salting**: Use application-specific salts when hashing sensitive data
|
|
47
225
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
226
|
+
```js
|
|
227
|
+
// Good security practices
|
|
228
|
+
const apiKey = process.env.ANALYTICS_API_KEY;
|
|
229
|
+
const saltedHash = await getHashServer(`${userData}${process.env.HASH_SALT}`);
|
|
51
230
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
231
|
+
await sendServer('https://secure-api.example.com/events', data, {
|
|
232
|
+
headers: {
|
|
233
|
+
Authorization: `Bearer ${apiKey}`,
|
|
234
|
+
'Content-Type': 'application/json',
|
|
235
|
+
},
|
|
236
|
+
timeout: 5000,
|
|
57
237
|
});
|
|
58
238
|
```
|
|
59
239
|
|
|
60
|
-
## Core
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
240
|
+
## Integration with Core
|
|
241
|
+
|
|
242
|
+
Server utilities work seamlessly with
|
|
243
|
+
[Core Utilities](https://www.elbwalker.com/docs/core):
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
import { getMappingValue, anonymizeIP } from '@walkeros/core';
|
|
247
|
+
import { sendServer, getHashServer } from '@walkeros/server-core';
|
|
248
|
+
|
|
249
|
+
async function processServerSideEvent(rawEvent, clientIP) {
|
|
250
|
+
// Use core utilities for data processing
|
|
251
|
+
const processedData = await getMappingValue(rawEvent, mappingConfig);
|
|
252
|
+
const safeIP = anonymizeIP(clientIP);
|
|
253
|
+
|
|
254
|
+
// Use server utilities for transmission
|
|
255
|
+
const sessionId = await getHashServer(`${safeIP}${userAgent}`, 16);
|
|
256
|
+
|
|
257
|
+
return await sendServer(endpoint, {
|
|
258
|
+
...processedData,
|
|
259
|
+
sessionId,
|
|
260
|
+
ip: safeIP,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
For platform-agnostic utilities, see
|
|
268
|
+
[Core Utilities](https://www.elbwalker.com/docs/core).
|
|
72
269
|
|
|
73
270
|
## Contribute
|
|
74
271
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/server-core",
|
|
3
3
|
"description": "Server-specific utilities for walkerOS",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"update": "npx npm-check-updates -u && npm update"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@walkeros/core": "0.0
|
|
28
|
+
"@walkeros/core": "0.1.0"
|
|
29
29
|
},
|
|
30
30
|
"repository": {
|
|
31
31
|
"url": "git+https://github.com/elbwalker/walkerOS.git",
|