@forgehive/hive-sdk 0.0.1 → 0.0.3
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 +335 -19
- package/dist/index.d.ts +27 -3
- package/dist/index.js +36 -15
- package/dist/test/getLog.test.js +8 -12
- package/dist/test/index.test.js +13 -13
- package/dist/test/metadata.test.d.ts +1 -0
- package/dist/test/metadata.test.js +352 -0
- package/dist/test/sendLog.test.js +15 -19
- package/dist/test/setQuality.test.js +10 -17
- package/package.json +1 -1
- package/src/index.ts +154 -15
- package/src/test/getLog.test.ts +9 -15
- package/src/test/index.test.ts +13 -13
- package/src/test/metadata.test.ts +467 -0
- package/src/test/sendLog.test.ts +16 -22
- package/src/test/setQuality.test.ts +11 -21
package/dist/test/index.test.js
CHANGED
|
@@ -15,31 +15,31 @@ describe('Hive SDK', () => {
|
|
|
15
15
|
delete process.env.HIVE_API_KEY;
|
|
16
16
|
process.env.HIVE_API_SECRET = 'test-secret';
|
|
17
17
|
process.env.HIVE_HOST = 'https://test.com';
|
|
18
|
-
expect(() => new index_1.HiveLogClient('test-project')).not.toThrow();
|
|
18
|
+
expect(() => new index_1.HiveLogClient({ projectName: 'test-project' })).not.toThrow();
|
|
19
19
|
});
|
|
20
20
|
it('should create client in silent mode when HIVE_API_SECRET is missing', () => {
|
|
21
21
|
process.env.HIVE_API_KEY = 'test-key';
|
|
22
22
|
delete process.env.HIVE_API_SECRET;
|
|
23
23
|
process.env.HIVE_HOST = 'https://test.com';
|
|
24
|
-
expect(() => new index_1.HiveLogClient('test-project')).not.toThrow();
|
|
24
|
+
expect(() => new index_1.HiveLogClient({ projectName: 'test-project' })).not.toThrow();
|
|
25
25
|
});
|
|
26
26
|
it('should create client in silent mode when HIVE_HOST is missing', () => {
|
|
27
27
|
process.env.HIVE_API_KEY = 'test-key';
|
|
28
28
|
process.env.HIVE_API_SECRET = 'test-secret';
|
|
29
29
|
delete process.env.HIVE_HOST;
|
|
30
|
-
expect(() => new index_1.HiveLogClient('test-project')).not.toThrow();
|
|
30
|
+
expect(() => new index_1.HiveLogClient({ projectName: 'test-project' })).not.toThrow();
|
|
31
31
|
});
|
|
32
32
|
it('should create client in silent mode when all environment variables are missing', () => {
|
|
33
33
|
delete process.env.HIVE_API_KEY;
|
|
34
34
|
delete process.env.HIVE_API_SECRET;
|
|
35
35
|
delete process.env.HIVE_HOST;
|
|
36
|
-
expect(() => new index_1.HiveLogClient('test-project')).not.toThrow();
|
|
36
|
+
expect(() => new index_1.HiveLogClient({ projectName: 'test-project' })).not.toThrow();
|
|
37
37
|
});
|
|
38
38
|
it('should create client successfully when all environment variables are present', () => {
|
|
39
39
|
process.env.HIVE_API_KEY = 'test-key';
|
|
40
40
|
process.env.HIVE_API_SECRET = 'test-secret';
|
|
41
41
|
process.env.HIVE_HOST = 'https://test.com';
|
|
42
|
-
expect(() => new index_1.HiveLogClient('test-project')).not.toThrow();
|
|
42
|
+
expect(() => new index_1.HiveLogClient({ projectName: 'test-project' })).not.toThrow();
|
|
43
43
|
});
|
|
44
44
|
});
|
|
45
45
|
describe('isActive method', () => {
|
|
@@ -47,14 +47,14 @@ describe('Hive SDK', () => {
|
|
|
47
47
|
delete process.env.HIVE_API_KEY;
|
|
48
48
|
delete process.env.HIVE_API_SECRET;
|
|
49
49
|
delete process.env.HIVE_HOST;
|
|
50
|
-
const client = new index_1.HiveLogClient('test-project');
|
|
50
|
+
const client = new index_1.HiveLogClient({ projectName: 'test-project' });
|
|
51
51
|
expect(client.isActive()).toBe(false);
|
|
52
52
|
});
|
|
53
53
|
it('should return true when all credentials are present', () => {
|
|
54
54
|
process.env.HIVE_API_KEY = 'test-key';
|
|
55
55
|
process.env.HIVE_API_SECRET = 'test-secret';
|
|
56
56
|
process.env.HIVE_HOST = 'https://test.com';
|
|
57
|
-
const client = new index_1.HiveLogClient('test-project');
|
|
57
|
+
const client = new index_1.HiveLogClient({ projectName: 'test-project' });
|
|
58
58
|
expect(client.isActive()).toBe(true);
|
|
59
59
|
});
|
|
60
60
|
});
|
|
@@ -63,14 +63,14 @@ describe('Hive SDK', () => {
|
|
|
63
63
|
process.env.HIVE_API_KEY = 'test-key';
|
|
64
64
|
process.env.HIVE_API_SECRET = 'test-secret';
|
|
65
65
|
process.env.HIVE_HOST = 'https://test.com';
|
|
66
|
-
const client = (0, index_1.createHiveLogClient)('test-project');
|
|
66
|
+
const client = (0, index_1.createHiveLogClient)({ projectName: 'test-project' });
|
|
67
67
|
expect(client).toBeInstanceOf(index_1.HiveLogClient);
|
|
68
68
|
});
|
|
69
69
|
it('should create client in silent mode when env vars are missing', () => {
|
|
70
70
|
delete process.env.HIVE_API_KEY;
|
|
71
71
|
delete process.env.HIVE_API_SECRET;
|
|
72
72
|
delete process.env.HIVE_HOST;
|
|
73
|
-
expect(() => (0, index_1.createHiveLogClient)('test-project')).not.toThrow();
|
|
73
|
+
expect(() => (0, index_1.createHiveLogClient)({ projectName: 'test-project' })).not.toThrow();
|
|
74
74
|
});
|
|
75
75
|
});
|
|
76
76
|
describe('Silent mode behavior', () => {
|
|
@@ -79,18 +79,18 @@ describe('Hive SDK', () => {
|
|
|
79
79
|
delete process.env.HIVE_API_KEY;
|
|
80
80
|
delete process.env.HIVE_API_SECRET;
|
|
81
81
|
delete process.env.HIVE_HOST;
|
|
82
|
-
silentClient = new index_1.HiveLogClient('silent-project');
|
|
82
|
+
silentClient = new index_1.HiveLogClient({ projectName: 'silent-project' });
|
|
83
83
|
});
|
|
84
84
|
it('should return "silent" for sendLog in silent mode', async () => {
|
|
85
|
-
const result = await silentClient.sendLog('test-task', {
|
|
85
|
+
const result = await silentClient.sendLog('test-task', { input: 'test' });
|
|
86
86
|
expect(result).toBe('silent');
|
|
87
87
|
});
|
|
88
88
|
it('should throw error for getLog in silent mode', async () => {
|
|
89
|
-
await expect(silentClient.getLog('test-task', 'test-uuid')).rejects.toThrow('Missing Hive API credentials or host, get them at https://forgehive.
|
|
89
|
+
await expect(silentClient.getLog('test-task', 'test-uuid')).rejects.toThrow('Missing Hive API credentials or host, get them at https://www.forgehive.cloud');
|
|
90
90
|
});
|
|
91
91
|
it('should throw error for setQuality in silent mode', async () => {
|
|
92
92
|
const quality = { score: 8, reason: 'test', suggestions: 'test' };
|
|
93
|
-
await expect(silentClient.setQuality('test-task', 'test-uuid', quality)).rejects.toThrow('Missing Hive API credentials or host, get them at https://forgehive.
|
|
93
|
+
await expect(silentClient.setQuality('test-task', 'test-uuid', quality)).rejects.toThrow('Missing Hive API credentials or host, get them at https://www.forgehive.cloud');
|
|
94
94
|
});
|
|
95
95
|
});
|
|
96
96
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const axios_1 = __importDefault(require("axios"));
|
|
7
|
+
const index_1 = require("../index");
|
|
8
|
+
// Mock axios
|
|
9
|
+
jest.mock('axios');
|
|
10
|
+
const mockedAxios = axios_1.default;
|
|
11
|
+
describe('HiveLogClient Metadata', () => {
|
|
12
|
+
const testConfig = {
|
|
13
|
+
projectName: 'test-project',
|
|
14
|
+
apiKey: 'test-api-key',
|
|
15
|
+
apiSecret: 'test-api-secret',
|
|
16
|
+
host: 'https://test-host.com'
|
|
17
|
+
};
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
// Clear all mocks
|
|
20
|
+
jest.clearAllMocks();
|
|
21
|
+
});
|
|
22
|
+
describe('Constructor with base metadata', () => {
|
|
23
|
+
it('should create client without base metadata', () => {
|
|
24
|
+
const client = new index_1.HiveLogClient(testConfig);
|
|
25
|
+
expect(client).toBeInstanceOf(index_1.HiveLogClient);
|
|
26
|
+
expect(client.isActive()).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
it('should create client with base metadata', () => {
|
|
29
|
+
const baseMetadata = {
|
|
30
|
+
environment: 'production',
|
|
31
|
+
version: '1.0.0',
|
|
32
|
+
service: 'test-service'
|
|
33
|
+
};
|
|
34
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
|
|
35
|
+
expect(client).toBeInstanceOf(index_1.HiveLogClient);
|
|
36
|
+
expect(client.isActive()).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it('should handle empty base metadata object', () => {
|
|
39
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: {} });
|
|
40
|
+
expect(client).toBeInstanceOf(index_1.HiveLogClient);
|
|
41
|
+
expect(client.isActive()).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
it('should handle undefined base metadata', () => {
|
|
44
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: undefined });
|
|
45
|
+
expect(client).toBeInstanceOf(index_1.HiveLogClient);
|
|
46
|
+
expect(client.isActive()).toBe(true);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe('createHiveLogClient factory with metadata', () => {
|
|
50
|
+
it('should create client without base metadata', () => {
|
|
51
|
+
const client = (0, index_1.createHiveLogClient)(testConfig);
|
|
52
|
+
expect(client).toBeInstanceOf(index_1.HiveLogClient);
|
|
53
|
+
});
|
|
54
|
+
it('should create client with base metadata', () => {
|
|
55
|
+
const baseMetadata = {
|
|
56
|
+
environment: 'development',
|
|
57
|
+
team: 'backend'
|
|
58
|
+
};
|
|
59
|
+
const client = (0, index_1.createHiveLogClient)({ ...testConfig, metadata: baseMetadata });
|
|
60
|
+
expect(client).toBeInstanceOf(index_1.HiveLogClient);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe('sendLog with metadata parameter', () => {
|
|
64
|
+
let client;
|
|
65
|
+
beforeEach(() => {
|
|
66
|
+
client = new index_1.HiveLogClient(testConfig);
|
|
67
|
+
});
|
|
68
|
+
it('should send log without metadata parameter', async () => {
|
|
69
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
70
|
+
const logItem = { input: 'test-input', output: 'test-output' };
|
|
71
|
+
const result = await client.sendLog('test-task', logItem);
|
|
72
|
+
expect(result).toBe('success');
|
|
73
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
74
|
+
projectName: 'test-project',
|
|
75
|
+
taskName: 'test-task',
|
|
76
|
+
logItem: JSON.stringify({
|
|
77
|
+
input: 'test-input',
|
|
78
|
+
output: 'test-output',
|
|
79
|
+
metadata: {}
|
|
80
|
+
})
|
|
81
|
+
}, {
|
|
82
|
+
headers: {
|
|
83
|
+
Authorization: 'Bearer test-api-key:test-api-secret',
|
|
84
|
+
'Content-Type': 'application/json'
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
it('should send log with metadata parameter', async () => {
|
|
89
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
90
|
+
const logItem = { input: 'test-input', output: 'test-output' };
|
|
91
|
+
const metadata = {
|
|
92
|
+
requestId: 'req-123',
|
|
93
|
+
userId: 'user-456'
|
|
94
|
+
};
|
|
95
|
+
const result = await client.sendLog('test-task', logItem, metadata);
|
|
96
|
+
expect(result).toBe('success');
|
|
97
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
98
|
+
projectName: 'test-project',
|
|
99
|
+
taskName: 'test-task',
|
|
100
|
+
logItem: JSON.stringify({
|
|
101
|
+
input: 'test-input',
|
|
102
|
+
output: 'test-output',
|
|
103
|
+
metadata: {
|
|
104
|
+
requestId: 'req-123',
|
|
105
|
+
userId: 'user-456'
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
}, {
|
|
109
|
+
headers: {
|
|
110
|
+
Authorization: 'Bearer test-api-key:test-api-secret',
|
|
111
|
+
'Content-Type': 'application/json'
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
it('should handle logItem with only input property', async () => {
|
|
116
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
117
|
+
const metadata = { type: 'minimal' };
|
|
118
|
+
const result = await client.sendLog('test-task', { input: 'simple input' }, metadata);
|
|
119
|
+
expect(result).toBe('success');
|
|
120
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
121
|
+
projectName: 'test-project',
|
|
122
|
+
taskName: 'test-task',
|
|
123
|
+
logItem: JSON.stringify({
|
|
124
|
+
input: 'simple input',
|
|
125
|
+
metadata: { type: 'minimal' }
|
|
126
|
+
})
|
|
127
|
+
}, expect.any(Object));
|
|
128
|
+
});
|
|
129
|
+
it('should handle logItem with null input values', async () => {
|
|
130
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
131
|
+
const metadata = { type: 'null-test' };
|
|
132
|
+
const result = await client.sendLog('test-task', { input: null }, metadata);
|
|
133
|
+
expect(result).toBe('success');
|
|
134
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
135
|
+
projectName: 'test-project',
|
|
136
|
+
taskName: 'test-task',
|
|
137
|
+
logItem: JSON.stringify({
|
|
138
|
+
input: null,
|
|
139
|
+
metadata: { type: 'null-test' }
|
|
140
|
+
})
|
|
141
|
+
}, expect.any(Object));
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe('Metadata priority system', () => {
|
|
145
|
+
it('should use only base metadata when no other metadata provided', async () => {
|
|
146
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
147
|
+
const baseMetadata = {
|
|
148
|
+
environment: 'production',
|
|
149
|
+
version: '1.0.0'
|
|
150
|
+
};
|
|
151
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
|
|
152
|
+
const logItem = { input: 'test' };
|
|
153
|
+
await client.sendLog('test-task', logItem);
|
|
154
|
+
const expectedLogItem = {
|
|
155
|
+
input: 'test',
|
|
156
|
+
metadata: {
|
|
157
|
+
environment: 'production',
|
|
158
|
+
version: '1.0.0'
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
162
|
+
projectName: 'test-project',
|
|
163
|
+
taskName: 'test-task',
|
|
164
|
+
logItem: JSON.stringify(expectedLogItem)
|
|
165
|
+
}, expect.any(Object));
|
|
166
|
+
});
|
|
167
|
+
it('should merge logItem metadata with base metadata', async () => {
|
|
168
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
169
|
+
const baseMetadata = {
|
|
170
|
+
environment: 'production',
|
|
171
|
+
version: '1.0.0'
|
|
172
|
+
};
|
|
173
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
|
|
174
|
+
const logItem = {
|
|
175
|
+
input: 'test',
|
|
176
|
+
metadata: {
|
|
177
|
+
sessionId: 'session-123',
|
|
178
|
+
version: '1.1.0' // This should override base version
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
await client.sendLog('test-task', logItem);
|
|
182
|
+
const expectedLogItem = {
|
|
183
|
+
input: 'test',
|
|
184
|
+
metadata: {
|
|
185
|
+
environment: 'production', // from base
|
|
186
|
+
version: '1.1.0', // from logItem (overrides base)
|
|
187
|
+
sessionId: 'session-123' // from logItem
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
191
|
+
projectName: 'test-project',
|
|
192
|
+
taskName: 'test-task',
|
|
193
|
+
logItem: JSON.stringify(expectedLogItem)
|
|
194
|
+
}, expect.any(Object));
|
|
195
|
+
});
|
|
196
|
+
it('should give sendLog metadata highest priority', async () => {
|
|
197
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
198
|
+
const baseMetadata = {
|
|
199
|
+
environment: 'production',
|
|
200
|
+
version: '1.0.0',
|
|
201
|
+
priority: 'base'
|
|
202
|
+
};
|
|
203
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
|
|
204
|
+
const logItem = {
|
|
205
|
+
input: 'test',
|
|
206
|
+
metadata: {
|
|
207
|
+
sessionId: 'session-123',
|
|
208
|
+
version: '1.1.0',
|
|
209
|
+
priority: 'logItem'
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
const sendLogMetadata = {
|
|
213
|
+
requestId: 'req-456',
|
|
214
|
+
version: '1.2.0',
|
|
215
|
+
priority: 'sendLog'
|
|
216
|
+
};
|
|
217
|
+
await client.sendLog('test-task', logItem, sendLogMetadata);
|
|
218
|
+
const expectedLogItem = {
|
|
219
|
+
input: 'test',
|
|
220
|
+
metadata: {
|
|
221
|
+
environment: 'production', // from base
|
|
222
|
+
version: '1.2.0', // from sendLog (highest priority)
|
|
223
|
+
priority: 'sendLog', // from sendLog (highest priority)
|
|
224
|
+
sessionId: 'session-123', // from logItem
|
|
225
|
+
requestId: 'req-456' // from sendLog
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
229
|
+
projectName: 'test-project',
|
|
230
|
+
taskName: 'test-task',
|
|
231
|
+
logItem: JSON.stringify(expectedLogItem)
|
|
232
|
+
}, expect.any(Object));
|
|
233
|
+
});
|
|
234
|
+
it('should handle all three metadata sources with complex merging', async () => {
|
|
235
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
236
|
+
const baseMetadata = {
|
|
237
|
+
environment: 'production',
|
|
238
|
+
service: 'api-gateway',
|
|
239
|
+
version: '1.0.0',
|
|
240
|
+
datacenter: 'us-west-2'
|
|
241
|
+
};
|
|
242
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
|
|
243
|
+
const logItem = {
|
|
244
|
+
input: { query: 'search' },
|
|
245
|
+
output: { results: [] },
|
|
246
|
+
metadata: {
|
|
247
|
+
algorithm: 'fuzzy-search',
|
|
248
|
+
processingTime: '250',
|
|
249
|
+
version: '1.1.0' // overrides base
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
const sendLogMetadata = {
|
|
253
|
+
requestId: 'req-789',
|
|
254
|
+
userId: 'user-123',
|
|
255
|
+
version: '1.2.0' // overrides both base and logItem
|
|
256
|
+
};
|
|
257
|
+
await client.sendLog('search-task', logItem, sendLogMetadata);
|
|
258
|
+
const expectedLogItem = {
|
|
259
|
+
input: { query: 'search' },
|
|
260
|
+
output: { results: [] },
|
|
261
|
+
metadata: {
|
|
262
|
+
environment: 'production', // from base
|
|
263
|
+
service: 'api-gateway', // from base
|
|
264
|
+
version: '1.2.0', // from sendLog (highest priority)
|
|
265
|
+
datacenter: 'us-west-2', // from base
|
|
266
|
+
algorithm: 'fuzzy-search', // from logItem
|
|
267
|
+
processingTime: '250', // from logItem
|
|
268
|
+
requestId: 'req-789', // from sendLog
|
|
269
|
+
userId: 'user-123' // from sendLog
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
273
|
+
projectName: 'test-project',
|
|
274
|
+
taskName: 'search-task',
|
|
275
|
+
logItem: JSON.stringify(expectedLogItem)
|
|
276
|
+
}, expect.any(Object));
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
describe('Edge cases and error handling', () => {
|
|
280
|
+
it('should handle logItem without metadata property', async () => {
|
|
281
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
282
|
+
const baseMetadata = { environment: 'test' };
|
|
283
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
|
|
284
|
+
const logItem = {
|
|
285
|
+
input: 'test'
|
|
286
|
+
// No metadata property
|
|
287
|
+
};
|
|
288
|
+
await client.sendLog('test-task', logItem);
|
|
289
|
+
const expectedLogItem = {
|
|
290
|
+
input: 'test',
|
|
291
|
+
metadata: {
|
|
292
|
+
environment: 'test' // Only base metadata should be used
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
296
|
+
projectName: 'test-project',
|
|
297
|
+
taskName: 'test-task',
|
|
298
|
+
logItem: JSON.stringify(expectedLogItem)
|
|
299
|
+
}, expect.any(Object));
|
|
300
|
+
});
|
|
301
|
+
it('should handle logItem with undefined metadata', async () => {
|
|
302
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
303
|
+
const baseMetadata = { environment: 'test' };
|
|
304
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
|
|
305
|
+
const logItem = {
|
|
306
|
+
input: 'test',
|
|
307
|
+
metadata: undefined
|
|
308
|
+
};
|
|
309
|
+
await client.sendLog('test-task', logItem);
|
|
310
|
+
const expectedLogItem = {
|
|
311
|
+
input: 'test',
|
|
312
|
+
metadata: {
|
|
313
|
+
environment: 'test' // Only base metadata should be used
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
317
|
+
projectName: 'test-project',
|
|
318
|
+
taskName: 'test-task',
|
|
319
|
+
logItem: JSON.stringify(expectedLogItem)
|
|
320
|
+
}, expect.any(Object));
|
|
321
|
+
});
|
|
322
|
+
it('should handle empty metadata objects', async () => {
|
|
323
|
+
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
324
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: {} });
|
|
325
|
+
const logItem = { input: 'test', metadata: {} };
|
|
326
|
+
await client.sendLog('test-task', logItem, {});
|
|
327
|
+
const expectedLogItem = {
|
|
328
|
+
input: 'test',
|
|
329
|
+
metadata: {} // All empty metadata objects result in empty final metadata
|
|
330
|
+
};
|
|
331
|
+
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
332
|
+
projectName: 'test-project',
|
|
333
|
+
taskName: 'test-task',
|
|
334
|
+
logItem: JSON.stringify(expectedLogItem)
|
|
335
|
+
}, expect.any(Object));
|
|
336
|
+
});
|
|
337
|
+
it('should work in silent mode with metadata', async () => {
|
|
338
|
+
const baseMetadata = { environment: 'test' };
|
|
339
|
+
const silentClient = new index_1.HiveLogClient({ projectName: 'silent-project', metadata: baseMetadata });
|
|
340
|
+
const result = await silentClient.sendLog('test-task', { input: 'test' }, { requestId: 'req-123' });
|
|
341
|
+
expect(result).toBe('silent');
|
|
342
|
+
expect(mockedAxios.post).not.toHaveBeenCalled();
|
|
343
|
+
});
|
|
344
|
+
it('should handle network errors with metadata', async () => {
|
|
345
|
+
mockedAxios.post.mockRejectedValueOnce(new Error('Network error'));
|
|
346
|
+
const baseMetadata = { environment: 'test' };
|
|
347
|
+
const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
|
|
348
|
+
const result = await client.sendLog('test-task', { input: 'test' }, { requestId: 'req-123' });
|
|
349
|
+
expect(result).toBe('error');
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
});
|
|
@@ -9,23 +9,19 @@ const index_1 = require("../index");
|
|
|
9
9
|
jest.mock('axios');
|
|
10
10
|
const mockedAxios = axios_1.default;
|
|
11
11
|
describe('HiveLogClient sendLog', () => {
|
|
12
|
-
const originalEnv = process.env;
|
|
13
12
|
let client;
|
|
13
|
+
const testConfig = {
|
|
14
|
+
projectName: 'test-project',
|
|
15
|
+
apiKey: 'test-api-key',
|
|
16
|
+
apiSecret: 'test-api-secret',
|
|
17
|
+
host: 'https://test-host.com'
|
|
18
|
+
};
|
|
14
19
|
beforeEach(() => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// Set up environment variables
|
|
18
|
-
process.env.HIVE_API_KEY = 'test-api-key';
|
|
19
|
-
process.env.HIVE_API_SECRET = 'test-api-secret';
|
|
20
|
-
process.env.HIVE_HOST = 'https://test-host.com';
|
|
21
|
-
// Create client instance
|
|
22
|
-
client = new index_1.HiveLogClient('test-project');
|
|
20
|
+
// Create client instance with config
|
|
21
|
+
client = new index_1.HiveLogClient(testConfig);
|
|
23
22
|
// Clear all mocks
|
|
24
23
|
jest.clearAllMocks();
|
|
25
24
|
});
|
|
26
|
-
afterAll(() => {
|
|
27
|
-
process.env = originalEnv;
|
|
28
|
-
});
|
|
29
25
|
describe('successful sendLog', () => {
|
|
30
26
|
it('should send log successfully and return true', async () => {
|
|
31
27
|
// Mock successful axios response
|
|
@@ -37,7 +33,7 @@ describe('HiveLogClient sendLog', () => {
|
|
|
37
33
|
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
38
34
|
projectName: 'test-project',
|
|
39
35
|
taskName: 'test-task',
|
|
40
|
-
logItem: JSON.stringify(logItem)
|
|
36
|
+
logItem: JSON.stringify({ ...logItem, metadata: {} })
|
|
41
37
|
}, {
|
|
42
38
|
headers: {
|
|
43
39
|
Authorization: 'Bearer test-api-key:test-api-secret',
|
|
@@ -60,7 +56,7 @@ describe('HiveLogClient sendLog', () => {
|
|
|
60
56
|
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
61
57
|
projectName: 'test-project',
|
|
62
58
|
taskName: 'complex-task',
|
|
63
|
-
logItem: JSON.stringify(complexLogItem)
|
|
59
|
+
logItem: JSON.stringify({ ...complexLogItem, metadata: {} })
|
|
64
60
|
}, {
|
|
65
61
|
headers: {
|
|
66
62
|
Authorization: 'Bearer test-api-key:test-api-secret',
|
|
@@ -86,14 +82,14 @@ describe('HiveLogClient sendLog', () => {
|
|
|
86
82
|
});
|
|
87
83
|
});
|
|
88
84
|
describe('sendLog parameters', () => {
|
|
89
|
-
it('should handle
|
|
85
|
+
it('should handle log items with minimal input', async () => {
|
|
90
86
|
mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
|
|
91
|
-
const result = await client.sendLog('
|
|
87
|
+
const result = await client.sendLog('minimal-task', { input: 'minimal input' });
|
|
92
88
|
expect(result).toBe('success');
|
|
93
89
|
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
94
90
|
projectName: 'test-project',
|
|
95
|
-
taskName: '
|
|
96
|
-
logItem: JSON.stringify({})
|
|
91
|
+
taskName: 'minimal-task',
|
|
92
|
+
logItem: JSON.stringify({ input: 'minimal input', metadata: {} })
|
|
97
93
|
}, expect.any(Object));
|
|
98
94
|
});
|
|
99
95
|
it('should handle null/undefined values in log items', async () => {
|
|
@@ -104,7 +100,7 @@ describe('HiveLogClient sendLog', () => {
|
|
|
104
100
|
expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
|
|
105
101
|
projectName: 'test-project',
|
|
106
102
|
taskName: 'null-task',
|
|
107
|
-
logItem: JSON.stringify(logItem)
|
|
103
|
+
logItem: JSON.stringify({ ...logItem, metadata: {} })
|
|
108
104
|
}, expect.any(Object));
|
|
109
105
|
});
|
|
110
106
|
});
|
|
@@ -9,23 +9,19 @@ const index_1 = require("../index");
|
|
|
9
9
|
jest.mock('axios');
|
|
10
10
|
const mockedAxios = axios_1.default;
|
|
11
11
|
describe('HiveLogClient setQuality', () => {
|
|
12
|
-
const originalEnv = process.env;
|
|
13
12
|
let client;
|
|
13
|
+
const testConfig = {
|
|
14
|
+
projectName: 'test-project',
|
|
15
|
+
apiKey: 'test-api-key',
|
|
16
|
+
apiSecret: 'test-api-secret',
|
|
17
|
+
host: 'https://test-host.com'
|
|
18
|
+
};
|
|
14
19
|
beforeEach(() => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// Set up environment variables
|
|
18
|
-
process.env.HIVE_API_KEY = 'test-api-key';
|
|
19
|
-
process.env.HIVE_API_SECRET = 'test-api-secret';
|
|
20
|
-
process.env.HIVE_HOST = 'https://test-host.com';
|
|
21
|
-
// Create client instance
|
|
22
|
-
client = new index_1.HiveLogClient('test-project');
|
|
20
|
+
// Create client instance with config
|
|
21
|
+
client = new index_1.HiveLogClient(testConfig);
|
|
23
22
|
// Clear all mocks
|
|
24
23
|
jest.clearAllMocks();
|
|
25
24
|
});
|
|
26
|
-
afterAll(() => {
|
|
27
|
-
process.env = originalEnv;
|
|
28
|
-
});
|
|
29
25
|
describe('successful setQuality', () => {
|
|
30
26
|
it('should set quality successfully and return true', async () => {
|
|
31
27
|
// Mock successful axios response
|
|
@@ -173,10 +169,7 @@ describe('HiveLogClient setQuality', () => {
|
|
|
173
169
|
describe('silent mode behavior', () => {
|
|
174
170
|
it('should throw error when credentials are missing', async () => {
|
|
175
171
|
// Create client without credentials
|
|
176
|
-
|
|
177
|
-
process.env.HIVE_API_SECRET = '';
|
|
178
|
-
process.env.HIVE_HOST = '';
|
|
179
|
-
const silentClient = new index_1.HiveLogClient('silent-project');
|
|
172
|
+
const silentClient = new index_1.HiveLogClient({ projectName: 'silent-project' });
|
|
180
173
|
const quality = {
|
|
181
174
|
score: 8.0,
|
|
182
175
|
reason: 'Test quality for silent mode',
|
|
@@ -184,7 +177,7 @@ describe('HiveLogClient setQuality', () => {
|
|
|
184
177
|
};
|
|
185
178
|
await expect(silentClient.setQuality('test-task', 'test-uuid', quality))
|
|
186
179
|
.rejects
|
|
187
|
-
.toThrow('Missing Hive API credentials or host, get them at https://forgehive.
|
|
180
|
+
.toThrow('Missing Hive API credentials or host, get them at https://www.forgehive.cloud');
|
|
188
181
|
// Verify axios was never called
|
|
189
182
|
expect(mockedAxios.post).not.toHaveBeenCalled();
|
|
190
183
|
});
|