or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-context.mdcomponent-structure.mdevent-system.mdindex.mdinterface-types.mdprop-types.mdservice-types.md

component-context.mddocs/

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

```