0
# Component Context
1
2
Runtime context types available during component execution, including access to props, services, and authentication.
3
4
## Capabilities
5
6
### Component This Context
7
8
The main runtime context available in component methods with access to props, services, and special methods.
9
10
```typescript { .api }
11
/**
12
* Runtime context object available in component methods (this)
13
*/
14
interface ComponentThis {
15
/** Dynamic access to all component props */
16
[propName: string]: any;
17
18
/** Method for emitting events */
19
$emit: EmitMethod;
20
21
/** Authentication context when using app integrations (optional) */
22
$auth?: AuthContext;
23
24
/** Database service when using $.service.db (optional) */
25
db?: DatabaseService;
26
27
/** HTTP interface when using $.interface.http (optional) */
28
http?: HttpEndpoint & { respond: HttpRespondMethod };
29
30
/** Timer interface when using $.interface.timer (optional) */
31
timer?: { type: "$.interface.timer" };
32
}
33
```
34
35
**Usage Examples:**
36
37
```typescript
38
import { PipedreamComponent, ComponentThis } from "@pipedream/types";
39
40
const contextAwareComponent: PipedreamComponent = {
41
name: "Context Aware Component",
42
version: "1.0.0",
43
props: {
44
apiKey: {
45
type: "string",
46
label: "API Key",
47
secret: true
48
},
49
maxResults: {
50
type: "integer",
51
label: "Max Results",
52
default: 10
53
},
54
db: "$.service.db"
55
},
56
async run(event) {
57
// Access props directly
58
console.log("API Key configured:", !!this.apiKey);
59
console.log("Max results:", this.maxResults);
60
61
// Use database service
62
const lastRun = this.db.get("lastRunTime") || 0;
63
this.db.set("lastRunTime", Date.now());
64
65
// Emit events
66
this.$emit({
67
message: "Component executed",
68
lastRun,
69
currentRun: Date.now()
70
});
71
}
72
};
73
```
74
75
### Authentication Context
76
77
Authentication information available when using app integrations.
78
79
```typescript { .api }
80
/**
81
* Authentication context for app integrations
82
*/
83
interface AuthContext {
84
/** OAuth 2.0 access token (optional) */
85
oauth_access_token?: string;
86
87
/** OAuth 2.0 refresh token (optional) */
88
oauth_refresh_token?: string;
89
90
/** API key for services that use API key authentication (optional) */
91
api_key?: string;
92
93
/** Discord bot token (optional) */
94
bot_token?: string;
95
96
/** Twilio Account SID (optional) */
97
Sid?: string;
98
99
/** Twilio Auth Token (optional) */
100
Secret?: string;
101
102
/** Twilio Account SID (optional) */
103
AccountSid?: string;
104
105
/** Salesforce instance identifier (optional) */
106
yourinstance?: string;
107
108
/** Salesforce instance URL (optional) */
109
instance_url?: string;
110
111
/** Additional service-specific authentication fields */
112
[key: string]: any;
113
}
114
```
115
116
**Usage Examples:**
117
118
```typescript
119
// OAuth-based component
120
const oauthComponent: PipedreamComponent = {
121
name: "OAuth Component",
122
version: "1.0.0",
123
props: {
124
github: {
125
type: "app",
126
app: "github"
127
}
128
},
129
async run(event) {
130
// Access OAuth token from app authentication
131
const token = this.github.$auth.oauth_access_token;
132
133
const response = await fetch("https://api.github.com/user/repos", {
134
headers: {
135
"Authorization": `Bearer ${token}`,
136
"Accept": "application/vnd.github.v3+json"
137
}
138
});
139
140
const repos = await response.json();
141
142
repos.forEach(repo => {
143
this.$emit(repo, {
144
id: repo.id,
145
summary: `Repository: ${repo.full_name}`
146
});
147
});
148
}
149
};
150
151
// API key-based component
152
const apiKeyComponent: PipedreamComponent = {
153
name: "API Key Component",
154
version: "1.0.0",
155
props: {
156
openai: {
157
type: "app",
158
app: "openai"
159
},
160
prompt: {
161
type: "string",
162
label: "Prompt",
163
description: "Text prompt for OpenAI"
164
}
165
},
166
async run(event) {
167
const apiKey = this.openai.$auth.api_key;
168
169
const response = await fetch("https://api.openai.com/v1/completions", {
170
method: "POST",
171
headers: {
172
"Authorization": `Bearer ${apiKey}`,
173
"Content-Type": "application/json"
174
},
175
body: JSON.stringify({
176
model: "text-davinci-003",
177
prompt: this.prompt,
178
max_tokens: 100
179
})
180
});
181
182
const completion = await response.json();
183
184
this.$emit(completion, {
185
id: completion.id,
186
summary: "OpenAI completion generated"
187
});
188
}
189
};
190
```
191
192
### Database Service Context
193
194
Database service interface available when using `$.service.db`.
195
196
```typescript { .api }
197
/**
198
* Database service for persistent storage
199
*/
200
interface DatabaseService {
201
/** Service type identifier */
202
type: "$.service.db";
203
204
/**
205
* Retrieve a value by key
206
* @param key - The key to retrieve
207
* @returns The stored value or undefined if not found
208
*/
209
get: (key: string) => any;
210
211
/**
212
* Store a value by key
213
* @param key - The key to store under
214
* @param value - The value to store
215
*/
216
set: (key: string, value: any) => void;
217
}
218
```
219
220
**Usage Examples:**
221
222
```typescript
223
// State management with database
224
const statefulComponent: PipedreamComponent = {
225
name: "Stateful Component",
226
version: "1.0.0",
227
props: {
228
timer: {
229
type: "$.interface.timer",
230
default: { intervalSeconds: 300 }
231
},
232
db: "$.service.db"
233
},
234
async run(event) {
235
// Get previous state
236
const runCount = this.db.get("runCount") || 0;
237
const lastItems = this.db.get("lastItems") || [];
238
239
// Fetch new data
240
const newItems = await fetchNewItems();
241
242
// Update state
243
this.db.set("runCount", runCount + 1);
244
this.db.set("lastItems", newItems);
245
this.db.set("lastRunTime", Date.now());
246
247
// Use state in processing
248
console.log(`Run #${runCount + 1}, found ${newItems.length} items`);
249
250
// Emit only new items (not in lastItems)
251
const actuallyNew = newItems.filter(item =>
252
!lastItems.some(prev => prev.id === item.id)
253
);
254
255
actuallyNew.forEach(item => {
256
this.$emit(item, {
257
id: item.id,
258
summary: `New item: ${item.name}`,
259
ts: Date.now()
260
});
261
});
262
}
263
};
264
265
// Pagination state management
266
const paginatedComponent: PipedreamComponent = {
267
name: "Paginated Component",
268
version: "1.0.0",
269
props: {
270
timer: {
271
type: "$.interface.timer",
272
default: { intervalSeconds: 600 }
273
},
274
db: "$.service.db"
275
},
276
async run(event) {
277
let nextPageToken = this.db.get("nextPageToken");
278
let hasMorePages = true;
279
280
while (hasMorePages) {
281
const response = await fetchPage(nextPageToken);
282
283
// Process page items
284
response.items.forEach(item => {
285
this.$emit(item, {
286
id: item.id,
287
summary: `Item: ${item.name}`
288
});
289
});
290
291
// Update pagination state
292
nextPageToken = response.nextPageToken;
293
hasMorePages = !!nextPageToken;
294
295
// Prevent infinite loops
296
if (response.items.length === 0) {
297
hasMorePages = false;
298
}
299
}
300
301
// Store next page token for next run
302
this.db.set("nextPageToken", nextPageToken);
303
}
304
};
305
```
306
307
### HTTP Context
308
309
HTTP-specific context available when using `$.interface.http`.
310
311
```typescript { .api }
312
/**
313
* HTTP endpoint information
314
*/
315
interface HttpEndpoint {
316
/** Generated unique endpoint URL */
317
endpoint: string;
318
}
319
320
/**
321
* Combined HTTP context available in components
322
*/
323
interface HttpContext extends HttpEndpoint {
324
/** Method for sending HTTP responses */
325
respond: HttpRespondMethod;
326
}
327
```
328
329
**Usage Examples:**
330
331
```typescript
332
// HTTP endpoint with response
333
const httpEndpointComponent: PipedreamComponent = {
334
name: "HTTP Endpoint Component",
335
version: "1.0.0",
336
props: {
337
http: {
338
type: "$.interface.http",
339
customResponse: true
340
}
341
},
342
async run(event) {
343
console.log("Endpoint URL:", this.http.endpoint);
344
345
try {
346
// Process the request
347
const result = await processRequest(event.body);
348
349
// Send success response
350
this.http.respond({
351
status: 200,
352
headers: {
353
"Content-Type": "application/json"
354
},
355
body: {
356
success: true,
357
data: result,
358
timestamp: new Date().toISOString()
359
}
360
});
361
362
// Emit event for downstream processing
363
this.$emit(result);
364
365
} catch (error) {
366
// Send error response
367
this.http.respond({
368
status: 500,
369
headers: {
370
"Content-Type": "application/json"
371
},
372
body: {
373
success: false,
374
error: error.message,
375
timestamp: new Date().toISOString()
376
}
377
});
378
}
379
}
380
};
381
```
382
383
## Advanced Context Patterns
384
385
### Method Context Binding
386
387
Using component methods with proper context:
388
389
```typescript
390
const methodComponent: PipedreamComponent = {
391
name: "Method Component",
392
version: "1.0.0",
393
props: {
394
apiEndpoint: {
395
type: "string",
396
label: "API Endpoint",
397
default: "https://api.example.com"
398
},
399
db: "$.service.db"
400
},
401
methods: {
402
async makeApiCall(path: string, params?: any) {
403
// Access component props and context
404
const response = await fetch(`${this.apiEndpoint}${path}`, {
405
method: params ? "POST" : "GET",
406
headers: {
407
"Content-Type": "application/json"
408
},
409
body: params ? JSON.stringify(params) : undefined
410
});
411
412
return response.json();
413
},
414
415
getCachedData(key: string) {
416
return this.db.get(`cache:${key}`);
417
},
418
419
setCachedData(key: string, data: any, ttl: number = 3600) {
420
this.db.set(`cache:${key}`, {
421
data,
422
expires: Date.now() + (ttl * 1000)
423
});
424
}
425
},
426
async run(event) {
427
// Use methods with proper context
428
const cachedData = this.getCachedData("users");
429
430
let users;
431
if (cachedData && cachedData.expires > Date.now()) {
432
users = cachedData.data;
433
} else {
434
users = await this.makeApiCall("/users");
435
this.setCachedData("users", users, 1800); // 30 minutes
436
}
437
438
users.forEach(user => {
439
this.$emit(user, {
440
id: user.id,
441
summary: `User: ${user.name}`
442
});
443
});
444
}
445
};
446
```
447
448
### Multi-Service Context
449
450
Using multiple services in a single component:
451
452
```typescript
453
const multiServiceComponent: PipedreamComponent = {
454
name: "Multi-Service Component",
455
version: "1.0.0",
456
props: {
457
slack: {
458
type: "app",
459
app: "slack"
460
},
461
github: {
462
type: "app",
463
app: "github"
464
},
465
http: {
466
type: "$.interface.http"
467
},
468
db: "$.service.db"
469
},
470
async run(event) {
471
// Access multiple app contexts
472
const slackToken = this.slack.$auth.bot_token;
473
const githubToken = this.github.$auth.oauth_access_token;
474
475
// Use database for coordination
476
const lastSyncTime = this.db.get("lastGithubSync") || 0;
477
478
// Process GitHub events
479
const events = await fetchGithubEvents(githubToken, lastSyncTime);
480
481
// Send notifications to Slack
482
for (const ghEvent of events) {
483
await sendSlackMessage(slackToken, {
484
text: `GitHub: ${ghEvent.type} in ${ghEvent.repo.name}`,
485
channel: "#dev-notifications"
486
});
487
488
// Emit for other systems
489
this.$emit(ghEvent, {
490
id: ghEvent.id,
491
summary: `${ghEvent.type}: ${ghEvent.repo.name}`
492
});
493
}
494
495
// Update sync time
496
this.db.set("lastGithubSync", Date.now());
497
}
498
};
499
```