@relazio/plugin-sdk 0.1.1 → 0.2.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/CHANGELOG.md +96 -0
- package/README.md +121 -12
- package/dist/core/types.d.ts +8 -8
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -1
- package/dist/utils/builders.d.ts +147 -0
- package/dist/utils/builders.d.ts.map +1 -0
- package/dist/utils/builders.js +316 -0
- package/dist/utils/id-generator.d.ts +81 -0
- package/dist/utils/id-generator.d.ts.map +1 -0
- package/dist/utils/id-generator.js +122 -0
- package/dist/utils/result-builder.d.ts +109 -0
- package/dist/utils/result-builder.d.ts.map +1 -0
- package/dist/utils/result-builder.js +185 -0
- package/docs/builders-guide.md +520 -0
- package/docs/examples.md +238 -0
- package/docs/quick-start.md +287 -0
- package/docs/response-format.md +515 -0
- package/package.json +4 -2
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EdgeBuilder = exports.EntityBuilder = void 0;
|
|
4
|
+
exports.createEntity = createEntity;
|
|
5
|
+
exports.createEdge = createEdge;
|
|
6
|
+
exports.validateEntities = validateEntities;
|
|
7
|
+
exports.validateEdges = validateEdges;
|
|
8
|
+
exports.validateTransformResult = validateTransformResult;
|
|
9
|
+
const id_generator_1 = require("./id-generator");
|
|
10
|
+
/**
|
|
11
|
+
* Crea un'entità OSINT nel formato corretto
|
|
12
|
+
* Genera automaticamente un ID deterministico se non specificato
|
|
13
|
+
*
|
|
14
|
+
* @param type - Tipo di entità
|
|
15
|
+
* @param value - Valore dell'entità (obbligatorio)
|
|
16
|
+
* @param options - Opzioni aggiuntive (label, metadata, id)
|
|
17
|
+
* @returns Entità nel formato corretto
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* // Esempio semplice
|
|
22
|
+
* createEntity('ip', '8.8.8.8')
|
|
23
|
+
*
|
|
24
|
+
* // Con label e metadata
|
|
25
|
+
* createEntity('ip', '8.8.8.8', {
|
|
26
|
+
* label: 'Google DNS',
|
|
27
|
+
* metadata: { country: 'US', isp: 'Google LLC' }
|
|
28
|
+
* })
|
|
29
|
+
*
|
|
30
|
+
* // Con ID personalizzato
|
|
31
|
+
* createEntity('location', 'Mountain View, CA', {
|
|
32
|
+
* id: 'custom-location-id',
|
|
33
|
+
* metadata: { latitude: 37.386, longitude: -122.084 }
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
function createEntity(type, value, options) {
|
|
38
|
+
if (!value || value.trim() === '') {
|
|
39
|
+
throw new Error('Entity value cannot be empty');
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
id: options?.id || (0, id_generator_1.generateEntityId)(type, value),
|
|
43
|
+
type,
|
|
44
|
+
value: value.trim(),
|
|
45
|
+
...(options?.label && { label: options.label }),
|
|
46
|
+
...(options?.metadata && { metadata: options.metadata }),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Crea un edge tra due entità nel formato corretto
|
|
51
|
+
* Genera automaticamente un ID deterministico se non specificato
|
|
52
|
+
*
|
|
53
|
+
* @param sourceId - ID dell'entità sorgente
|
|
54
|
+
* @param targetId - ID dell'entità target
|
|
55
|
+
* @param label - Label visibile dell'edge (obbligatorio)
|
|
56
|
+
* @param options - Opzioni aggiuntive (id, relationship, metadata)
|
|
57
|
+
* @returns Edge nel formato corretto
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* // Esempio semplice
|
|
62
|
+
* createEdge('ip-c909e98d', 'location-a3f42bc1', 'located in')
|
|
63
|
+
*
|
|
64
|
+
* // Con relationship e metadata
|
|
65
|
+
* createEdge('ip-c909e98d', 'org-5b3c1a2d', 'assigned by', {
|
|
66
|
+
* relationship: 'isp_assignment',
|
|
67
|
+
* metadata: { confidence: 0.98 }
|
|
68
|
+
* })
|
|
69
|
+
*
|
|
70
|
+
* // Con ID personalizzato
|
|
71
|
+
* createEdge('node-1', 'node-2', 'related to', {
|
|
72
|
+
* id: 'custom-edge-id'
|
|
73
|
+
* })
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
function createEdge(sourceId, targetId, label, options) {
|
|
77
|
+
if (!sourceId || sourceId.trim() === '') {
|
|
78
|
+
throw new Error('Edge sourceId cannot be empty');
|
|
79
|
+
}
|
|
80
|
+
if (!targetId || targetId.trim() === '') {
|
|
81
|
+
throw new Error('Edge targetId cannot be empty');
|
|
82
|
+
}
|
|
83
|
+
if (!label || label.trim() === '') {
|
|
84
|
+
throw new Error('Edge label cannot be empty');
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
id: options?.id || (0, id_generator_1.generateEdgeId)(sourceId, targetId, label),
|
|
88
|
+
sourceId: sourceId.trim(),
|
|
89
|
+
targetId: targetId.trim(),
|
|
90
|
+
label: label.trim(),
|
|
91
|
+
...(options?.relationship && { relationship: options.relationship }),
|
|
92
|
+
...(options?.metadata && { metadata: options.metadata }),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* NOTA: Gli helper specifici sono stati rimossi per rendere l'SDK più scalabile.
|
|
97
|
+
* Usa `createEntity(type, value, options)` per creare qualsiasi tipo di entità.
|
|
98
|
+
*
|
|
99
|
+
* Esempio:
|
|
100
|
+
* ```ts
|
|
101
|
+
* createEntity('ip', '8.8.8.8', { metadata: { country: 'US' } })
|
|
102
|
+
* createEntity('domain', 'example.com')
|
|
103
|
+
* createEntity('custom-type', 'value') // Funziona anche con tipi futuri!
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
/**
|
|
107
|
+
* Builder fluente per creare entità complesse
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* const entity = EntityBuilder
|
|
112
|
+
* .create('ip', '8.8.8.8')
|
|
113
|
+
* .withLabel('Google DNS')
|
|
114
|
+
* .withMetadata({ country: 'US', isp: 'Google LLC' })
|
|
115
|
+
* .build();
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
class EntityBuilder {
|
|
119
|
+
constructor(type, value) {
|
|
120
|
+
this.entity = {
|
|
121
|
+
type,
|
|
122
|
+
value: value.trim(),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
static create(type, value) {
|
|
126
|
+
return new EntityBuilder(type, value);
|
|
127
|
+
}
|
|
128
|
+
withId(id) {
|
|
129
|
+
this.entity.id = id;
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
withLabel(label) {
|
|
133
|
+
this.entity.label = label;
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
withMetadata(metadata) {
|
|
137
|
+
this.entity.metadata = { ...this.entity.metadata, ...metadata };
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
addMetadata(key, value) {
|
|
141
|
+
if (!this.entity.metadata) {
|
|
142
|
+
this.entity.metadata = {};
|
|
143
|
+
}
|
|
144
|
+
this.entity.metadata[key] = value;
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
build() {
|
|
148
|
+
if (!this.entity.value) {
|
|
149
|
+
throw new Error('Entity value is required');
|
|
150
|
+
}
|
|
151
|
+
if (!this.entity.type) {
|
|
152
|
+
throw new Error('Entity type is required');
|
|
153
|
+
}
|
|
154
|
+
const id = this.entity.id || (0, id_generator_1.generateEntityId)(this.entity.type, this.entity.value);
|
|
155
|
+
return {
|
|
156
|
+
id,
|
|
157
|
+
type: this.entity.type,
|
|
158
|
+
value: this.entity.value,
|
|
159
|
+
...(this.entity.label && { label: this.entity.label }),
|
|
160
|
+
...(this.entity.metadata && { metadata: this.entity.metadata }),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
exports.EntityBuilder = EntityBuilder;
|
|
165
|
+
/**
|
|
166
|
+
* Builder fluente per creare edge complessi
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* const edge = EdgeBuilder
|
|
171
|
+
* .create('ip-abc', 'location-xyz', 'located in')
|
|
172
|
+
* .withRelationship('geolocation')
|
|
173
|
+
* .withMetadata({ confidence: 0.98 })
|
|
174
|
+
* .build();
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
class EdgeBuilder {
|
|
178
|
+
constructor(sourceId, targetId, label) {
|
|
179
|
+
this.edge = {
|
|
180
|
+
sourceId: sourceId.trim(),
|
|
181
|
+
targetId: targetId.trim(),
|
|
182
|
+
label: label.trim(),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
static create(sourceId, targetId, label) {
|
|
186
|
+
return new EdgeBuilder(sourceId, targetId, label);
|
|
187
|
+
}
|
|
188
|
+
withId(id) {
|
|
189
|
+
this.edge.id = id;
|
|
190
|
+
return this;
|
|
191
|
+
}
|
|
192
|
+
withRelationship(relationship) {
|
|
193
|
+
this.edge.relationship = relationship;
|
|
194
|
+
return this;
|
|
195
|
+
}
|
|
196
|
+
withMetadata(metadata) {
|
|
197
|
+
this.edge.metadata = { ...this.edge.metadata, ...metadata };
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
addMetadata(key, value) {
|
|
201
|
+
if (!this.edge.metadata) {
|
|
202
|
+
this.edge.metadata = {};
|
|
203
|
+
}
|
|
204
|
+
this.edge.metadata[key] = value;
|
|
205
|
+
return this;
|
|
206
|
+
}
|
|
207
|
+
build() {
|
|
208
|
+
if (!this.edge.sourceId) {
|
|
209
|
+
throw new Error('Edge sourceId is required');
|
|
210
|
+
}
|
|
211
|
+
if (!this.edge.targetId) {
|
|
212
|
+
throw new Error('Edge targetId is required');
|
|
213
|
+
}
|
|
214
|
+
if (!this.edge.label) {
|
|
215
|
+
throw new Error('Edge label is required');
|
|
216
|
+
}
|
|
217
|
+
const id = this.edge.id || (0, id_generator_1.generateEdgeId)(this.edge.sourceId, this.edge.targetId, this.edge.label);
|
|
218
|
+
return {
|
|
219
|
+
id,
|
|
220
|
+
sourceId: this.edge.sourceId,
|
|
221
|
+
targetId: this.edge.targetId,
|
|
222
|
+
label: this.edge.label,
|
|
223
|
+
...(this.edge.relationship && { relationship: this.edge.relationship }),
|
|
224
|
+
...(this.edge.metadata && { metadata: this.edge.metadata }),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
exports.EdgeBuilder = EdgeBuilder;
|
|
229
|
+
/**
|
|
230
|
+
* Helper per validare un array di entità
|
|
231
|
+
* Controlla ID duplicati e campi obbligatori
|
|
232
|
+
*/
|
|
233
|
+
function validateEntities(entities) {
|
|
234
|
+
const errors = [];
|
|
235
|
+
const ids = new Set();
|
|
236
|
+
for (const entity of entities) {
|
|
237
|
+
// Verifica campi obbligatori
|
|
238
|
+
if (!entity.id) {
|
|
239
|
+
errors.push(`Entity missing required field: id`);
|
|
240
|
+
}
|
|
241
|
+
if (!entity.type) {
|
|
242
|
+
errors.push(`Entity missing required field: type`);
|
|
243
|
+
}
|
|
244
|
+
if (!entity.value) {
|
|
245
|
+
errors.push(`Entity missing required field: value`);
|
|
246
|
+
}
|
|
247
|
+
// Verifica ID duplicati
|
|
248
|
+
if (entity.id) {
|
|
249
|
+
if (ids.has(entity.id)) {
|
|
250
|
+
errors.push(`Duplicate entity ID: ${entity.id}`);
|
|
251
|
+
}
|
|
252
|
+
ids.add(entity.id);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
valid: errors.length === 0,
|
|
257
|
+
errors,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Helper per validare un array di edge
|
|
262
|
+
* Controlla ID duplicati, campi obbligatori e riferimenti validi
|
|
263
|
+
*/
|
|
264
|
+
function validateEdges(edges, entities, inputEntityId) {
|
|
265
|
+
const errors = [];
|
|
266
|
+
const edgeIds = new Set();
|
|
267
|
+
const entityIds = new Set(entities.map(e => e.id));
|
|
268
|
+
// Aggiungi l'ID dell'entità di input se fornito
|
|
269
|
+
if (inputEntityId) {
|
|
270
|
+
entityIds.add(inputEntityId);
|
|
271
|
+
}
|
|
272
|
+
for (const edge of edges) {
|
|
273
|
+
// Verifica campi obbligatori
|
|
274
|
+
if (!edge.id) {
|
|
275
|
+
errors.push(`Edge missing required field: id`);
|
|
276
|
+
}
|
|
277
|
+
if (!edge.sourceId) {
|
|
278
|
+
errors.push(`Edge missing required field: sourceId`);
|
|
279
|
+
}
|
|
280
|
+
if (!edge.targetId) {
|
|
281
|
+
errors.push(`Edge missing required field: targetId`);
|
|
282
|
+
}
|
|
283
|
+
if (!edge.label) {
|
|
284
|
+
errors.push(`Edge missing required field: label`);
|
|
285
|
+
}
|
|
286
|
+
// Verifica ID duplicati
|
|
287
|
+
if (edge.id) {
|
|
288
|
+
if (edgeIds.has(edge.id)) {
|
|
289
|
+
errors.push(`Duplicate edge ID: ${edge.id}`);
|
|
290
|
+
}
|
|
291
|
+
edgeIds.add(edge.id);
|
|
292
|
+
}
|
|
293
|
+
// Verifica riferimenti validi
|
|
294
|
+
if (edge.targetId && !entityIds.has(edge.targetId)) {
|
|
295
|
+
errors.push(`Edge references non-existent target entity: ${edge.targetId}`);
|
|
296
|
+
}
|
|
297
|
+
if (edge.sourceId && !entityIds.has(edge.sourceId)) {
|
|
298
|
+
errors.push(`Edge references non-existent source entity: ${edge.sourceId}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
valid: errors.length === 0,
|
|
303
|
+
errors,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Helper per validare una risposta completa di transform
|
|
308
|
+
*/
|
|
309
|
+
function validateTransformResult(result, inputEntityId) {
|
|
310
|
+
const entityValidation = validateEntities(result.entities);
|
|
311
|
+
const edgeValidation = validateEdges(result.edges, result.entities, inputEntityId);
|
|
312
|
+
return {
|
|
313
|
+
valid: entityValidation.valid && edgeValidation.valid,
|
|
314
|
+
errors: [...entityValidation.errors, ...edgeValidation.errors],
|
|
315
|
+
};
|
|
316
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { EntityType } from '../core/types';
|
|
2
|
+
/**
|
|
3
|
+
* Genera un ID deterministico per un'entità
|
|
4
|
+
* Formato: {type}-{hash-short}
|
|
5
|
+
*
|
|
6
|
+
* @param type - Tipo di entità
|
|
7
|
+
* @param value - Valore dell'entità
|
|
8
|
+
* @returns ID univoco e deterministico
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* generateEntityId('ip', '8.8.8.8')
|
|
13
|
+
* // => "ip-c909e98d"
|
|
14
|
+
*
|
|
15
|
+
* generateEntityId('location', 'Mountain View, CA')
|
|
16
|
+
* // => "location-a3f42bc1"
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateEntityId(type: EntityType, value: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Genera un ID deterministico per un edge
|
|
22
|
+
* Formato: edge-{hash-short}
|
|
23
|
+
*
|
|
24
|
+
* @param sourceId - ID dell'entità sorgente
|
|
25
|
+
* @param targetId - ID dell'entità target
|
|
26
|
+
* @param label - Label dell'edge (opzionale, per maggiore unicità)
|
|
27
|
+
* @returns ID univoco e deterministico
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* generateEdgeId('ip-c909e98d', 'location-a3f42bc1')
|
|
32
|
+
* // => "edge-4f8a2d1c"
|
|
33
|
+
*
|
|
34
|
+
* generateEdgeId('ip-c909e98d', 'org-5b3c1a2d', 'assigned by')
|
|
35
|
+
* // => "edge-7e9b3f4a"
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function generateEdgeId(sourceId: string, targetId: string, label?: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Genera un ID casuale con prefisso
|
|
41
|
+
* Utile per entità temporanee o quando non serve deterministicità
|
|
42
|
+
*
|
|
43
|
+
* @param prefix - Prefisso per l'ID (es: 'note', 'temp')
|
|
44
|
+
* @returns ID univoco random
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* generateRandomId('note')
|
|
49
|
+
* // => "note-1735123456789"
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function generateRandomId(prefix: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Normalizza un valore per la generazione di ID
|
|
55
|
+
* Rimuove spazi extra, converte a lowercase, rimuove caratteri speciali
|
|
56
|
+
*
|
|
57
|
+
* @param value - Valore da normalizzare
|
|
58
|
+
* @returns Valore normalizzato
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* normalizeValue(' Mountain View, CA ')
|
|
63
|
+
* // => "mountain-view-ca"
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function normalizeValue(value: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Valida un ID di entità
|
|
69
|
+
*
|
|
70
|
+
* @param id - ID da validare
|
|
71
|
+
* @returns true se l'ID è valido
|
|
72
|
+
*/
|
|
73
|
+
export declare function isValidEntityId(id: string): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Valida un ID di edge
|
|
76
|
+
*
|
|
77
|
+
* @param id - ID da validare
|
|
78
|
+
* @returns true se l'ID è valido
|
|
79
|
+
*/
|
|
80
|
+
export declare function isValidEdgeId(id: string): boolean;
|
|
81
|
+
//# sourceMappingURL=id-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-generator.d.ts","sourceRoot":"","sources":["../../src/utils/id-generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQxE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,MAAM,CAYR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEjD"}
|
|
@@ -0,0 +1,122 @@
|
|
|
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
|
+
exports.generateEntityId = generateEntityId;
|
|
7
|
+
exports.generateEdgeId = generateEdgeId;
|
|
8
|
+
exports.generateRandomId = generateRandomId;
|
|
9
|
+
exports.normalizeValue = normalizeValue;
|
|
10
|
+
exports.isValidEntityId = isValidEntityId;
|
|
11
|
+
exports.isValidEdgeId = isValidEdgeId;
|
|
12
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
13
|
+
/**
|
|
14
|
+
* Genera un ID deterministico per un'entità
|
|
15
|
+
* Formato: {type}-{hash-short}
|
|
16
|
+
*
|
|
17
|
+
* @param type - Tipo di entità
|
|
18
|
+
* @param value - Valore dell'entità
|
|
19
|
+
* @returns ID univoco e deterministico
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* generateEntityId('ip', '8.8.8.8')
|
|
24
|
+
* // => "ip-c909e98d"
|
|
25
|
+
*
|
|
26
|
+
* generateEntityId('location', 'Mountain View, CA')
|
|
27
|
+
* // => "location-a3f42bc1"
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
function generateEntityId(type, value) {
|
|
31
|
+
const hash = crypto_1.default
|
|
32
|
+
.createHash('md5')
|
|
33
|
+
.update(value.toLowerCase().trim())
|
|
34
|
+
.digest('hex')
|
|
35
|
+
.substring(0, 8);
|
|
36
|
+
return `${type}-${hash}`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Genera un ID deterministico per un edge
|
|
40
|
+
* Formato: edge-{hash-short}
|
|
41
|
+
*
|
|
42
|
+
* @param sourceId - ID dell'entità sorgente
|
|
43
|
+
* @param targetId - ID dell'entità target
|
|
44
|
+
* @param label - Label dell'edge (opzionale, per maggiore unicità)
|
|
45
|
+
* @returns ID univoco e deterministico
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* generateEdgeId('ip-c909e98d', 'location-a3f42bc1')
|
|
50
|
+
* // => "edge-4f8a2d1c"
|
|
51
|
+
*
|
|
52
|
+
* generateEdgeId('ip-c909e98d', 'org-5b3c1a2d', 'assigned by')
|
|
53
|
+
* // => "edge-7e9b3f4a"
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
function generateEdgeId(sourceId, targetId, label) {
|
|
57
|
+
const content = label
|
|
58
|
+
? `${sourceId}-${targetId}-${label}`
|
|
59
|
+
: `${sourceId}-${targetId}`;
|
|
60
|
+
const hash = crypto_1.default
|
|
61
|
+
.createHash('md5')
|
|
62
|
+
.update(content.toLowerCase().trim())
|
|
63
|
+
.digest('hex')
|
|
64
|
+
.substring(0, 8);
|
|
65
|
+
return `edge-${hash}`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Genera un ID casuale con prefisso
|
|
69
|
+
* Utile per entità temporanee o quando non serve deterministicità
|
|
70
|
+
*
|
|
71
|
+
* @param prefix - Prefisso per l'ID (es: 'note', 'temp')
|
|
72
|
+
* @returns ID univoco random
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* generateRandomId('note')
|
|
77
|
+
* // => "note-1735123456789"
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
function generateRandomId(prefix) {
|
|
81
|
+
return `${prefix}-${Date.now()}-${crypto_1.default.randomBytes(4).toString('hex')}`;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Normalizza un valore per la generazione di ID
|
|
85
|
+
* Rimuove spazi extra, converte a lowercase, rimuove caratteri speciali
|
|
86
|
+
*
|
|
87
|
+
* @param value - Valore da normalizzare
|
|
88
|
+
* @returns Valore normalizzato
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* normalizeValue(' Mountain View, CA ')
|
|
93
|
+
* // => "mountain-view-ca"
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
function normalizeValue(value) {
|
|
97
|
+
return value
|
|
98
|
+
.toLowerCase()
|
|
99
|
+
.trim()
|
|
100
|
+
.replace(/\s+/g, '-')
|
|
101
|
+
.replace(/[^a-z0-9-]/g, '')
|
|
102
|
+
.replace(/-+/g, '-')
|
|
103
|
+
.replace(/^-|-$/g, '');
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Valida un ID di entità
|
|
107
|
+
*
|
|
108
|
+
* @param id - ID da validare
|
|
109
|
+
* @returns true se l'ID è valido
|
|
110
|
+
*/
|
|
111
|
+
function isValidEntityId(id) {
|
|
112
|
+
return id.length > 0 && id.trim() === id;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Valida un ID di edge
|
|
116
|
+
*
|
|
117
|
+
* @param id - ID da validare
|
|
118
|
+
* @returns true se l'ID è valido
|
|
119
|
+
*/
|
|
120
|
+
function isValidEdgeId(id) {
|
|
121
|
+
return id.length > 0 && id.trim() === id;
|
|
122
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { OSINTEntity, OSINTEdge, TransformResult, TransformInput } from '../core/types';
|
|
2
|
+
/**
|
|
3
|
+
* Builder per costruire facilmente un TransformResult
|
|
4
|
+
* Gestisce automaticamente gli edge dall'entità di input alle nuove entità
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const result = new ResultBuilder(input)
|
|
9
|
+
* .addEntity(createIP('8.8.8.8'), 'resolves to')
|
|
10
|
+
* .addEntity(createLocation('Mountain View, CA'), 'located in')
|
|
11
|
+
* .setMessage('Found IP information')
|
|
12
|
+
* .build();
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare class ResultBuilder {
|
|
16
|
+
private entities;
|
|
17
|
+
private edges;
|
|
18
|
+
private message?;
|
|
19
|
+
private metadata?;
|
|
20
|
+
private inputEntityId;
|
|
21
|
+
constructor(input: TransformInput);
|
|
22
|
+
/**
|
|
23
|
+
* Aggiungi un'entità con edge automatico dall'input
|
|
24
|
+
*
|
|
25
|
+
* @param entity - Entità da aggiungere
|
|
26
|
+
* @param edgeLabel - Label dell'edge (opzionale)
|
|
27
|
+
* @param edgeOptions - Opzioni per l'edge
|
|
28
|
+
*/
|
|
29
|
+
addEntity(entity: OSINTEntity, edgeLabel?: string, edgeOptions?: {
|
|
30
|
+
relationship?: string;
|
|
31
|
+
metadata?: Record<string, any>;
|
|
32
|
+
}): this;
|
|
33
|
+
/**
|
|
34
|
+
* Aggiungi multiple entità con lo stesso tipo di edge
|
|
35
|
+
*
|
|
36
|
+
* @param entities - Array di entità da aggiungere
|
|
37
|
+
* @param edgeLabel - Label dell'edge (opzionale)
|
|
38
|
+
* @param edgeOptions - Opzioni per l'edge
|
|
39
|
+
*/
|
|
40
|
+
addEntities(entities: OSINTEntity[], edgeLabel?: string, edgeOptions?: {
|
|
41
|
+
relationship?: string;
|
|
42
|
+
metadata?: Record<string, any>;
|
|
43
|
+
}): this;
|
|
44
|
+
/**
|
|
45
|
+
* Aggiungi un'entità senza edge automatico
|
|
46
|
+
*/
|
|
47
|
+
addEntityOnly(entity: OSINTEntity): this;
|
|
48
|
+
/**
|
|
49
|
+
* Aggiungi un edge manualmente
|
|
50
|
+
*/
|
|
51
|
+
addEdge(edge: OSINTEdge): this;
|
|
52
|
+
/**
|
|
53
|
+
* Aggiungi multiple edges
|
|
54
|
+
*/
|
|
55
|
+
addEdges(edges: OSINTEdge[]): this;
|
|
56
|
+
/**
|
|
57
|
+
* Imposta il messaggio di successo
|
|
58
|
+
*/
|
|
59
|
+
setMessage(message: string): this;
|
|
60
|
+
/**
|
|
61
|
+
* Imposta metadata addizionali
|
|
62
|
+
*/
|
|
63
|
+
setMetadata(metadata: Record<string, any>): this;
|
|
64
|
+
/**
|
|
65
|
+
* Aggiungi metadata
|
|
66
|
+
*/
|
|
67
|
+
addMetadata(key: string, value: any): this;
|
|
68
|
+
/**
|
|
69
|
+
* Costruisci il risultato finale
|
|
70
|
+
*/
|
|
71
|
+
build(): TransformResult;
|
|
72
|
+
/**
|
|
73
|
+
* Ottieni il numero di entità aggiunte
|
|
74
|
+
*/
|
|
75
|
+
getEntityCount(): number;
|
|
76
|
+
/**
|
|
77
|
+
* Ottieni il numero di edge aggiunti
|
|
78
|
+
*/
|
|
79
|
+
getEdgeCount(): number;
|
|
80
|
+
/**
|
|
81
|
+
* Verifica se ci sono risultati
|
|
82
|
+
*/
|
|
83
|
+
hasResults(): boolean;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Helper veloce per creare un risultato vuoto (no results)
|
|
87
|
+
*/
|
|
88
|
+
export declare function emptyResult(message?: string): TransformResult;
|
|
89
|
+
/**
|
|
90
|
+
* Helper veloce per creare un risultato di errore
|
|
91
|
+
*/
|
|
92
|
+
export declare function errorResult(error: string | Error): TransformResult;
|
|
93
|
+
/**
|
|
94
|
+
* Helper per creare un risultato con una singola entità
|
|
95
|
+
*/
|
|
96
|
+
export declare function singleEntityResult(inputEntityId: string, entity: OSINTEntity, edgeLabel: string, options?: {
|
|
97
|
+
relationship?: string;
|
|
98
|
+
message?: string;
|
|
99
|
+
metadata?: Record<string, any>;
|
|
100
|
+
}): TransformResult;
|
|
101
|
+
/**
|
|
102
|
+
* Helper per creare un risultato con multiple entità dello stesso tipo
|
|
103
|
+
*/
|
|
104
|
+
export declare function multiEntityResult(inputEntityId: string, entities: OSINTEntity[], edgeLabel: string, options?: {
|
|
105
|
+
relationship?: string;
|
|
106
|
+
message?: string;
|
|
107
|
+
metadata?: Record<string, any>;
|
|
108
|
+
}): TransformResult;
|
|
109
|
+
//# sourceMappingURL=result-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-builder.d.ts","sourceRoot":"","sources":["../../src/utils/result-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG7F;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,CAAsB;IACvC,OAAO,CAAC,aAAa,CAAS;gBAElB,KAAK,EAAE,cAAc;IAIjC;;;;;;OAMG;IACH,SAAS,CACP,MAAM,EAAE,WAAW,EACnB,SAAS,CAAC,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE;QACZ,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAChC,GACA,IAAI;IAiBP;;;;;;OAMG;IACH,WAAW,CACT,QAAQ,EAAE,WAAW,EAAE,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE;QACZ,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAChC,GACA,IAAI;IAOP;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAKxC;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAK9B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI;IAKlC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKjC;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAKhD;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAQ1C;;OAEG;IACH,KAAK,IAAI,eAAe;IAUxB;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,UAAU,IAAI,OAAO;CAGtB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe,CAO7D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,eAAe,CAOlE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IACR,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC,GACA,eAAe,CAYjB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,WAAW,EAAE,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IACR,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC,GACA,eAAe,CAcjB"}
|