{"id":26628119,"url":"https://github.com/flowcore-io/flowcore-pathways","last_synced_at":"2026-04-01T19:43:40.322Z","repository":{"id":282579749,"uuid":"936194688","full_name":"flowcore-io/flowcore-pathways","owner":"flowcore-io","description":"A Deno Library for creating Flowcore Pathways, simplifying the integration with the flowcore platform","archived":false,"fork":false,"pushed_at":"2026-03-27T09:33:24.000Z","size":400,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-03-27T16:37:50.598Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flowcore-io.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-20T17:19:51.000Z","updated_at":"2026-03-27T09:33:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"3bfddae4-4710-4f59-9d10-a89f43ee44ab","html_url":"https://github.com/flowcore-io/flowcore-pathways","commit_stats":null,"previous_names":["flowcore-io/flowcore-pathways"],"tags_count":39,"template":false,"template_full_name":null,"purl":"pkg:github/flowcore-io/flowcore-pathways","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowcore-io%2Fflowcore-pathways","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowcore-io%2Fflowcore-pathways/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowcore-io%2Fflowcore-pathways/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowcore-io%2Fflowcore-pathways/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flowcore-io","download_url":"https://codeload.github.com/flowcore-io/flowcore-pathways/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowcore-io%2Fflowcore-pathways/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31291202,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-24T12:28:00.853Z","updated_at":"2026-04-01T19:43:40.313Z","avatar_url":"https://github.com/flowcore-io.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Flowcore Pathways\n\nA TypeScript Library for creating Flowcore Pathways, simplifying the integration with the Flowcore platform. Flowcore\nPathways helps you build event-driven applications with type-safe pathways for processing and producing events.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Getting Started](#getting-started)\n- [Core Concepts](#core-concepts)\n- [Usage](#usage)\n  - [Creating a Pathways Builder](#creating-a-pathways-builder)\n  - [Registering Pathways](#registering-pathways)\n  - [Handling Events](#handling-events)\n  - [Writing Events](#writing-events)\n  - [Error Handling](#error-handling)\n  - [Event Observability](#event-observability)\n  - [Setting up a Router](#setting-up-a-router)\n  - [HTTP Server Integration](#http-server-integration)\n  - [Persistence Options](#persistence-options)\n- [Advanced Usage](#advanced-usage)\n  - [Auditing](#auditing)\n  - [Custom Loggers](#custom-loggers)\n  - [Retry Mechanisms](#retry-mechanisms)\n  - [Session Pathways](#session-pathways)\n- [File Pathways](#file-pathways)\n- [API Reference](#api-reference)\n\n## Installation\n\n```bash\n# Bun\nbunx jsr add @flowcore/pathways\n\n# Deno\ndeno add jsr:@flowcore/pathways\n\n# npm / yarn\nnpx jsr add @flowcore/pathways\n```\n\nor using npm:\n\n```bash\nnpm install @flowcore/pathways\n```\n\nor using yarn:\n\n```bash\nyarn add @flowcore/pathways\n```\n\n## Getting Started\n\nHere's a basic example to get you started with Flowcore Pathways:\n\n```typescript\nimport { z } from \"zod\"\nimport { PathwaysBuilder } from \"@flowcore/pathways\"\n\n// Define your event schema\nconst userSchema = z.object({\n  id: z.string(),\n  name: z.string(),\n  email: z.string(),\n})\n\n// Create a pathways builder\nconst pathways = new PathwaysBuilder({\n  baseUrl: \"https://api.flowcore.io\",\n  tenant: \"your-tenant\",\n  dataCore: \"your-data-core\",\n  apiKey: \"your-api-key\",\n})\n\n// Register a pathway\npathways\n  .register({\n    flowType: \"user\",\n    eventType: \"created\",\n    schema: userSchema,\n  })\n  .handle(\"user/created\", async (event) =\u003e {\n    console.log(`Processing user created event: ${event.eventId}`)\n    console.log(`User data:`, event.payload)\n\n    // Process the event...\n\n    // You can write to another pathway if needed\n    await pathways.write(\"notifications/sent\", {\n      data: {\n        userId: event.payload.id,\n        message: `Welcome ${event.payload.name}!`,\n        channel: \"email\",\n      },\n    })\n  })\n```\n\n## Core Concepts\n\nFlowcore Pathways is built around these core concepts:\n\n- **PathwaysBuilder**: The main entry point for creating and managing pathways\n- **Pathways**: Define event flows with schemas for type safety\n- **Handlers**: Process incoming events\n- **Writers**: Send events to pathways\n- **Router**: Direct incoming events to the appropriate pathway\n- **Persistence**: Store pathway state for reliable processing\n\n## Usage\n\n### Creating a Pathways Builder\n\nThe `PathwaysBuilder` is the main configuration point for your pathways:\n\n```typescript\nimport { PathwaysBuilder } from \"@flowcore/pathways\"\n\nconst pathways = new PathwaysBuilder({\n  baseUrl: \"https://api.flowcore.io\",\n  tenant: \"your-tenant\",\n  dataCore: \"your-data-core\",\n  apiKey: \"your-api-key\",\n  pathwayTimeoutMs: 10000, // Optional, default is 10000 (10s)\n  logger: customLogger, // Optional, defaults to NoopLogger\n})\n```\n\n### Registering Pathways\n\nRegister pathways with their schemas for type-safe event handling:\n\n```typescript\nimport { z } from \"zod\"\n\n// Define your event schema\nconst orderSchema = z.object({\n  orderId: z.string(),\n  userId: z.string(),\n  total: z.number(),\n  items: z.array(\n    z.Object({\n      id: z.string(),\n      quantity: z.number(),\n    }),\n  ),\n})\n\n// Register pathway\npathways.register({\n  flowType: \"order\",\n  eventType: \"placed\",\n  schema: orderSchema,\n  writable: true, // Optional, default is true\n  maxRetries: 3, // Optional, default is 3\n  retryDelayMs: 500, // Optional, default is 500\n})\n```\n\n### Handling Events\n\nSet up handlers to process events for specific pathways:\n\n```typescript\nconst pathwayKey = \"order/placed\"\n\npathways.handle(pathwayKey, async (event) =\u003e {\n  console.log(`Processing order ${event.payload.orderId}`)\n\n  // Access typed payload data\n  const { userId, total, items } = event.payload\n\n  // Your business logic here\n  await updateInventory(items)\n  await notifyUser(userId, total)\n})\n```\n\n### Writing Events\n\nSend events to pathways:\n\n```typescript\n// Basic write\nconst eventId = await pathways.write(\"order/placed\", {\n  data: {\n    orderId: \"ord-123\",\n    userId: \"user-456\",\n    total: 99.99,\n    items: [\n      { id: \"item-1\", quantity: 2 },\n    ],\n  },\n})\n\n// Write with metadata\nconst eventId2 = await pathways.write(\"order/placed\", {\n  data: orderData,\n  metadata: {\n    correlationId: \"corr-789\",\n    source: \"checkout-service\",\n  },\n})\n\n// Fire-and-forget mode (doesn't wait for processing)\nconst eventId3 = await pathways.write(\"order/placed\", {\n  data: orderData,\n  options: {\n    fireAndForget: true,\n  },\n})\n\n// Batch write multiple events\nconst eventIds = await pathways.write(\"order/placed\", {\n  batch: true,\n  data: [orderData1, orderData2, orderData3],\n})\n\n// Batch write with metadata\nconst eventIds2 = await pathways.write(\"order/placed\", {\n  batch: true,\n  data: [orderData1, orderData2],\n  metadata: {\n    source: \"bulk-import\",\n  },\n})\n```\n\n### Error Handling\n\nHandle errors in pathway processing:\n\n```typescript\n// Error handler for a specific pathway\npathways.onError(\"order/placed\", (error, event) =\u003e {\n  console.error(`Error processing order ${event.payload.orderId}:`, error)\n  reportToMonitoring(error, event)\n})\n\n// Global error handler for all pathways\npathways.onAnyError((error, event, pathway) =\u003e {\n  console.error(`Error in pathway ${pathway}:`, error)\n  reportToMonitoring(error, event, pathway)\n})\n```\n\n### Event Observability\n\nSubscribe to events for observability at different stages:\n\n```typescript\n// Before processing\npathways.subscribe(\"order/placed\", (event) =\u003e {\n  console.log(`About to process order ${event.payload.orderId}`)\n}, \"before\")\n\n// After processing\npathways.subscribe(\"order/placed\", (event) =\u003e {\n  console.log(`Finished processing order ${event.payload.orderId}`)\n}, \"after\")\n\n// At both stages\npathways.subscribe(\"order/placed\", (event) =\u003e {\n  console.log(`Event ${event.eventId} at ${new Date().toISOString()}`)\n}, \"all\")\n```\n\n### Setting up a Router\n\nThe `PathwayRouter` routes incoming events to the appropriate pathway:\n\n```typescript\nimport { PathwayRouter } from \"@flowcore/pathways\"\n\n// Create a router with a secret key for validation\nconst WEBHOOK_SECRET = \"your-webhook-secret\"\nconst router = new PathwayRouter(pathways, WEBHOOK_SECRET)\n\n// Process an incoming event from a webhook\nasync function handleWebhook(req: Request) {\n  const event = await req.json()\n  const secret = req.headers.get(\"X-Webhook-Secret\")\n\n  try {\n    // This validates the secret and routes to the right pathway\n    await router.processEvent(event, secret)\n    return new Response(\"Event processed\", { status: 200 })\n  } catch (error) {\n    console.error(\"Error processing event:\", error)\n    return new Response(\"Error processing event\", { status: 500 })\n  }\n}\n```\n\n### HTTP Server Integration\n\nIntegrate with Deno's HTTP server:\n\n```typescript\nimport { serve } from \"https://deno.land/std/http/server.ts\"\n\nserve(async (req: Request) =\u003e {\n  const url = new URL(req.url)\n\n  if (req.method === \"POST\" \u0026\u0026 url.pathname === \"/webhook\") {\n    return handleWebhook(req)\n  }\n\n  return new Response(\"Not found\", { status: 404 })\n}, { port: 3000 })\n```\n\n### Persistence Options\n\nFlowcore Pathways supports different persistence options to track processed events and ensure exactly-once processing.\n\n#### Default In-Memory KV Store (Development)\n\nBy default, Flowcore Pathways uses an internal in-memory KV store for persistence:\n\n```typescript\n// The default persistence is used automatically, no explicit setup required\nconst pathways = new PathwaysBuilder({\n  baseUrl: \"https://api.flowcore.io\",\n  tenant: \"your-tenant\",\n  dataCore: \"your-data-core\",\n  apiKey: \"your-api-key\",\n})\n```\n\nThe internal store uses the appropriate KV adapter for your environment (Bun, Node, or Deno), but note that this state\nis not persistent across application restarts and should be used primarily for development.\n\n#### PostgreSQL Persistence (Production)\n\nFor production environments, you can use PostgreSQL for reliable and scalable persistence:\n\n```typescript\nimport { createPostgresPathwayState, PostgresPathwayState } from \"@flowcore/pathways\"\n\n// Create a PostgreSQL state handler\nconst postgresState = createPostgresPathwayState({\n  host: \"localhost\",\n  port: 5432,\n  user: \"postgres\",\n  password: \"postgres\",\n  database: \"pathway_db\",\n  tableName: \"pathway_state\", // Optional, defaults to \"pathway_state\"\n  ttlMs: 300000, // Optional, defaults to 5 minutes (300000ms)\n  ssl: false, // Optional, defaults to false\n})\n\n// Use PostgreSQL for pathway state\npathways.withPathwayState(postgresState)\n```\n\nThe PostgreSQL implementation:\n\n- Automatically creates the necessary table if it doesn't exist\n- Includes TTL-based automatic cleanup of processed events\n- Creates appropriate indexes for performance\n\n## Advanced Usage\n\n### Auditing\n\nEnable auditing to track events:\n\n```typescript\n// Set up auditing\npathways\n  .withAudit((path, event) =\u003e {\n    console.log(`Audit: ${path} event ${event.eventId}`)\n    logToAuditSystem(path, event)\n  })\n  .withUserResolver(async () =\u003e {\n    // Get the current user ID from context\n    return {\n      entityId: \"user-123\",\n      entityType: \"user\",\n    }\n  })\n```\n\n### Custom Loggers\n\nCreate a custom logger:\n\n```typescript\nimport { Logger } from \"@flowcore/pathways\"\n\nclass MyCustomLogger implements Logger {\n  debug(message: string, context?: Record\u003cstring, unknown\u003e): void {\n    console.debug(`[DEBUG] ${message}`, context)\n  }\n\n  info(message: string, context?: Record\u003cstring, unknown\u003e): void {\n    console.info(`[INFO] ${message}`, context)\n  }\n\n  warn(message: string, context?: Record\u003cstring, unknown\u003e): void {\n    console.warn(`[WARN] ${message}`, context)\n  }\n\n  error(message: string, error?: Error, context?: Record\u003cstring, unknown\u003e): void {\n    console.error(`[ERROR] ${message}`, error, context)\n  }\n}\n\n// Use custom logger\nconst pathways = new PathwaysBuilder({\n  // ...other config\n  logger: new MyCustomLogger(),\n})\n```\n\n### Retry Mechanisms\n\nConfigure retry behavior for pathways:\n\n```typescript\n// Global timeout for pathway processing\nconst pathways = new PathwaysBuilder({\n  // ...other config\n  pathwayTimeoutMs: 15000, // 15 seconds\n})\n\n// Per-pathway retry configuration\npathways.register({\n  flowType: \"payment\",\n  eventType: \"process\",\n  schema: paymentSchema,\n  maxRetries: 5, // Retry up to 5 times\n  retryDelayMs: 1000, // 1 second between retries\n})\n```\n\n### Session Pathways\n\nThe `SessionPathwayBuilder` provides a way to associate session IDs with pathway operations, making it easier to track\nand manage user sessions in your application.\n\n#### Setting Up Session Support\n\nTo use session-specific functionality, first configure your `PathwaysBuilder` with session support:\n\n```typescript\nimport { PathwaysBuilder } from \"@flowcore/pathways\"\n\n// Configure the builder with session support\nconst pathways = new PathwaysBuilder({\n  baseUrl: \"https://api.flowcore.io\",\n  tenant: \"your-tenant\",\n  dataCore: \"your-data-core\",\n  apiKey: \"your-api-key\",\n  enableSessionUserResolvers: true, // Enable session-specific resolvers\n})\n```\n\n#### Creating Session Pathways\n\nCreate a session-specific pathway wrapper:\n\n```typescript\nimport { SessionPathwayBuilder } from \"@flowcore/pathways\"\n\n// Create a session with an auto-generated session ID\nconst session = new SessionPathwayBuilder(pathways)\nconst sessionId = session.getSessionId() // Get the auto-generated ID\n\n// Or create a session with a specific session ID\nconst customSession = new SessionPathwayBuilder(pathways, \"user-session-123\")\n```\n\n#### Session-Specific User Resolvers\n\nYou can register different user resolvers for different sessions, allowing you to associate users with specific\nsessions:\n\n```typescript\n// Register a user resolver for a specific session\npathways.withSessionUserResolver(\"user-session-123\", async () =\u003e {\n  // Return the user ID for this session\n  return {\n    entityId: \"user-456\",\n    entityType: \"user\",\n  }\n})\n\n// Alternative: Register directly through the session instance\nsession.withUserResolver(async () =\u003e {\n  return {\n    entityId: \"key-789\",\n    entityType: \"key\",\n  }\n})\n```\n\n#### Writing Events with Session Context\n\nEvents written through a session builder automatically include the session ID:\n\n```typescript\n// Write an event with session context\nawait session.write(\"order/placed\", {\n  data: {\n    orderId: \"ord-123\",\n    userId: \"user-456\",\n    total: 99.99,\n    items: [{ id: \"item-1\", quantity: 2 }],\n  },\n})\n\n// You can override the session ID for a specific write\nawait session.write(\"order/placed\", {\n  data: orderData,\n  options: { sessionId: \"different-session\" },\n})\n\n// Batch write events with session context\nawait session.write(\"user/actions\", {\n  batch: true,\n  data: [actionData1, actionData2, actionData3],\n})\n```\n\n#### Session ID in Audit Events\n\nWhen auditing is enabled, the session ID is included in the audit metadata:\n\n```typescript\n// Enable auditing\npathways.withAudit((path, event) =\u003e {\n  console.log(`Audit: ${path} event ${event.eventId}`)\n  // The session ID will be included in event metadata\n})\n\n// Now when writing events through a session\nawait session.write(\"order/placed\", { data: orderData })\n// The session ID is automatically included in the audit metadata\n```\n\n### File Pathways\n\nFile pathways provide a specialized way to handle file uploads and processing in your Flowcore applications. They\nautomatically handle file type detection, binary content processing, and provide a structured approach to file\nmanagement.\n\n#### Registering File Pathways\n\nRegister a file pathway by setting the `isFilePathway` flag to `true`:\n\n```typescript\nimport { z } from \"zod\"\n\n// Define additional properties schema for your file\nconst documentSchema = z.object({\n  documentType: z.enum([\"invoice\", \"receipt\", \"contract\"]),\n  department: z.string(),\n  metadata: z.record(z.string()).optional(),\n})\n\n// Register a file pathway\npathways.register({\n  flowType: \"document\",\n  eventType: \"uploaded\",\n  schema: documentSchema, // Additional properties beyond the file itself\n  isFilePathway: true, // This marks it as a file pathway\n  writable: true,\n})\n```\n\n#### Writing Files to Pathways\n\nFile pathways use a special input format that includes file content and metadata:\n\n```typescript\nimport { readFile } from \"node:fs/promises\"\n\n// Read file content (as Buffer for Node.js/Bun, Uint8Array for Deno)\nconst fileContent = await readFile(\"./invoice.pdf\")\n\n// Write a file to a pathway\nconst eventId = await pathways.write(\"document/uploaded\", {\n  data: {\n    fileId: \"file-123\", // Unique identifier for the file\n    fileName: \"invoice-2024.pdf\", // Original filename\n    fileContent: fileContent, // File content as Buffer/Uint8Array\n    // Additional properties defined in your schema\n    documentType: \"invoice\",\n    department: \"finance\",\n    metadata: {\n      customer: \"ACME Corp\",\n      amount: \"1500.00\",\n    },\n  },\n})\n```\n\n#### File Input Schema\n\nFile pathways automatically include these required fields:\n\n```typescript\n// Built-in file fields (automatically added)\ninterface FileInput {\n  fileId: string // Unique identifier for the file\n  fileName: string // Original filename with extension\n  fileContent: Buffer | Uint8Array // Binary file content\n  // ... your additional schema properties\n}\n```\n\n#### File Event Schema\n\nWhen processed, file events include automatic file type detection:\n\n```typescript\n// Built-in file event fields (automatically added to your schema)\ninterface FileEvent {\n  fileId: string // Unique identifier for the file\n  fileName: string // Original filename\n  fileType: string // MIME type (automatically detected)\n  fileContent: Blob // File content as Blob\n  // ... your additional schema properties\n}\n```\n\n#### Handling File Events\n\nHandle file events just like regular events, but with access to file-specific properties:\n\n```typescript\npathways.handle(\"document/uploaded\", async (event) =\u003e {\n  const { fileId, fileName, fileType, fileContent, documentType, department } = event.payload\n\n  console.log(`Processing file: ${fileName} (${fileType})`)\n  console.log(`Document type: ${documentType}, Department: ${department}`)\n\n  // Process the file content\n  if (fileType === \"application/pdf\") {\n    await processPDFDocument(fileContent, event.payload.metadata)\n  } else if (fileType.startsWith(\"image/\")) {\n    await processImageFile(fileContent, documentType)\n  }\n\n  // Store file metadata\n  await storeFileMetadata({\n    fileId,\n    fileName,\n    fileType,\n    documentType,\n    department,\n    processedAt: new Date(),\n  })\n})\n```\n\n#### File Pathway Limitations\n\nFile pathways have some specific limitations:\n\n```typescript\n// ❌ Batch writes are NOT supported for file pathways\n// This will throw an error:\nawait pathways.write(\"document/uploaded\", {\n  batch: true, // Error: Batch is not possible for file pathways\n  data: [fileData1, fileData2],\n})\n\n// ✅ Write files individually instead:\nfor (const fileData of fileDataArray) {\n  await pathways.write(\"document/uploaded\", { data: fileData })\n}\n```\n\n#### Complete File Pathway Example\n\nHere's a complete example of setting up and using file pathways:\n\n```typescript\nimport { PathwaysBuilder } from \"@flowcore/pathways\"\nimport { z } from \"zod\"\nimport { readFile } from \"node:fs/promises\"\n\n// Define schema for additional file properties\nconst documentSchema = z.object({\n  documentType: z.enum([\"invoice\", \"receipt\", \"contract\", \"report\"]),\n  department: z.string(),\n  tags: z.array(z.string()).optional(),\n  metadata: z.record(z.string()).optional(),\n})\n\nconst pathways = new PathwaysBuilder({\n  baseUrl: \"https://api.flowcore.io\",\n  tenant: \"your-tenant\",\n  dataCore: \"your-data-core\",\n  apiKey: \"your-api-key\",\n})\n\n// Register file pathway\npathways\n  .register({\n    flowType: \"document\",\n    eventType: \"uploaded\",\n    schema: documentSchema,\n    isFilePathway: true,\n  })\n  .handle(\"document/uploaded\", async (event) =\u003e {\n    const { fileId, fileName, fileType, documentType, department } = event.payload\n\n    console.log(`Processing ${documentType} from ${department}: ${fileName}`)\n\n    // File type-specific processing\n    switch (fileType) {\n      case \"application/pdf\":\n        await extractPDFText(event.payload.fileContent)\n        break\n      case \"image/jpeg\":\n      case \"image/png\":\n        await extractImageMetadata(event.payload.fileContent)\n        break\n      default:\n        console.log(`Unsupported file type: ${fileType}`)\n    }\n\n    // Trigger downstream processing\n    await pathways.write(\"document/processed\", {\n      data: {\n        fileId,\n        fileName,\n        documentType,\n        department,\n        processedAt: new Date().toISOString(),\n        status: \"completed\",\n      },\n    })\n  })\n\n// Upload a file\nasync function uploadDocument(filePath: string, documentType: string, department: string) {\n  const fileContent = await readFile(filePath)\n  const fileName = filePath.split(\"/\").pop() || \"unknown\"\n\n  return await pathways.write(\"document/uploaded\", {\n    data: {\n      fileId: `doc-${Date.now()}`,\n      fileName,\n      fileContent,\n      documentType,\n      department,\n      tags: [\"automated-upload\"],\n      metadata: {\n        uploadedAt: new Date().toISOString(),\n        source: \"api\",\n      },\n    },\n  })\n}\n\n// Usage\nawait uploadDocument(\"./invoice.pdf\", \"invoice\", \"finance\")\n```\n\n## API Reference\n\nFor a complete API reference, please see the [API documentation](https://jsr.io/@flowcore/pathways).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowcore-io%2Fflowcore-pathways","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflowcore-io%2Fflowcore-pathways","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowcore-io%2Fflowcore-pathways/lists"}