@forgehive/hive-sdk 0.1.6 → 0.3.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/dist/index.d.ts CHANGED
@@ -61,13 +61,11 @@ export declare class HiveLogClient {
61
61
  }>;
62
62
  private mergeMetadata;
63
63
  sendLog(record: ExecutionRecord, metadata?: Metadata): Promise<'success' | 'error' | 'silent' | LogApiSuccess>;
64
- sendLogByUuid(record: ExecutionRecord, taskUuid: string, metadata?: Metadata): Promise<'success' | 'error' | 'silent' | LogApiSuccess>;
65
64
  getListener(): (record: ExecutionRecord) => Promise<void>;
66
65
  getLog(taskName: string, uuid: string): Promise<LogApiResult | null>;
67
66
  setQuality(taskName: string, uuid: string, quality: Quality): Promise<boolean>;
68
67
  private loadForgeConfig;
69
68
  private getTaskUUID;
70
- sendLogByName(taskName: string, record: ExecutionRecord, metadata?: Metadata): Promise<'success' | 'error' | 'silent' | LogApiSuccess>;
71
69
  }
72
70
  export declare const createHiveLogClient: (config: HiveLogClientConfig) => HiveLogClient;
73
71
  export interface HiveClientConfig {
package/dist/index.js CHANGED
@@ -169,55 +169,19 @@ class HiveLogClient {
169
169
  log('Silent mode: Skipping sendLog for task "%s" - client not initialized', taskName);
170
170
  return 'silent';
171
171
  }
172
- // Deprecation warning for legacy endpoint
173
- log('DEPRECATION WARNING: sendLog() is deprecated. Use sendLogByUuid() with project and task UUIDs for enhanced features and better performance.');
174
- try {
175
- const logsUrl = `${this.host}/api/tasks/log-ingest`;
176
- log('Sending log for task "%s" to %s', taskName, logsUrl);
177
- const authToken = `${this.apiKey}:${this.apiSecret}`;
178
- // Merge metadata with priority: sendLog > record.metadata > client
179
- const finalMetadata = this.mergeMetadata(record, metadata);
180
- // Create logItem with merged metadata (no UUID generation for legacy method)
181
- const logItem = {
182
- ...record,
183
- taskName,
184
- metadata: finalMetadata
185
- };
186
- const response = await axios_1.default.post(logsUrl, {
187
- projectName: this.projectName,
188
- taskName,
189
- logItem: JSON.stringify(logItem)
190
- }, {
191
- headers: {
192
- Authorization: `Bearer ${authToken}`,
193
- 'Content-Type': 'application/json'
194
- }
195
- });
196
- log('Success: Sent log for task "%s"', taskName);
197
- // Return the full response data if available
198
- if (response.data && typeof response.data === 'object' && 'uuid' in response.data) {
199
- return response.data;
200
- }
201
- return 'success';
202
- }
203
- catch (e) {
204
- const error = e;
205
- log('Error: Failed to send log for task "%s": %s', taskName, error.message);
172
+ if (!this.projectUuid) {
173
+ log('Error: sendLog requires projectUuid to be set in client config');
206
174
  return 'error';
207
175
  }
208
- }
209
- async sendLogByUuid(record, taskUuid, metadata) {
210
- if (!this.isInitialized) {
211
- log('Silent mode: Skipping sendLogByUuid for task UUID "%s" - client not initialized', taskUuid);
212
- return 'silent';
213
- }
214
- if (!this.projectUuid) {
215
- log('Error: sendLogByUuid requires projectUuid to be set in client config');
176
+ // Look up task UUID from forge.json
177
+ const taskUuid = this.getTaskUUID(taskName);
178
+ if (!taskUuid) {
179
+ log('Error: Cannot find UUID for task "%s" in forge.json', taskName);
216
180
  return 'error';
217
181
  }
218
182
  try {
219
183
  const logsUrl = `${this.host}/api/log-ingest`;
220
- log('Sending log for task UUID "%s" to %s', taskUuid, logsUrl);
184
+ log('Sending log for task "%s" (UUID: %s) to %s', taskName, taskUuid, logsUrl);
221
185
  const authToken = `${this.apiKey}:${this.apiSecret}`;
222
186
  // Merge metadata with priority: sendLog > record.metadata > client
223
187
  const finalMetadata = this.mergeMetadata(record, metadata);
@@ -227,19 +191,17 @@ class HiveLogClient {
227
191
  uuid: record.uuid || (0, uuid_1.v7)(),
228
192
  metadata: finalMetadata
229
193
  };
230
- // Create logItem with merged metadata and UUID
231
- const logItem = recordWithUuid;
232
194
  const response = await axios_1.default.post(logsUrl, {
233
195
  projectUuid: this.projectUuid,
234
196
  taskUuid,
235
- logItem: JSON.stringify(logItem)
197
+ logItem: JSON.stringify(recordWithUuid)
236
198
  }, {
237
199
  headers: {
238
200
  Authorization: `Bearer ${authToken}`,
239
201
  'Content-Type': 'application/json'
240
202
  }
241
203
  });
242
- log('Success: Sent log for task UUID "%s"', taskUuid);
204
+ log('Success: Sent log for task "%s" (UUID: %s)', taskName, taskUuid);
243
205
  // Return the full response data if available
244
206
  if (response.data && typeof response.data === 'object' && 'uuid' in response.data) {
245
207
  return response.data;
@@ -248,7 +210,7 @@ class HiveLogClient {
248
210
  }
249
211
  catch (e) {
250
212
  const error = e;
251
- log('Error: Failed to send log for task UUID "%s": %s', taskUuid, error.message);
213
+ log('Error: Failed to send log for task "%s": %s', taskName, error.message);
252
214
  return 'error';
253
215
  }
254
216
  }
@@ -335,24 +297,6 @@ class HiveLogClient {
335
297
  log('Found UUID "%s" for task "%s"', task.uuid, taskName);
336
298
  return task.uuid;
337
299
  }
338
- async sendLogByName(taskName, record, metadata) {
339
- if (!this.isInitialized) {
340
- log('Silent mode: Skipping sendLogByName for task "%s" - client not initialized', taskName);
341
- return 'silent';
342
- }
343
- if (!this.projectUuid) {
344
- log('Error: sendLogByName requires projectUuid to be set in client config');
345
- return 'error';
346
- }
347
- const taskUuid = this.getTaskUUID(taskName);
348
- if (!taskUuid) {
349
- log('Error: Cannot find UUID for task "%s" in forge.json', taskName);
350
- return 'error';
351
- }
352
- // Use the existing sendLogByUuid method
353
- log('Sending log for task "%s" with uuid "%s"', taskName, taskUuid);
354
- return await this.sendLogByUuid(record, taskUuid, metadata);
355
- }
356
300
  }
357
301
  exports.HiveLogClient = HiveLogClient;
358
302
  const createHiveLogClient = (config) => {
@@ -4,18 +4,44 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const axios_1 = __importDefault(require("axios"));
7
+ const fs_1 = __importDefault(require("fs"));
7
8
  const index_1 = require("../index");
8
- // Mock axios
9
+ // Mock axios and fs
9
10
  jest.mock('axios');
11
+ jest.mock('fs');
10
12
  const mockedAxios = axios_1.default;
13
+ const mockedFs = fs_1.default;
11
14
  describe('HiveLogClient Metadata', () => {
12
15
  const testConfig = {
13
16
  projectName: 'test-project',
17
+ projectUuid: '550e8400-e29b-41d4-a716-446655440000',
14
18
  apiKey: 'test-api-key',
15
19
  apiSecret: 'test-api-secret',
16
- host: 'https://test-host.com'
20
+ host: 'https://test-host.com',
21
+ forgeConfigPath: './forge.json'
22
+ };
23
+ const mockForgeConfig = {
24
+ project: {
25
+ name: 'test-project',
26
+ uuid: '550e8400-e29b-41d4-a716-446655440000'
27
+ },
28
+ tasks: {
29
+ 'test-task': {
30
+ path: 'src/tasks/test.ts',
31
+ handler: 'testTask',
32
+ uuid: 'f47ac10b-58cc-4372-a567-0e02b2c3d479'
33
+ },
34
+ 'search-task': {
35
+ path: 'src/tasks/search.ts',
36
+ handler: 'searchTask',
37
+ uuid: 'a45aafe3-8b01-4b58-b15d-9a96274858ee'
38
+ }
39
+ }
17
40
  };
18
41
  beforeEach(() => {
42
+ // Mock fs
43
+ mockedFs.existsSync.mockReturnValue(true);
44
+ mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockForgeConfig));
19
45
  // Clear all mocks
20
46
  jest.clearAllMocks();
21
47
  });
@@ -64,6 +90,7 @@ describe('HiveLogClient Metadata', () => {
64
90
  let client;
65
91
  beforeEach(() => {
66
92
  client = new index_1.HiveLogClient(testConfig);
93
+ jest.clearAllMocks();
67
94
  });
68
95
  it('should send log without metadata parameter', async () => {
69
96
  mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
@@ -77,23 +104,21 @@ describe('HiveLogClient Metadata', () => {
77
104
  };
78
105
  const result = await client.sendLog(executionRecord);
79
106
  expect(result).toBe('success');
80
- expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
81
- projectName: 'test-project',
82
- taskName: 'test-task',
83
- logItem: JSON.stringify({
84
- input: 'test-input',
85
- output: 'test-output',
86
- taskName: 'test-task',
87
- type: 'success',
88
- boundaries: {},
89
- metadata: {}
90
- })
91
- }, {
92
- headers: {
93
- Authorization: 'Bearer test-api-key:test-api-secret',
94
- 'Content-Type': 'application/json'
95
- }
96
- });
107
+ // Verify it uses the UUID endpoint
108
+ const callArgs = mockedAxios.post.mock.calls[0];
109
+ expect(callArgs[0]).toBe('https://test-host.com/api/log-ingest');
110
+ // Verify request body structure
111
+ const requestBody = callArgs[1];
112
+ expect(requestBody.projectUuid).toBe(testConfig.projectUuid);
113
+ expect(requestBody.taskUuid).toBe('f47ac10b-58cc-4372-a567-0e02b2c3d479');
114
+ // Parse and verify logItem
115
+ const logItem = JSON.parse(requestBody.logItem);
116
+ expect(logItem.uuid).toBeDefined();
117
+ expect(logItem.input).toBe('test-input');
118
+ expect(logItem.output).toBe('test-output');
119
+ expect(logItem.taskName).toBe('test-task');
120
+ expect(logItem.type).toBe('success');
121
+ expect(logItem.metadata).toEqual({});
97
122
  });
98
123
  it('should send log with metadata parameter', async () => {
99
124
  mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
@@ -111,25 +136,13 @@ describe('HiveLogClient Metadata', () => {
111
136
  };
112
137
  const result = await client.sendLog(executionRecord, metadata);
113
138
  expect(result).toBe('success');
114
- expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
115
- projectName: 'test-project',
116
- taskName: 'test-task',
117
- logItem: JSON.stringify({
118
- input: 'test-input',
119
- output: 'test-output',
120
- taskName: 'test-task',
121
- type: 'success',
122
- boundaries: {},
123
- metadata: {
124
- requestId: 'req-123',
125
- userId: 'user-456'
126
- }
127
- })
128
- }, {
129
- headers: {
130
- Authorization: 'Bearer test-api-key:test-api-secret',
131
- 'Content-Type': 'application/json'
132
- }
139
+ const callArgs = mockedAxios.post.mock.calls[0];
140
+ expect(callArgs[0]).toBe('https://test-host.com/api/log-ingest');
141
+ const requestBody = callArgs[1];
142
+ const logItem = JSON.parse(requestBody.logItem);
143
+ expect(logItem.metadata).toEqual({
144
+ requestId: 'req-123',
145
+ userId: 'user-456'
133
146
  });
134
147
  });
135
148
  it('should handle logItem with only input property', async () => {
@@ -137,34 +150,22 @@ describe('HiveLogClient Metadata', () => {
137
150
  const metadata = { type: 'minimal' };
138
151
  const result = await client.sendLog({ input: 'simple input', taskName: 'test-task', type: 'success', boundaries: {}, metadata: {} }, metadata);
139
152
  expect(result).toBe('success');
140
- expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
141
- projectName: 'test-project',
142
- taskName: 'test-task',
143
- logItem: JSON.stringify({
144
- input: 'simple input',
145
- taskName: 'test-task',
146
- type: 'success',
147
- boundaries: {},
148
- metadata: { type: 'minimal' }
149
- })
150
- }, expect.any(Object));
153
+ const callArgs = mockedAxios.post.mock.calls[0];
154
+ const requestBody = callArgs[1];
155
+ const logItem = JSON.parse(requestBody.logItem);
156
+ expect(logItem.input).toBe('simple input');
157
+ expect(logItem.metadata).toEqual({ type: 'minimal' });
151
158
  });
152
159
  it('should handle logItem with null input values', async () => {
153
160
  mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
154
161
  const metadata = { type: 'null-test' };
155
162
  const result = await client.sendLog({ input: null, taskName: 'test-task', type: 'success', boundaries: {}, metadata: {} }, metadata);
156
163
  expect(result).toBe('success');
157
- expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
158
- projectName: 'test-project',
159
- taskName: 'test-task',
160
- logItem: JSON.stringify({
161
- input: null,
162
- taskName: 'test-task',
163
- type: 'success',
164
- boundaries: {},
165
- metadata: { type: 'null-test' }
166
- })
167
- }, expect.any(Object));
164
+ const callArgs = mockedAxios.post.mock.calls[0];
165
+ const requestBody = callArgs[1];
166
+ const logItem = JSON.parse(requestBody.logItem);
167
+ expect(logItem.input).toBeNull();
168
+ expect(logItem.metadata).toEqual({ type: 'null-test' });
168
169
  });
169
170
  });
170
171
  describe('Metadata priority system', () => {
@@ -175,23 +176,16 @@ describe('HiveLogClient Metadata', () => {
175
176
  version: '1.0.0'
176
177
  };
177
178
  const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
179
+ jest.clearAllMocks();
178
180
  const logItem = { input: 'test' };
179
181
  await client.sendLog({ ...logItem, taskName: 'test-task', type: 'success', boundaries: {}, metadata: {} });
180
- const expectedLogItem = {
181
- input: 'test',
182
- taskName: 'test-task',
183
- type: 'success',
184
- boundaries: {},
185
- metadata: {
186
- environment: 'production',
187
- version: '1.0.0'
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));
182
+ const callArgs = mockedAxios.post.mock.calls[0];
183
+ const requestBody = callArgs[1];
184
+ const parsedLogItem = JSON.parse(requestBody.logItem);
185
+ expect(parsedLogItem.metadata).toEqual({
186
+ environment: 'production',
187
+ version: '1.0.0'
188
+ });
195
189
  });
196
190
  it('should merge logItem metadata with base metadata', async () => {
197
191
  mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
@@ -200,6 +194,7 @@ describe('HiveLogClient Metadata', () => {
200
194
  version: '1.0.0'
201
195
  };
202
196
  const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
197
+ jest.clearAllMocks();
203
198
  const logItem = {
204
199
  input: 'test',
205
200
  metadata: {
@@ -208,22 +203,14 @@ describe('HiveLogClient Metadata', () => {
208
203
  }
209
204
  };
210
205
  await client.sendLog({ ...logItem, taskName: 'test-task', type: 'success', boundaries: {}, metadata: logItem.metadata || {} });
211
- const expectedLogItem = {
212
- input: 'test',
213
- metadata: {
214
- environment: 'production', // from base
215
- version: '1.1.0', // from logItem (overrides base)
216
- sessionId: 'session-123' // from logItem
217
- },
218
- taskName: 'test-task',
219
- type: 'success',
220
- boundaries: {}
221
- };
222
- expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
223
- projectName: 'test-project',
224
- taskName: 'test-task',
225
- logItem: JSON.stringify(expectedLogItem)
226
- }, expect.any(Object));
206
+ const callArgs = mockedAxios.post.mock.calls[0];
207
+ const requestBody = callArgs[1];
208
+ const parsedLogItem = JSON.parse(requestBody.logItem);
209
+ expect(parsedLogItem.metadata).toEqual({
210
+ environment: 'production', // from base
211
+ version: '1.1.0', // from logItem (overrides base)
212
+ sessionId: 'session-123' // from logItem
213
+ });
227
214
  });
228
215
  it('should give sendLog metadata highest priority', async () => {
229
216
  mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
@@ -233,6 +220,7 @@ describe('HiveLogClient Metadata', () => {
233
220
  priority: 'base'
234
221
  };
235
222
  const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
223
+ jest.clearAllMocks();
236
224
  const logItem = {
237
225
  input: 'test',
238
226
  metadata: {
@@ -247,24 +235,16 @@ describe('HiveLogClient Metadata', () => {
247
235
  priority: 'sendLog'
248
236
  };
249
237
  await client.sendLog({ ...logItem, taskName: 'test-task', type: 'success', boundaries: {}, metadata: logItem.metadata || {} }, sendLogMetadata);
250
- const expectedLogItem = {
251
- input: 'test',
252
- metadata: {
253
- environment: 'production', // from base
254
- version: '1.2.0', // from sendLog (highest priority)
255
- priority: 'sendLog', // from sendLog (highest priority)
256
- sessionId: 'session-123', // from logItem
257
- requestId: 'req-456' // from sendLog
258
- },
259
- taskName: 'test-task',
260
- type: 'success',
261
- boundaries: {}
262
- };
263
- expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
264
- projectName: 'test-project',
265
- taskName: 'test-task',
266
- logItem: JSON.stringify(expectedLogItem)
267
- }, expect.any(Object));
238
+ const callArgs = mockedAxios.post.mock.calls[0];
239
+ const requestBody = callArgs[1];
240
+ const parsedLogItem = JSON.parse(requestBody.logItem);
241
+ expect(parsedLogItem.metadata).toEqual({
242
+ environment: 'production', // from base
243
+ version: '1.2.0', // from sendLog (highest priority)
244
+ priority: 'sendLog', // from sendLog (highest priority)
245
+ sessionId: 'session-123', // from logItem
246
+ requestId: 'req-456' // from sendLog
247
+ });
268
248
  });
269
249
  it('should handle all three metadata sources with complex merging', async () => {
270
250
  mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
@@ -275,6 +255,7 @@ describe('HiveLogClient Metadata', () => {
275
255
  datacenter: 'us-west-2'
276
256
  };
277
257
  const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
258
+ jest.clearAllMocks();
278
259
  const logItem = {
279
260
  input: { query: 'search' },
280
261
  output: { results: [] },
@@ -290,28 +271,19 @@ describe('HiveLogClient Metadata', () => {
290
271
  version: '1.2.0' // overrides both base and logItem
291
272
  };
292
273
  await client.sendLog({ ...logItem, taskName: 'search-task', type: 'success', boundaries: {}, metadata: logItem.metadata || {} }, sendLogMetadata);
293
- const expectedLogItem = {
294
- input: { query: 'search' },
295
- output: { results: [] },
296
- metadata: {
297
- environment: 'production', // from base
298
- service: 'api-gateway', // from base
299
- version: '1.2.0', // from sendLog (highest priority)
300
- datacenter: 'us-west-2', // from base
301
- algorithm: 'fuzzy-search', // from logItem
302
- processingTime: '250', // from logItem
303
- requestId: 'req-789', // from sendLog
304
- userId: 'user-123' // from sendLog
305
- },
306
- taskName: 'search-task',
307
- type: 'success',
308
- boundaries: {}
309
- };
310
- expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
311
- projectName: 'test-project',
312
- taskName: 'search-task',
313
- logItem: JSON.stringify(expectedLogItem)
314
- }, expect.any(Object));
274
+ const callArgs = mockedAxios.post.mock.calls[0];
275
+ const requestBody = callArgs[1];
276
+ const parsedLogItem = JSON.parse(requestBody.logItem);
277
+ expect(parsedLogItem.metadata).toEqual({
278
+ environment: 'production', // from base
279
+ service: 'api-gateway', // from base
280
+ version: '1.2.0', // from sendLog (highest priority)
281
+ datacenter: 'us-west-2', // from base
282
+ algorithm: 'fuzzy-search', // from logItem
283
+ processingTime: '250', // from logItem
284
+ requestId: 'req-789', // from sendLog
285
+ userId: 'user-123' // from sendLog
286
+ });
315
287
  });
316
288
  });
317
289
  describe('Edge cases and error handling', () => {
@@ -319,67 +291,46 @@ describe('HiveLogClient Metadata', () => {
319
291
  mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
320
292
  const baseMetadata = { environment: 'test' };
321
293
  const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
294
+ jest.clearAllMocks();
322
295
  const logItem = {
323
296
  input: 'test'
324
297
  // No metadata property
325
298
  };
326
299
  await client.sendLog({ ...logItem, taskName: 'test-task', type: 'success', boundaries: {}, metadata: {} });
327
- const expectedLogItem = {
328
- input: 'test',
329
- taskName: 'test-task',
330
- type: 'success',
331
- boundaries: {},
332
- metadata: {
333
- environment: 'test' // Only base metadata should be used
334
- }
335
- };
336
- expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
337
- projectName: 'test-project',
338
- taskName: 'test-task',
339
- logItem: JSON.stringify(expectedLogItem)
340
- }, expect.any(Object));
300
+ const callArgs = mockedAxios.post.mock.calls[0];
301
+ const requestBody = callArgs[1];
302
+ const parsedLogItem = JSON.parse(requestBody.logItem);
303
+ expect(parsedLogItem.metadata).toEqual({
304
+ environment: 'test' // Only base metadata should be used
305
+ });
341
306
  });
342
307
  it('should handle logItem with undefined metadata', async () => {
343
308
  mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
344
309
  const baseMetadata = { environment: 'test' };
345
310
  const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
311
+ jest.clearAllMocks();
346
312
  const logItem = {
347
313
  input: 'test',
348
314
  metadata: undefined
349
315
  };
350
316
  await client.sendLog({ ...logItem, taskName: 'test-task', type: 'success', boundaries: {}, metadata: logItem.metadata || {} });
351
- const expectedLogItem = {
352
- input: 'test',
353
- metadata: {
354
- environment: 'test' // Only base metadata should be used
355
- },
356
- taskName: 'test-task',
357
- type: 'success',
358
- boundaries: {}
359
- };
360
- expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
361
- projectName: 'test-project',
362
- taskName: 'test-task',
363
- logItem: JSON.stringify(expectedLogItem)
364
- }, expect.any(Object));
317
+ const callArgs = mockedAxios.post.mock.calls[0];
318
+ const requestBody = callArgs[1];
319
+ const parsedLogItem = JSON.parse(requestBody.logItem);
320
+ expect(parsedLogItem.metadata).toEqual({
321
+ environment: 'test' // Only base metadata should be used
322
+ });
365
323
  });
366
324
  it('should handle empty metadata objects', async () => {
367
325
  mockedAxios.post.mockResolvedValueOnce({ data: { success: true } });
368
326
  const client = new index_1.HiveLogClient({ ...testConfig, metadata: {} });
327
+ jest.clearAllMocks();
369
328
  const logItem = { input: 'test', metadata: {} };
370
329
  await client.sendLog({ ...logItem, taskName: 'test-task', type: 'success', boundaries: {}, metadata: logItem.metadata || {} }, {});
371
- const expectedLogItem = {
372
- input: 'test',
373
- metadata: {}, // All empty metadata objects result in empty final metadata
374
- taskName: 'test-task',
375
- type: 'success',
376
- boundaries: {}
377
- };
378
- expect(mockedAxios.post).toHaveBeenCalledWith('https://test-host.com/api/tasks/log-ingest', {
379
- projectName: 'test-project',
380
- taskName: 'test-task',
381
- logItem: JSON.stringify(expectedLogItem)
382
- }, expect.any(Object));
330
+ const callArgs = mockedAxios.post.mock.calls[0];
331
+ const requestBody = callArgs[1];
332
+ const parsedLogItem = JSON.parse(requestBody.logItem);
333
+ expect(parsedLogItem.metadata).toEqual({}); // All empty metadata objects result in empty final metadata
383
334
  });
384
335
  it('should work in silent mode with metadata', async () => {
385
336
  const baseMetadata = { environment: 'test' };
@@ -392,6 +343,7 @@ describe('HiveLogClient Metadata', () => {
392
343
  mockedAxios.post.mockRejectedValueOnce(new Error('Network error'));
393
344
  const baseMetadata = { environment: 'test' };
394
345
  const client = new index_1.HiveLogClient({ ...testConfig, metadata: baseMetadata });
346
+ jest.clearAllMocks();
395
347
  const result = await client.sendLog({ input: 'test', taskName: 'test-task', type: 'success', boundaries: {}, metadata: {} }, { requestId: 'req-123' });
396
348
  expect(result).toBe('error');
397
349
  });