@relazio/plugin-sdk 0.1.0 → 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 +206 -200
- 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 +5 -4
package/docs/examples.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Examples Documentation
|
|
2
|
+
|
|
3
|
+
This document provides an overview of the example plugins included in the SDK.
|
|
4
|
+
|
|
5
|
+
## Primary Examples
|
|
6
|
+
|
|
7
|
+
### 1. simple-sync-example - Synchronous Transform
|
|
8
|
+
|
|
9
|
+
**Location**: `examples/simple-sync-example/`
|
|
10
|
+
|
|
11
|
+
A clear, well-documented example of a synchronous transform that demonstrates core SDK features.
|
|
12
|
+
|
|
13
|
+
**Features**:
|
|
14
|
+
- Synchronous transform (response < 30 seconds)
|
|
15
|
+
- Creates multiple entity types (IP, Location, Organization, Note)
|
|
16
|
+
- Uses `createEntity()` for scalable entity creation
|
|
17
|
+
- Demonstrates `ResultBuilder` with automatic edge creation
|
|
18
|
+
- Includes Markdown-formatted notes
|
|
19
|
+
- Rich metadata structure
|
|
20
|
+
|
|
21
|
+
**Running**:
|
|
22
|
+
```bash
|
|
23
|
+
cd examples/simple-sync-example
|
|
24
|
+
npm install
|
|
25
|
+
npm start
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Testing**:
|
|
29
|
+
```bash
|
|
30
|
+
curl -X POST http://localhost:3000/transforms/analyze-domain \
|
|
31
|
+
-H "Content-Type: application/json" \
|
|
32
|
+
-d '{
|
|
33
|
+
"transformId": "analyze-domain",
|
|
34
|
+
"input": {
|
|
35
|
+
"entity": {
|
|
36
|
+
"id": "test-1",
|
|
37
|
+
"type": "domain",
|
|
38
|
+
"value": "google.com"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"callbackUrl": "https://webhook.site/..."
|
|
42
|
+
}'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 2. async-subdomain-scanner - Asynchronous Transform
|
|
46
|
+
|
|
47
|
+
**Location**: `examples/async-subdomain-scanner/`
|
|
48
|
+
|
|
49
|
+
Demonstrates asynchronous transform handling with progress tracking and webhook callbacks.
|
|
50
|
+
|
|
51
|
+
**Features**:
|
|
52
|
+
- Asynchronous transform (long-running operations)
|
|
53
|
+
- Real-time progress tracking (0% to 100%)
|
|
54
|
+
- Automatic webhook callbacks on completion
|
|
55
|
+
- Multiple result handling
|
|
56
|
+
- Scalable entity creation
|
|
57
|
+
- Summary notes in Markdown
|
|
58
|
+
|
|
59
|
+
**Running**:
|
|
60
|
+
```bash
|
|
61
|
+
cd examples/async-subdomain-scanner
|
|
62
|
+
npm install
|
|
63
|
+
npm start
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Testing**:
|
|
67
|
+
```bash
|
|
68
|
+
curl -X POST http://localhost:3002/transforms/scan-subdomains \
|
|
69
|
+
-H "Content-Type: application/json" \
|
|
70
|
+
-d '{
|
|
71
|
+
"transformId": "scan-subdomains",
|
|
72
|
+
"input": {
|
|
73
|
+
"entity": {
|
|
74
|
+
"id": "test-1",
|
|
75
|
+
"type": "domain",
|
|
76
|
+
"value": "example.com"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"callbackUrl": "https://webhook.site/your-unique-url"
|
|
80
|
+
}'
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Additional Examples
|
|
84
|
+
|
|
85
|
+
### 3. email-parser - Basic Email Parsing
|
|
86
|
+
|
|
87
|
+
**Location**: `examples/email-parser/`
|
|
88
|
+
|
|
89
|
+
Simple plugin that extracts domain from email addresses.
|
|
90
|
+
|
|
91
|
+
**Features**:
|
|
92
|
+
- Basic synchronous transform
|
|
93
|
+
- Simple entity creation
|
|
94
|
+
- Single result handling
|
|
95
|
+
|
|
96
|
+
**Running**:
|
|
97
|
+
```bash
|
|
98
|
+
cd examples/email-parser
|
|
99
|
+
npm install
|
|
100
|
+
npm start
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 4. dns-toolkit - Multiple Transforms
|
|
104
|
+
|
|
105
|
+
**Location**: `examples/dns-toolkit/`
|
|
106
|
+
|
|
107
|
+
Plugin with multiple synchronous transforms for DNS analysis (A, MX, NS records).
|
|
108
|
+
|
|
109
|
+
**Features**:
|
|
110
|
+
- Multiple transforms in one plugin
|
|
111
|
+
- DNS resolution examples
|
|
112
|
+
- Array handling with `addEntities()`
|
|
113
|
+
|
|
114
|
+
**Running**:
|
|
115
|
+
```bash
|
|
116
|
+
cd examples/dns-toolkit
|
|
117
|
+
npm install
|
|
118
|
+
npm start
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 5. ip-lookup-complete - Comprehensive Example
|
|
122
|
+
|
|
123
|
+
**Location**: `examples/ip-lookup-complete/`
|
|
124
|
+
|
|
125
|
+
Advanced example showing all SDK capabilities.
|
|
126
|
+
|
|
127
|
+
**Features**:
|
|
128
|
+
- Complex entity creation
|
|
129
|
+
- EntityBuilder usage
|
|
130
|
+
- Advanced metadata structures
|
|
131
|
+
- Optional configuration support
|
|
132
|
+
|
|
133
|
+
**Running**:
|
|
134
|
+
```bash
|
|
135
|
+
cd examples/ip-lookup-complete
|
|
136
|
+
npm install
|
|
137
|
+
npm start
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 6. multi-tenant-plugin - Multi-Tenancy Support
|
|
141
|
+
|
|
142
|
+
**Location**: `examples/multi-tenant-plugin/`
|
|
143
|
+
|
|
144
|
+
Demonstrates multi-tenant architecture with organization isolation.
|
|
145
|
+
|
|
146
|
+
**Features**:
|
|
147
|
+
- Multi-tenant support
|
|
148
|
+
- Registration/unregistration endpoints
|
|
149
|
+
- Organization isolation
|
|
150
|
+
- Per-organization webhook secrets
|
|
151
|
+
|
|
152
|
+
**Running**:
|
|
153
|
+
```bash
|
|
154
|
+
cd examples/multi-tenant-plugin
|
|
155
|
+
npm install
|
|
156
|
+
npm start
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Example Selection Guide
|
|
160
|
+
|
|
161
|
+
| Use Case | Example |
|
|
162
|
+
|----------|---------|
|
|
163
|
+
| Getting started with sync transforms | `simple-sync-example` |
|
|
164
|
+
| Implementing long-running operations | `async-subdomain-scanner` |
|
|
165
|
+
| Understanding DNS patterns | `dns-toolkit` |
|
|
166
|
+
| Basic email parsing | `email-parser` |
|
|
167
|
+
| Advanced features exploration | `ip-lookup-complete` |
|
|
168
|
+
| Multi-organization support | `multi-tenant-plugin` |
|
|
169
|
+
|
|
170
|
+
## Common Patterns
|
|
171
|
+
|
|
172
|
+
### Creating Entities
|
|
173
|
+
|
|
174
|
+
All examples use the scalable `createEntity()` approach:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
const entity = createEntity('type', 'value', {
|
|
178
|
+
metadata: { /* ... */ }
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Building Results
|
|
183
|
+
|
|
184
|
+
Examples demonstrate `ResultBuilder` for automatic edge creation:
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
return new ResultBuilder(input)
|
|
188
|
+
.addEntity(entity, 'edge label')
|
|
189
|
+
.setMessage('Success')
|
|
190
|
+
.build();
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Progress Tracking (Async)
|
|
194
|
+
|
|
195
|
+
Async examples show progress updates:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
await job.updateProgress(50, 'Processing...');
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Development Workflow
|
|
202
|
+
|
|
203
|
+
### Standard Development Setup
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# In SDK root
|
|
207
|
+
npm run build
|
|
208
|
+
|
|
209
|
+
# In any example
|
|
210
|
+
cd examples/example-name
|
|
211
|
+
npm install
|
|
212
|
+
npm start
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Testing Workflow
|
|
216
|
+
|
|
217
|
+
1. Start the example plugin
|
|
218
|
+
2. Use curl or a tool like Postman to send test requests
|
|
219
|
+
3. For async examples, use webhook.site to receive callbacks
|
|
220
|
+
4. Monitor console output for logs and errors
|
|
221
|
+
|
|
222
|
+
## Creating Custom Plugins
|
|
223
|
+
|
|
224
|
+
Use the examples as templates for your own plugins:
|
|
225
|
+
|
|
226
|
+
1. Copy an example directory
|
|
227
|
+
2. Modify `package.json` (id, name, description)
|
|
228
|
+
3. Implement your transform logic
|
|
229
|
+
4. Update dependencies as needed
|
|
230
|
+
5. Test thoroughly before deployment
|
|
231
|
+
|
|
232
|
+
## Additional Resources
|
|
233
|
+
|
|
234
|
+
- [Quick Start Guide](./quick-start.md)
|
|
235
|
+
- [Builders Guide](./builders-guide.md)
|
|
236
|
+
- [Response Format Specification](./response-format.md)
|
|
237
|
+
- [Main README](../README.md)
|
|
238
|
+
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Quick Start Guide
|
|
2
|
+
|
|
3
|
+
This guide demonstrates how to create Relazio plugins using the SDK.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @relazio/plugin-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Core Concepts
|
|
12
|
+
|
|
13
|
+
The SDK provides two types of transforms:
|
|
14
|
+
|
|
15
|
+
- **Synchronous Transforms**: Return results immediately (< 30 seconds)
|
|
16
|
+
- **Asynchronous Transforms**: Handle long-running operations (minutes to hours) with progress tracking
|
|
17
|
+
|
|
18
|
+
## Example 1: Synchronous Transform
|
|
19
|
+
|
|
20
|
+
Synchronous transforms process requests and return results immediately.
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { RelazioPlugin, createEntity, ResultBuilder } from '@relazio/plugin-sdk';
|
|
24
|
+
|
|
25
|
+
const plugin = new RelazioPlugin({
|
|
26
|
+
id: 'domain-analyzer',
|
|
27
|
+
name: 'Domain Analyzer',
|
|
28
|
+
version: '1.0.0',
|
|
29
|
+
author: 'Your Name',
|
|
30
|
+
description: 'Analyzes domains and returns related entities',
|
|
31
|
+
category: 'network',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
plugin.transform({
|
|
35
|
+
id: 'analyze-domain',
|
|
36
|
+
name: 'Analyze Domain',
|
|
37
|
+
inputType: 'domain',
|
|
38
|
+
outputTypes: ['ip', 'location', 'organization'],
|
|
39
|
+
|
|
40
|
+
handler: async (input) => {
|
|
41
|
+
const domain = input.entity.value;
|
|
42
|
+
|
|
43
|
+
// Your analysis logic
|
|
44
|
+
const ip = await resolveDNS(domain);
|
|
45
|
+
const location = await getGeoLocation(ip);
|
|
46
|
+
const organization = await getISPInfo(ip);
|
|
47
|
+
|
|
48
|
+
// Create entities using createEntity()
|
|
49
|
+
const ipEntity = createEntity('ip', ip, {
|
|
50
|
+
metadata: { resolvedFrom: domain }
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const locationEntity = createEntity('location', location.city, {
|
|
54
|
+
metadata: {
|
|
55
|
+
latitude: location.lat,
|
|
56
|
+
longitude: location.lon,
|
|
57
|
+
country: location.country
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const orgEntity = createEntity('organization', organization.name, {
|
|
62
|
+
metadata: { asn: organization.asn }
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Build result with automatic edge creation
|
|
66
|
+
return new ResultBuilder(input)
|
|
67
|
+
.addEntity(ipEntity, 'resolves to')
|
|
68
|
+
.addEntity(locationEntity, 'located in')
|
|
69
|
+
.addEntity(orgEntity, 'hosted by')
|
|
70
|
+
.setMessage('Analysis completed')
|
|
71
|
+
.build();
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
await plugin.start({ port: 3000 });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Use Cases**: API calls, DNS lookups, data parsing, quick analysis
|
|
79
|
+
|
|
80
|
+
**Complete Example**: See `examples/simple-sync-example/`
|
|
81
|
+
|
|
82
|
+
## Example 2: Asynchronous Transform
|
|
83
|
+
|
|
84
|
+
Asynchronous transforms handle long-running operations with progress tracking and webhook callbacks.
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { RelazioPlugin, createEntity, ResultBuilder } from '@relazio/plugin-sdk';
|
|
88
|
+
|
|
89
|
+
const plugin = new RelazioPlugin({
|
|
90
|
+
id: 'subdomain-scanner',
|
|
91
|
+
name: 'Subdomain Scanner',
|
|
92
|
+
version: '1.0.0',
|
|
93
|
+
author: 'Your Name',
|
|
94
|
+
description: 'Scans for subdomains',
|
|
95
|
+
category: 'network',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Required for async transforms
|
|
99
|
+
plugin.setWebhookSecret(process.env.WEBHOOK_SECRET || 'dev-secret');
|
|
100
|
+
|
|
101
|
+
plugin.asyncTransform({
|
|
102
|
+
id: 'scan-subdomains',
|
|
103
|
+
name: 'Scan Subdomains',
|
|
104
|
+
inputType: 'domain',
|
|
105
|
+
outputTypes: ['domain'],
|
|
106
|
+
|
|
107
|
+
handler: async (input, config, job) => {
|
|
108
|
+
const domain = input.entity.value;
|
|
109
|
+
|
|
110
|
+
// Update progress during execution
|
|
111
|
+
await job.updateProgress(0, 'Starting scan');
|
|
112
|
+
|
|
113
|
+
const results = [];
|
|
114
|
+
for (let i = 0; i < totalScans; i++) {
|
|
115
|
+
const subdomain = await scanForSubdomain(domain, i);
|
|
116
|
+
if (subdomain) results.push(subdomain);
|
|
117
|
+
|
|
118
|
+
// Update progress
|
|
119
|
+
const progress = ((i + 1) / totalScans) * 100;
|
|
120
|
+
await job.updateProgress(progress, `Found ${results.length} subdomains`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Create entities for results
|
|
124
|
+
const subdomainEntities = results.map(sub =>
|
|
125
|
+
createEntity('domain', sub, {
|
|
126
|
+
metadata: { discoveredFrom: domain }
|
|
127
|
+
})
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// Build and return result
|
|
131
|
+
return new ResultBuilder(input)
|
|
132
|
+
.addEntities(subdomainEntities, 'subdomain')
|
|
133
|
+
.setMessage(`Scan completed: ${results.length} subdomains found`)
|
|
134
|
+
.build();
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
await plugin.start({ port: 3000 });
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Use Cases**: Port scanning, subdomain enumeration, batch processing, crawling
|
|
142
|
+
|
|
143
|
+
**Complete Example**: See `examples/async-subdomain-scanner/`
|
|
144
|
+
|
|
145
|
+
## Core SDK Functions
|
|
146
|
+
|
|
147
|
+
### createEntity()
|
|
148
|
+
|
|
149
|
+
Creates an entity with automatic ID generation. Works with any entity type.
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
createEntity(type: EntityType, value: string, options?: {
|
|
153
|
+
id?: string;
|
|
154
|
+
label?: string;
|
|
155
|
+
metadata?: Record<string, any>;
|
|
156
|
+
})
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Examples**:
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
createEntity('ip', '8.8.8.8')
|
|
163
|
+
createEntity('domain', 'example.com')
|
|
164
|
+
createEntity('location', 'New York, NY', {
|
|
165
|
+
metadata: { latitude: 40.7, longitude: -74.0 }
|
|
166
|
+
})
|
|
167
|
+
createEntity('note', 'Analysis Results', {
|
|
168
|
+
label: '## Results\n\nAnalysis completed successfully',
|
|
169
|
+
metadata: { format: 'markdown' }
|
|
170
|
+
})
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### ResultBuilder
|
|
174
|
+
|
|
175
|
+
Constructs transform results with automatic edge generation.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
const result = new ResultBuilder(input);
|
|
179
|
+
|
|
180
|
+
// Add entity with automatic edge
|
|
181
|
+
result.addEntity(entity, 'edge label', {
|
|
182
|
+
relationship: 'relationship_type'
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Add multiple entities with the same edge type
|
|
186
|
+
result.addEntities(entities, 'edge label');
|
|
187
|
+
|
|
188
|
+
// Add message and metadata
|
|
189
|
+
result
|
|
190
|
+
.setMessage('Operation completed')
|
|
191
|
+
.addMetadata('executionTime', Date.now());
|
|
192
|
+
|
|
193
|
+
// Build final result
|
|
194
|
+
return result.build();
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### createEdge()
|
|
198
|
+
|
|
199
|
+
Creates edges manually when needed.
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
createEdge(sourceId, targetId, label, options?)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Example**:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
createEdge(
|
|
209
|
+
'source-entity-id',
|
|
210
|
+
'target-entity-id',
|
|
211
|
+
'related to',
|
|
212
|
+
{ relationship: 'custom_relationship' }
|
|
213
|
+
)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Supported Entity Types
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
'email' | 'domain' | 'ip' | 'person' | 'username' | 'phone'
|
|
220
|
+
| 'organization' | 'hash' | 'credential' | 'social' | 'document'
|
|
221
|
+
| 'note' | 'image' | 'video' | 'location' | 'wallet'
|
|
222
|
+
| 'transaction' | 'exchange' | 'url' | 'maps' | 'custom'
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
The SDK is type-agnostic and works with any entity type, including future additions.
|
|
226
|
+
|
|
227
|
+
## Testing Your Plugin
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
curl -X POST http://localhost:3000/transforms/your-transform-id \
|
|
231
|
+
-H "Content-Type: application/json" \
|
|
232
|
+
-d '{
|
|
233
|
+
"transformId": "your-transform-id",
|
|
234
|
+
"input": {
|
|
235
|
+
"entity": {
|
|
236
|
+
"id": "test-1",
|
|
237
|
+
"type": "domain",
|
|
238
|
+
"value": "example.com"
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
"callbackUrl": "https://your-webhook-url.com"
|
|
242
|
+
}'
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Best Practices
|
|
246
|
+
|
|
247
|
+
### Synchronous Transforms
|
|
248
|
+
|
|
249
|
+
- Keep execution time under 30 seconds
|
|
250
|
+
- Use for quick operations (DNS lookups, API calls, parsing)
|
|
251
|
+
- Return results directly in the response
|
|
252
|
+
|
|
253
|
+
### Asynchronous Transforms
|
|
254
|
+
|
|
255
|
+
- Use for operations taking longer than 30 seconds
|
|
256
|
+
- Always set a webhook secret using `setWebhookSecret()`
|
|
257
|
+
- Update progress regularly using `job.updateProgress()`
|
|
258
|
+
- Handle errors gracefully
|
|
259
|
+
|
|
260
|
+
### Entity Creation
|
|
261
|
+
|
|
262
|
+
- Use `createEntity()` for all entity creation (scalable approach)
|
|
263
|
+
- Include meaningful metadata
|
|
264
|
+
- Use descriptive labels for better visualization
|
|
265
|
+
- Leverage markdown format for note entities
|
|
266
|
+
|
|
267
|
+
### Edge Creation
|
|
268
|
+
|
|
269
|
+
- Use `ResultBuilder.addEntity()` for automatic edge creation
|
|
270
|
+
- Provide clear, descriptive edge labels
|
|
271
|
+
- Use `relationship` field to categorize edge types
|
|
272
|
+
|
|
273
|
+
## Next Steps
|
|
274
|
+
|
|
275
|
+
1. **Try the examples**: `cd examples/simple-sync-example && npm install && npm start`
|
|
276
|
+
2. **Read the builders guide**: [builders-guide.md](./builders-guide.md)
|
|
277
|
+
3. **Understand the response format**: [response-format.md](./response-format.md)
|
|
278
|
+
4. **Explore examples**: [examples.md](./examples.md)
|
|
279
|
+
|
|
280
|
+
## Additional Resources
|
|
281
|
+
|
|
282
|
+
- [Main README](../README.md)
|
|
283
|
+
- [Builders Guide](./builders-guide.md)
|
|
284
|
+
- [Response Format Specification](./response-format.md)
|
|
285
|
+
- [Examples Documentation](./examples.md)
|
|
286
|
+
- [Changelog](../CHANGELOG.md)
|
|
287
|
+
|