holosphere 1.1.6 → 1.1.8
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/FEDERATION.md +108 -160
- package/README.md +140 -0
- package/examples/federation.js +154 -0
- package/examples/references.js +177 -0
- package/federation.js +637 -372
- package/holosphere.d.ts +445 -20
- package/holosphere.js +343 -126
- package/package.json +1 -4
- package/test/delete.test.js +225 -0
- package/test/federation.test.js +50 -2
- package/config/default.js +0 -1
- package/services/environmentalApi.js +0 -253
- package/services/environmentalApitest.js +0 -164
- package/test/ai.test.js +0 -425
- package/test/sea.html +0 -33
- /package/test/{holonauth.test.js → auth.test.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "holosphere",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "Holonic Geospatial Communication Infrastructure",
|
|
5
5
|
"main": "holosphere.js",
|
|
6
6
|
"types": "holosphere.d.ts",
|
|
@@ -14,14 +14,11 @@
|
|
|
14
14
|
"license": "GPL-3.0-or-later",
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"ajv": "^8.12.0",
|
|
17
|
-
"axios": "^1.6.7",
|
|
18
|
-
"dotenv": "^16.4.7",
|
|
19
17
|
"gun": "^0.2020.1240",
|
|
20
18
|
"h3-js": "^4.1.0",
|
|
21
19
|
"openai": "^4.85.1"
|
|
22
20
|
},
|
|
23
21
|
"devDependencies": {
|
|
24
|
-
"@babel/preset-env": "^7.24.0",
|
|
25
22
|
"jest": "^29.7.0",
|
|
26
23
|
"jest-environment-node": "^29.7.0"
|
|
27
24
|
},
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import HoloSphere from '../holosphere.js';
|
|
2
|
+
import { jest } from '@jest/globals';
|
|
3
|
+
|
|
4
|
+
// Configure Jest
|
|
5
|
+
jest.setTimeout(30000); // 30 second timeout
|
|
6
|
+
|
|
7
|
+
describe('HoloSphere Deletion Tests', () => {
|
|
8
|
+
const testAppName = 'test-app-deletion';
|
|
9
|
+
const testHolon = 'testHolonDeletion';
|
|
10
|
+
const testLens = 'testLensDeletion';
|
|
11
|
+
const testGlobalTable = 'testGlobalTable';
|
|
12
|
+
const testPassword = 'testPassword1234';
|
|
13
|
+
let holoSphere;
|
|
14
|
+
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
holoSphere = new HoloSphere(testAppName, false, null);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
afterAll(async () => {
|
|
20
|
+
// Clean up all test data
|
|
21
|
+
await holoSphere.deleteAll(testHolon, testLens);
|
|
22
|
+
await holoSphere.deleteAllGlobal(testGlobalTable);
|
|
23
|
+
|
|
24
|
+
// Close Gun connections
|
|
25
|
+
if (holoSphere) {
|
|
26
|
+
await holoSphere.close();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Wait for connections to close
|
|
30
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('Basic Deletion', () => {
|
|
34
|
+
test('should delete a single item properly', async () => {
|
|
35
|
+
// Create test data
|
|
36
|
+
const testData = { id: 'delete-test-1', value: 'delete me' };
|
|
37
|
+
|
|
38
|
+
// Store data
|
|
39
|
+
await holoSphere.put(testHolon, testLens, testData);
|
|
40
|
+
|
|
41
|
+
// Verify data exists
|
|
42
|
+
const storedData = await holoSphere.get(testHolon, testLens, testData.id);
|
|
43
|
+
expect(storedData).toBeDefined();
|
|
44
|
+
expect(storedData.value).toBe(testData.value);
|
|
45
|
+
|
|
46
|
+
// Delete data
|
|
47
|
+
const deleteResult = await holoSphere.delete(testHolon, testLens, testData.id);
|
|
48
|
+
expect(deleteResult).toBe(true);
|
|
49
|
+
|
|
50
|
+
// Verify data is deleted
|
|
51
|
+
const deletedData = await holoSphere.get(testHolon, testLens, testData.id);
|
|
52
|
+
expect(deletedData).toBeNull();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('should delete a node properly', async () => {
|
|
56
|
+
// Create test node data
|
|
57
|
+
const nodeData = { value: 'node-to-delete' };
|
|
58
|
+
const nodeKey = 'test-node-key';
|
|
59
|
+
|
|
60
|
+
// Store node
|
|
61
|
+
await holoSphere.putNode(testHolon, testLens, { id: nodeKey, value: nodeData });
|
|
62
|
+
|
|
63
|
+
// Verify node exists
|
|
64
|
+
const storedNode = await holoSphere.getNode(testHolon, testLens, 'value');
|
|
65
|
+
expect(storedNode).toBeDefined();
|
|
66
|
+
|
|
67
|
+
// Delete node
|
|
68
|
+
const deleteResult = await holoSphere.deleteNode(testHolon, testLens, 'value');
|
|
69
|
+
expect(deleteResult).toBe(true);
|
|
70
|
+
|
|
71
|
+
// Verify node is deleted
|
|
72
|
+
const deletedNode = await holoSphere.getNode(testHolon, testLens, 'value');
|
|
73
|
+
expect(deletedNode).toBeNull();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe('Bulk Deletion', () => {
|
|
78
|
+
test('should delete all items in a lens', async () => {
|
|
79
|
+
// Create multiple test items
|
|
80
|
+
const items = [
|
|
81
|
+
{ id: 'bulk-delete-1', value: 'bulk 1' },
|
|
82
|
+
{ id: 'bulk-delete-2', value: 'bulk 2' },
|
|
83
|
+
{ id: 'bulk-delete-3', value: 'bulk 3' }
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
// Store all items
|
|
87
|
+
for (const item of items) {
|
|
88
|
+
await holoSphere.put(testHolon, testLens, item);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Verify items exist
|
|
92
|
+
const allItems = await holoSphere.getAll(testHolon, testLens);
|
|
93
|
+
expect(allItems.length).toBeGreaterThanOrEqual(items.length);
|
|
94
|
+
|
|
95
|
+
// Delete all items
|
|
96
|
+
const deleteAllResult = await holoSphere.deleteAll(testHolon, testLens);
|
|
97
|
+
expect(deleteAllResult).toBe(true);
|
|
98
|
+
|
|
99
|
+
// Verify all items are deleted
|
|
100
|
+
const remainingItems = await holoSphere.getAll(testHolon, testLens);
|
|
101
|
+
expect(remainingItems.length).toBe(0);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe('Global Table Deletion', () => {
|
|
106
|
+
test('should delete global items properly', async () => {
|
|
107
|
+
// Create global test data
|
|
108
|
+
const globalData = { id: 'global-delete-test', value: 'global delete me' };
|
|
109
|
+
|
|
110
|
+
// Store global data
|
|
111
|
+
await holoSphere.putGlobal(testGlobalTable, globalData);
|
|
112
|
+
|
|
113
|
+
// Verify global data exists
|
|
114
|
+
const storedGlobalData = await holoSphere.getGlobal(testGlobalTable, globalData.id);
|
|
115
|
+
expect(storedGlobalData).toBeDefined();
|
|
116
|
+
expect(storedGlobalData.value).toBe(globalData.value);
|
|
117
|
+
|
|
118
|
+
// Delete global data
|
|
119
|
+
const deleteResult = await holoSphere.deleteGlobal(testGlobalTable, globalData.id);
|
|
120
|
+
expect(deleteResult).toBe(true);
|
|
121
|
+
|
|
122
|
+
// Verify global data is deleted
|
|
123
|
+
const deletedGlobalData = await holoSphere.getGlobal(testGlobalTable, globalData.id);
|
|
124
|
+
expect(deletedGlobalData).toBeNull();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('should delete all global items in a table', async () => {
|
|
128
|
+
// Create multiple global test items
|
|
129
|
+
const items = [
|
|
130
|
+
{ id: 'global-bulk-1', value: 'global bulk 1' },
|
|
131
|
+
{ id: 'global-bulk-2', value: 'global bulk 2' },
|
|
132
|
+
{ id: 'global-bulk-3', value: 'global bulk 3' }
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
// Store all global items
|
|
136
|
+
for (const item of items) {
|
|
137
|
+
await holoSphere.putGlobal(testGlobalTable, item);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Verify global items exist
|
|
141
|
+
const allGlobalItems = await holoSphere.getAllGlobal(testGlobalTable);
|
|
142
|
+
expect(allGlobalItems.length).toBeGreaterThanOrEqual(items.length);
|
|
143
|
+
|
|
144
|
+
// Delete all global items
|
|
145
|
+
const deleteAllResult = await holoSphere.deleteAllGlobal(testGlobalTable);
|
|
146
|
+
expect(deleteAllResult).toBe(true);
|
|
147
|
+
|
|
148
|
+
// Verify all global items are deleted
|
|
149
|
+
const remainingGlobalItems = await holoSphere.getAllGlobal(testGlobalTable);
|
|
150
|
+
expect(remainingGlobalItems.length).toBe(0);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('Private Data Deletion', () => {
|
|
155
|
+
test('should delete private data properly', async () => {
|
|
156
|
+
// Create private test data
|
|
157
|
+
const privateData = { id: 'private-delete-test', value: 'private delete me' };
|
|
158
|
+
|
|
159
|
+
// Store private data
|
|
160
|
+
await holoSphere.put(testHolon, testLens, privateData, testPassword);
|
|
161
|
+
|
|
162
|
+
// Verify private data exists
|
|
163
|
+
const storedPrivateData = await holoSphere.get(testHolon, testLens, privateData.id, testPassword);
|
|
164
|
+
expect(storedPrivateData).toBeDefined();
|
|
165
|
+
expect(storedPrivateData.value).toBe(privateData.value);
|
|
166
|
+
|
|
167
|
+
// Delete private data
|
|
168
|
+
const deleteResult = await holoSphere.delete(testHolon, testLens, privateData.id, testPassword);
|
|
169
|
+
expect(deleteResult).toBe(true);
|
|
170
|
+
|
|
171
|
+
// Verify private data is deleted
|
|
172
|
+
const deletedPrivateData = await holoSphere.get(testHolon, testLens, privateData.id, testPassword);
|
|
173
|
+
expect(deletedPrivateData).toBeNull();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('should delete all private items in a lens', async () => {
|
|
177
|
+
// Create multiple private test items
|
|
178
|
+
const items = [
|
|
179
|
+
{ id: 'private-bulk-1', value: 'private bulk 1' },
|
|
180
|
+
{ id: 'private-bulk-2', value: 'private bulk 2' },
|
|
181
|
+
{ id: 'private-bulk-3', value: 'private bulk 3' }
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
// Store all private items
|
|
185
|
+
for (const item of items) {
|
|
186
|
+
await holoSphere.put(testHolon, testLens, item, testPassword);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Verify private items exist
|
|
190
|
+
const allPrivateItems = await holoSphere.getAll(testHolon, testLens, testPassword);
|
|
191
|
+
expect(allPrivateItems.length).toBeGreaterThanOrEqual(items.length);
|
|
192
|
+
|
|
193
|
+
// Delete all private items
|
|
194
|
+
const deleteAllResult = await holoSphere.deleteAll(testHolon, testLens, testPassword);
|
|
195
|
+
expect(deleteAllResult).toBe(true);
|
|
196
|
+
|
|
197
|
+
// Verify all private items are deleted
|
|
198
|
+
const remainingPrivateItems = await holoSphere.getAll(testHolon, testLens, testPassword);
|
|
199
|
+
expect(remainingPrivateItems.length).toBe(0);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
describe('Edge Cases', () => {
|
|
204
|
+
test('should handle deletion of non-existent items gracefully', async () => {
|
|
205
|
+
// Try to delete non-existent item
|
|
206
|
+
const deleteResult = await holoSphere.delete(testHolon, testLens, 'non-existent-id');
|
|
207
|
+
expect(deleteResult).toBe(true); // Gun returns success even for non-existent items
|
|
208
|
+
|
|
209
|
+
// Try to delete non-existent global item
|
|
210
|
+
const deleteGlobalResult = await holoSphere.deleteGlobal(testGlobalTable, 'non-existent-global-id');
|
|
211
|
+
expect(deleteGlobalResult).toBe(true);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test('should handle invalid parameters gracefully', async () => {
|
|
215
|
+
// Test with missing parameters
|
|
216
|
+
await expect(holoSphere.delete(null, testLens, 'test-id')).rejects.toThrow();
|
|
217
|
+
await expect(holoSphere.delete(testHolon, null, 'test-id')).rejects.toThrow();
|
|
218
|
+
await expect(holoSphere.delete(testHolon, testLens, null)).rejects.toThrow();
|
|
219
|
+
|
|
220
|
+
// Test with missing global parameters
|
|
221
|
+
await expect(holoSphere.deleteGlobal(null, 'test-id')).rejects.toThrow();
|
|
222
|
+
await expect(holoSphere.deleteGlobal(testGlobalTable, null)).rejects.toThrow();
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
});
|
package/test/federation.test.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import HoloSphere from '../holosphere.js';
|
|
2
2
|
import { jest } from '@jest/globals';
|
|
3
3
|
|
|
4
|
+
// Increase the default test timeout for all tests
|
|
5
|
+
jest.setTimeout(30000);
|
|
6
|
+
|
|
4
7
|
describe('Federation Tests', () => {
|
|
5
8
|
let holosphere;
|
|
6
9
|
const testPrefix = `test_${Date.now()}_`;
|
|
@@ -36,6 +39,50 @@ describe('Federation Tests', () => {
|
|
|
36
39
|
}
|
|
37
40
|
});
|
|
38
41
|
|
|
42
|
+
test('should set up the correct notification structure', async () => {
|
|
43
|
+
const space1 = `${testPrefix}notify_space1`;
|
|
44
|
+
const space2 = `${testPrefix}notify_space2`;
|
|
45
|
+
|
|
46
|
+
// Create federation
|
|
47
|
+
await holosphere.federate(space1, space2, null, null);
|
|
48
|
+
|
|
49
|
+
// Allow time for federation to be created
|
|
50
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
51
|
+
|
|
52
|
+
// In the current implementation:
|
|
53
|
+
// space1's federation list should contain space2
|
|
54
|
+
// space2's notify list should contain space1
|
|
55
|
+
const fedInfo1 = await holosphere.getGlobal('federation', space1);
|
|
56
|
+
expect(fedInfo1).toBeTruthy();
|
|
57
|
+
expect(fedInfo1.federation).toContain(space2);
|
|
58
|
+
|
|
59
|
+
const fedInfo2 = await holosphere.getGlobal('federation', space2);
|
|
60
|
+
expect(fedInfo2).toBeTruthy();
|
|
61
|
+
expect(fedInfo2.notify).toContain(space1);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('should respect unidirectional settings', async () => {
|
|
65
|
+
const space1 = `${testPrefix}one_way_space1`;
|
|
66
|
+
const space2 = `${testPrefix}one_way_space2`;
|
|
67
|
+
|
|
68
|
+
// Create federation with bidirectional=false
|
|
69
|
+
await holosphere.federate(space1, space2, null, null, false);
|
|
70
|
+
|
|
71
|
+
// Allow time for federation to be created
|
|
72
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
73
|
+
|
|
74
|
+
// Verify federation structure:
|
|
75
|
+
// space1 has space2 in federation list
|
|
76
|
+
// space2 has space1 in notify list (this is different from the original test)
|
|
77
|
+
const fedInfo1 = await holosphere.getGlobal('federation', space1);
|
|
78
|
+
expect(fedInfo1).toBeTruthy();
|
|
79
|
+
expect(fedInfo1.federation).toContain(space2);
|
|
80
|
+
|
|
81
|
+
const fedInfo2 = await holosphere.getGlobal('federation', space2);
|
|
82
|
+
expect(fedInfo2).toBeTruthy();
|
|
83
|
+
expect(fedInfo2.notify).toContain(space1);
|
|
84
|
+
});
|
|
85
|
+
|
|
39
86
|
test('should throw error when trying to federate a space with itself', async () => {
|
|
40
87
|
const space = `${testPrefix}self_fed_space`;
|
|
41
88
|
await expect(holosphere.federate(space, space, null))
|
|
@@ -107,16 +154,17 @@ describe('Federation Tests', () => {
|
|
|
107
154
|
});
|
|
108
155
|
});
|
|
109
156
|
|
|
110
|
-
describe('
|
|
157
|
+
describe('propagate', () => {
|
|
111
158
|
test('should handle propagation to non-federated space gracefully', async () => {
|
|
112
159
|
const space = `${testPrefix}no_fed_space`;
|
|
113
160
|
const data = { id: 'test-item', value: 42 };
|
|
114
161
|
|
|
115
162
|
// Try to propagate to a space with no federation
|
|
116
|
-
const result = await holosphere.
|
|
163
|
+
const result = await holosphere.propagate(space, 'items', data);
|
|
117
164
|
|
|
118
165
|
// Should have a message property but not fail
|
|
119
166
|
expect(result).toBeDefined();
|
|
167
|
+
expect(result.message).toBeDefined();
|
|
120
168
|
});
|
|
121
169
|
});
|
|
122
170
|
});
|
package/config/default.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import dotenv from 'dotenv';
|
|
3
|
-
|
|
4
|
-
dotenv.config();
|
|
5
|
-
|
|
6
|
-
const logError = (service, error) => {
|
|
7
|
-
const status = error.response?.status;
|
|
8
|
-
const message = error.response?.data?.message || error.message;
|
|
9
|
-
console.error(`${service} API Error:`, { status, message });
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Fetch Carbon Sequestration Data (Using NASA POWER API)
|
|
14
|
-
*/
|
|
15
|
-
export async function getCarbonSequestration(lat = 41.9, lon = 12.5) {
|
|
16
|
-
try {
|
|
17
|
-
const response = await axios.default.get(
|
|
18
|
-
`https://power.larc.nasa.gov/api/temporal/daily/point?parameters=T2M,PRECTOT,PS,WS2M&community=RE&longitude=${lon}&latitude=${lat}&start=20230101&end=20231231&format=JSON`
|
|
19
|
-
);
|
|
20
|
-
return response.data;
|
|
21
|
-
} catch (error) {
|
|
22
|
-
logError('Carbon Sequestration', error);
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Fetch Soil Carbon Data (Using ISRIC World Soil Information)
|
|
29
|
-
*/
|
|
30
|
-
export async function getSoilCarbon(lat = 41.9, lon = 12.5) {
|
|
31
|
-
try {
|
|
32
|
-
const response = await axios.default.get(
|
|
33
|
-
`https://rest.isric.org/soilgrids/v2.0/properties/query?lat=${lat}&lon=${lon}&property=soc&depth=0-30cm&value=mean`
|
|
34
|
-
);
|
|
35
|
-
return response.data;
|
|
36
|
-
} catch (error) {
|
|
37
|
-
logError('Soil Carbon', error);
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Fetch Biodiversity Data (GBIF API)
|
|
44
|
-
*/
|
|
45
|
-
export async function getBiodiversityData(countryCode = "ITA") {
|
|
46
|
-
try {
|
|
47
|
-
const response = await axios.default.get(`https://api.gbif.org/v1/occurrence/search?country=${countryCode}&limit=100`);
|
|
48
|
-
return response.data;
|
|
49
|
-
} catch (error) {
|
|
50
|
-
logError('Biodiversity', error);
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Fetch Vegetation Cover Data (Using NASA MODIS Vegetation Index)
|
|
57
|
-
*/
|
|
58
|
-
export async function getVegetationCover(lat = 41.9, lon = 12.5) {
|
|
59
|
-
try {
|
|
60
|
-
const response = await axios.default.get(
|
|
61
|
-
`https://modis.ornl.gov/rst/api/v1/MOD13Q1/subset?latitude=${lat}&longitude=${lon}&band=NDVI&startDate=2023-01-01&endDate=2023-12-31`,
|
|
62
|
-
{
|
|
63
|
-
headers: {
|
|
64
|
-
'Accept': 'application/json'
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
return response.data;
|
|
69
|
-
} catch (error) {
|
|
70
|
-
logError('Vegetation Cover', error);
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Fetch Air Quality Data (OpenWeather API)
|
|
77
|
-
*/
|
|
78
|
-
export async function getAirQuality(lat = 41.9, lon = 12.5) {
|
|
79
|
-
try {
|
|
80
|
-
const response = await axios.default.get(
|
|
81
|
-
`https://api.openweathermap.org/data/2.5/air_pollution?lat=${lat}&lon=${lon}&appid=${process.env.OPENWEATHER_API_KEY}`
|
|
82
|
-
);
|
|
83
|
-
return response.data;
|
|
84
|
-
} catch (error) {
|
|
85
|
-
logError('Air Quality', error);
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Fetch Water Retention Data (Using USGS Water Services)
|
|
92
|
-
*/
|
|
93
|
-
export async function getWaterRetention(lat = 41.9, lon = 12.5) {
|
|
94
|
-
try {
|
|
95
|
-
const response = await axios.default.get(
|
|
96
|
-
`https://waterservices.usgs.gov/nwis/iv/?format=json&sites=11447650&siteStatus=active`,
|
|
97
|
-
{
|
|
98
|
-
headers: {
|
|
99
|
-
'Accept': 'application/json'
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
);
|
|
103
|
-
return response.data;
|
|
104
|
-
} catch (error) {
|
|
105
|
-
logError('Water Retention', error);
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Fetch Deforestation Data (Using World Bank Forest Data)
|
|
112
|
-
*/
|
|
113
|
-
export async function getDeforestationData(countryCode = "ITA") {
|
|
114
|
-
try {
|
|
115
|
-
const response = await axios.default.get(
|
|
116
|
-
`https://api.worldbank.org/v2/country/${countryCode}/indicator/AG.LND.FRST.ZS?format=json`
|
|
117
|
-
);
|
|
118
|
-
return response.data;
|
|
119
|
-
} catch (error) {
|
|
120
|
-
logError('Deforestation', error);
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Fetch Flood Risk Data (Using USGS Water Services)
|
|
127
|
-
*/
|
|
128
|
-
export async function getFloodRisk(lat = 41.9, lon = 12.5) {
|
|
129
|
-
try {
|
|
130
|
-
const response = await axios.default.get(
|
|
131
|
-
`https://waterservices.usgs.gov/nwis/iv/?format=json&stateCd=CA¶meterCd=00065&siteStatus=active`,
|
|
132
|
-
{
|
|
133
|
-
headers: {
|
|
134
|
-
'Accept': 'application/json'
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
);
|
|
138
|
-
return response.data;
|
|
139
|
-
} catch (error) {
|
|
140
|
-
logError('Flood Risk', error);
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Fetch Food Security Data (World Bank API)
|
|
147
|
-
*/
|
|
148
|
-
export async function getFoodSecurity(countryCode = "ITA") {
|
|
149
|
-
try {
|
|
150
|
-
const response = await axios.default.get(
|
|
151
|
-
`https://api.worldbank.org/v2/country/${countryCode}/indicator/SN.ITK.DEFC.ZS?format=json`
|
|
152
|
-
);
|
|
153
|
-
return response.data;
|
|
154
|
-
} catch (error) {
|
|
155
|
-
logError('Food Security', error);
|
|
156
|
-
return null;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Fetch Local Employment Rate (World Bank API)
|
|
162
|
-
*/
|
|
163
|
-
export async function getEmploymentRate(countryCode = "ITA") {
|
|
164
|
-
try {
|
|
165
|
-
const response = await axios.default.get(
|
|
166
|
-
`https://api.worldbank.org/v2/country/${countryCode}/indicator/SL.EMP.TOTL.SP.ZS?format=json`
|
|
167
|
-
);
|
|
168
|
-
return response.data;
|
|
169
|
-
} catch (error) {
|
|
170
|
-
logError('Employment Rate', error);
|
|
171
|
-
return null;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Fetch Governance Score (World Bank API)
|
|
177
|
-
*/
|
|
178
|
-
export async function getTransparencyScore(countryCode = "ITA") {
|
|
179
|
-
try {
|
|
180
|
-
const response = await axios.default.get(
|
|
181
|
-
`https://api.worldbank.org/v2/country/${countryCode}/indicator/GE.EST?format=json`
|
|
182
|
-
);
|
|
183
|
-
return response.data;
|
|
184
|
-
} catch (error) {
|
|
185
|
-
logError('Transparency Score', error);
|
|
186
|
-
return null;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Fetch Blockchain Transactions (Etherscan API)
|
|
192
|
-
*/
|
|
193
|
-
export async function getBlockchainTransactions(address = "0x0000000000000000000000000000000000000000") {
|
|
194
|
-
try {
|
|
195
|
-
const response = await axios.default.get(
|
|
196
|
-
`https://api.etherscan.io/api?module=account&action=txlist&address=${address}&startblock=0&endblock=99999999&sort=desc&apikey=${process.env.ETHERSCAN_API_KEY}`
|
|
197
|
-
);
|
|
198
|
-
return response.data;
|
|
199
|
-
} catch (error) {
|
|
200
|
-
logError('Blockchain Transactions', error);
|
|
201
|
-
return null;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Fetch Circular Economy Data (Using World Bank Development Indicators)
|
|
207
|
-
*/
|
|
208
|
-
export async function getCircularEconomyData(countryCode = "ITA") {
|
|
209
|
-
try {
|
|
210
|
-
const response = await axios.default.get(
|
|
211
|
-
`https://api.worldbank.org/v2/country/${countryCode}/indicator/EN.ATM.GHGT.KT.CE?format=json`
|
|
212
|
-
);
|
|
213
|
-
return response.data;
|
|
214
|
-
} catch (error) {
|
|
215
|
-
logError('Circular Economy', error);
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Fetch Renewable Energy Data (World Bank API)
|
|
222
|
-
*/
|
|
223
|
-
export async function getRenewableEnergyData(countryCode = "ITA") {
|
|
224
|
-
try {
|
|
225
|
-
const response = await axios.default.get(
|
|
226
|
-
`https://api.worldbank.org/v2/country/${countryCode}/indicator/EG.FEC.RNEW.ZS?format=json`
|
|
227
|
-
);
|
|
228
|
-
return response.data;
|
|
229
|
-
} catch (error) {
|
|
230
|
-
logError('Renewable Energy', error);
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Fetch Climate Change Data (NOAA Climate API)
|
|
237
|
-
*/
|
|
238
|
-
export async function getClimateChangeData(lat = 41.9, lon = 12.5) {
|
|
239
|
-
try {
|
|
240
|
-
const response = await axios.default.get(
|
|
241
|
-
`https://www.ncdc.noaa.gov/cdo-web/api/v2/data?datasetid=GHCND&latitude=${lat}&longitude=${lon}&startdate=2023-01-01&enddate=2023-12-31&limit=1000`,
|
|
242
|
-
{
|
|
243
|
-
headers: {
|
|
244
|
-
'token': process.env.NOAA_API_KEY
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
);
|
|
248
|
-
return response.data;
|
|
249
|
-
} catch (error) {
|
|
250
|
-
logError('Climate Change', error);
|
|
251
|
-
return null;
|
|
252
|
-
}
|
|
253
|
-
}
|