### Post-install Message Displayed to User Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md An example of the console output shown to the user immediately after the @jenova-marie/ts-rust-result package is installed. It highlights the availability of documentation and provides quick links to key resources. ```text ╔═══════════════════════════════════════════════════════════════════╗ ║ ║ ║ 📚 @jenova-marie/ts-rust-result - Documentation Available! ║ ║ ║ ╚═══════════════════════════════════════════════════════════════════╝ ✨ Complete documentation is included in this package! Quick Start: → node_modules/@jenova-marie/ts-rust-result/DOCUMENTATION.md Key Resources: 📖 README.md - Quick start & examples 📜 CHANGELOG.md - Version history & migrations 🎯 content/PATTERNS.md - Common patterns & best practices ... ``` -------------------------------- ### User Workflow: Install and Explore Package Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md This bash script illustrates a typical user workflow after installing the @jenova-marie/ts-rust-result package. It shows how to view the post-install message, read the README, explore pattern guides and API documentation, and check the changelog. ```bash # User installs package npm install @jenova-marie/ts-rust-result # Post-install message appears with documentation info # User reads getting started cat node_modules/@jenova-marie/ts-rust-result/README.md # User explores patterns guide cat node_modules/@jenova-marie/ts-rust-result/content/PATTERNS.md # User needs API details open node_modules/@jenova-marie/ts-rust-result/docs/index.html # User integrates OpenTelemetry cat node_modules/@jenova-marie/ts-rust-result/content/OPENTELEMETRY.md # User checks migration guide for new version cat node_modules/@jenova-marie/ts-rust-result/CHANGELOG.md ``` -------------------------------- ### Setup: Install OpenTelemetry Dependencies Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/OPENTELEMETRY.md Provides the necessary npm or pnpm commands to install the required OpenTelemetry packages for Node.js applications. These include the core API, the Node.js SDK, and auto-instrumentations. ```bash npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node # or pnpm add @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node ``` -------------------------------- ### Setup: Install and Initialize Sentry SDK Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/SENTRY.md Provides instructions for installing the Sentry Node.js SDK and initializing it with your Sentry DSN and environment configuration. This is a prerequisite for capturing errors. ```bash npm install @sentry/node # or pnpm add @sentry/node ``` ```typescript import * as Sentry from '@sentry/node' Sentry.init({ dsn: process.env.SENTRY_DSN, environment: process.env.NODE_ENV, tracesSampleRate: 1.0, }) ``` -------------------------------- ### npm package.json 'scripts' Post-Install Configuration Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md Defines the 'postinstall' script, which automatically executes a Node.js script after the package is installed via npm. This script is used to display a helpful message to the user about available documentation. ```json { "scripts": { "postinstall": "node scripts/postinstall.js" } } ``` -------------------------------- ### Setup: Initialize OpenTelemetry Node SDK Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/OPENTELEMETRY.md Illustrates how to initialize the OpenTelemetry Node.js SDK. This includes configuring an OTLP trace exporter to send traces to a specified endpoint and enabling automatic instrumentation for common Node.js modules. ```typescript import { NodeSDK } from '@opentelemetry/sdk-node' import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node' import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http' const sdk = new NodeSDK({ traceExporter: new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318/v1/traces' }), instrumentations: [getNodeAutoInstrumentations()] }) sdk.start() ``` -------------------------------- ### npm package.json 'files' Array Configuration Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md Specifies which files and directories are included when the npm package is published. This ensures that compiled code, documentation, content guides, scripts, and license information are part of the distributed package. ```json { "files": [ "dist", "docs", "content", "scripts", "README.md", "CHANGELOG.md", "DOCUMENTATION.md", "LICENSE" ] } ``` -------------------------------- ### Install Zod as a Peer Dependency Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/ZOD.md Instructions for installing Zod, which is an optional peer dependency for ts-rust-result. It's only required if you intend to use the Zod integration features. ```bash npm install zod # or pnpm add zod ``` -------------------------------- ### Accessing Offline Documentation via npm Source: https://github.com/jenova-marie/ts-rust-result/blob/main/API.md Provides instructions on how to access the project's documentation offline by extracting it from the installed npm package. It specifies the path to the TypeDoc API reference within the `node_modules` directory. ```bash # Extract from installed package cd node_modules/@jenova-marie/ts-rust-result open docs/index.html # TypeDoc API reference ``` -------------------------------- ### Quick Start: Validate Data with Zod and ts-rust-result Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/ZOD.md Demonstrates a quick setup for validating unknown data against a Zod schema and converting the validation result into a ts-rust-result's `Result` type. Handles potential validation errors. ```typescript import { z } from 'zod' import { fromZodSafeParse } from '@jenova-marie/ts-rust-result/errors' const UserSchema = z.object({ name: z.string(), email: z.string().email() }) function validateUser(data: unknown): Result { return fromZodSafeParse(UserSchema.safeParse(data)) } const result = validateUser({ name: 'Alice' }) // Missing email if (!result.ok) { // result.error.kind === 'SchemaValidation' // result.error.context.issues contains detailed validation errors } ``` -------------------------------- ### Clone Repository and Install Dependencies (Git, PNPM) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/README.md Instructions for forking the repository, cloning the project, and installing necessary dependencies using PNPM. This is the initial step for contributing to the project. ```bash git clone https://github.com/yourusername/ts-rust-result.git pnpm install ``` -------------------------------- ### Serving HTML API Reference Locally (Bash) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md Provides bash commands to navigate to the generated HTML API documentation directory and serve it locally using `http-server`. This allows viewing the documentation in a web browser. ```bash # Navigate to the docs directory cd node_modules/@jenova-marie/ts-rust-result/docs # Serve the documentation locally on port 8080 npx http-server -p 8080 # Visit http://localhost:8080 in your browser ``` -------------------------------- ### Accessing Documentation Paths from package.json (JavaScript) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md Demonstrates how to programmatically retrieve documentation paths defined in the 'documentation' field of the package.json file using Node.js's require mechanism. ```javascript const pkg = require('@jenova-marie/ts-rust-result/package.json') console.log(pkg.documentation.patterns) // './content/PATTERNS.md' ``` -------------------------------- ### Quick Start: Capture Errors with Sentry Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/SENTRY.md Demonstrates the initial steps to integrate Sentry error capturing within a TypeScript application using ts-rust-result. It shows how to convert a `DomainError` to a Sentry-compatible format and capture it. ```typescript import * as Sentry from '@sentry/node' import { toSentryError } from '@jenova-marie/ts-rust-result/errors' const result = loadConfig() if (!result.ok) { // Convert DomainError to Error instance for Sentry Sentry.captureException(toSentryError(result.error)) } ``` -------------------------------- ### Generating and Viewing Local Documentation Source: https://github.com/jenova-marie/ts-rust-result/blob/main/API.md Details the command-line process for generating or updating the project's documentation locally using `pnpm docs` and subsequently viewing the generated TypeDoc HTML files in a web browser. ```bash # Generate/update docs locally pnpm docs # View in browser open docs/index.html ``` -------------------------------- ### Accessing Markdown Documentation from Node.js (CommonJS) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md Shows how to read markdown documentation files (like DOCUMENTATION.md or PATTERNS.md) from within a Node.js environment using the file system module. ```javascript const { readFileSync } = require('fs') const { join, dirname } = require('path') const { fileURLToPath } = require('url') // Assuming pkgPath is already defined and points to the package.json // const pkgPath = import.meta.resolve('@jenova-marie/ts-rust-result/package.json') // For ESM const pkgPath = require.resolve('@jenova-marie/ts-rust-result/package.json') // For CommonJS const pkgDir = dirname(pkgPath) // Example: Reading PATTERNS.md const patternsDocPath = join(pkgDir, 'content/PATTERNS.md') const patternsDoc = readFileSync(patternsDocPath, 'utf-8') console.log(patternsDoc) ``` -------------------------------- ### Build and Verify Package Contents Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md This sequence of commands builds the project and then performs a dry run of the npm pack command to verify that all intended files are included in the package tarball. It uses pnpm for building and npm for packing. ```bash pnpm build npm pack --dry-run ``` -------------------------------- ### Install ts-rust-result Package Source: https://github.com/jenova-marie/ts-rust-result/blob/main/README.md Instructions for installing the ts-rust-result library using npm, yarn, or pnpm. This library is zero-dependency and supports both ESM and CommonJS module formats. ```bash npm install @jenova-marie/ts-rust-result # or yarn add @jenova-marie/ts-rust-result # or pnpm add @jenova-marie/ts-rust-result ``` -------------------------------- ### npm package.json 'directories' Field Configuration Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md Defines standard directories used by npm, such as the documentation directory ('docs') and the library directory ('dist'). This helps npm and other tools locate key project components. ```json { "directories": { "doc": "docs", "lib": "dist" } } ``` -------------------------------- ### Install Latest Package (Bash) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/RELEASING.md This command installs the latest version of the @jenova-marie/ts-rust-result package from npm. It's used to verify that the published release is correctly installed. ```bash npm install @jenova-marie/ts-rust-result@latest ``` -------------------------------- ### TypeDoc Configuration for Media Inclusion Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md This JSON configuration snippet for TypeDoc specifies that the content directory should be automatically copied to the docs/media directory. This makes markdown content available both as source and within the generated documentation website. ```json { "media": "content" } ``` -------------------------------- ### Testing Sentry Integration in Development Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/SENTRY.md Initializes Sentry in development mode with debug logging enabled. It includes an example of sending a test error using `captureException` and checking the Sentry dashboard. ```typescript import * as Sentry from '@sentry/node' // Initialize Sentry with debug mode Sentry.init({ dsn: process.env.SENTRY_DSN, environment: 'development', debug: true, // Enable debug logging beforeSend(event) { console.log('Sentry event:', event) return event } }) // Test sending an error const testError = fileNotFound('/test.txt') Sentry.captureException(toSentryError(testError)) // Check Sentry dashboard for the error ``` -------------------------------- ### Update Source Content with Vim Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md This command demonstrates how to update markdown source content using the Vim editor. It targets the PATTERNS.md file within the content directory. ```bash vim content/PATTERNS.md ``` -------------------------------- ### Form Validation with Zod and ts-rust-result Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/ZOD.md Provides an example of validating a signup form using Zod and `fromZodSchema`. It defines a `SignupFormSchema` with complex validation rules, including password confirmation matching. The function `handleSignup` processes form data, returning either success with user data or a map of validation errors. ```typescript import { z } from 'zod' import { fromZodSchema } from '@jenova-marie/ts-rust-result/errors' const SignupFormSchema = z.object({ username: z.string() .min(3, 'Username must be at least 3 characters') .max(20, 'Username must be at most 20 characters') .regex(/^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers, and underscores'), email: z.string().email('Invalid email address'), password: z.string() .min(8, 'Password must be at least 8 characters') .regex(/[A-Z]/, 'Password must contain at least one uppercase letter') .regex(/[0-9]/, 'Password must contain at least one number'), confirmPassword: z.string() }).refine(data => data.password === data.confirmPassword, { message: 'Passwords do not match', path: ['confirmPassword'] }) function handleSignup(formData: unknown) { const result = fromZodSchema(SignupFormSchema, formData) if (!result.ok) { // Display validation errors to user const errors = new Map() result.error.context.issues.forEach(issue => { const field = issue.path.join('.') errors.set(field, issue.message) }) return { success: false, errors } } // Proceed with signup return createUser(result.value) } ``` -------------------------------- ### Bash: Run Jaeger All-in-One Docker Container Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/OPENTELEMETRY.md This bash command starts a Jaeger all-in-one Docker container, making the Jaeger UI accessible at http://localhost:16686 and the OTLP receiver available at port 4318. This is useful for local development and testing of OpenTelemetry tracing configurations. ```bash docker run -d --name jaeger \ -p 16686:16686 \ -p 4318:4318 \ jaegertracing/all-in-one:latest ``` -------------------------------- ### Database Query Tracing with OpenTelemetry Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/OPENTELEMETRY.md An example demonstrating how to trace database queries using OpenTelemetry. It wraps a database query operation with a span, adding relevant database attributes and setting the span status based on success or failure. Error details are added to the span upon failure. Dependencies: '@opentelemetry/api', '@jenova-marie/ts-rust-result/observability'. ```typescript import { trace, SpanStatusCode } from '@opentelemetry/api' import { toSpanAttributes } from '@jenova-marie/ts-rust-result/observability' async function queryDatabase(sql: string): Promise> { const tracer = trace.getTracer('database') const span = tracer.startSpan('db.query', { attributes: { 'db.system': 'postgresql', 'db.statement': sql } }) const result = await tryResultSafe(async () => { return await pool.query(sql) }) if (!result.ok) { span.setAttributes(toSpanAttributes(result.error)) span.setStatus({ code: SpanStatusCode.ERROR, message: 'Database query failed' }) } else { span.setStatus({ code: SpanStatusCode.OK }) span.setAttribute('db.rows_affected', result.value.length) } span.end() return result } ``` -------------------------------- ### Observability Module Exports for ts-rust-result Source: https://github.com/jenova-marie/ts-rust-result/blob/main/API.md Lists the observability-related utilities exported from '@jenova-marie/ts-rust-result/observability'. These include functions for structured logging, OpenTelemetry span attributes, Sentry error conversion, and Prometheus metric labels. ```typescript // Observability import { toLogContext, // Structured logging toSpanAttributes, // OpenTelemetry spans recordErrorEvent, recordErrorCauseChain, toSentryError, // Sentry integration toMetricLabels // Prometheus metrics } from '@jenova-marie/ts-rust-result/observability' ``` -------------------------------- ### Helper Module Exports for ts-rust-result Source: https://github.com/jenova-marie/ts-rust-result/blob/main/API.md Highlights the exports from the '@jenova-marie/ts-rust-result/helpers' module, specifically focusing on the `createDomainResult` function. This function is used to create domain-specific `Result` type aliases, simplifying their usage. ```typescript // Helpers (v2.2.0+) import { createDomainResult // Create domain-specific wrappers } from '@jenova-marie/ts-rust-result/helpers' ``` -------------------------------- ### Quick Start: Add Error Attributes to Span Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/OPENTELEMETRY.md Demonstrates the basic steps to integrate ts-rust-result with OpenTelemetry. It shows how to get the active span, perform an operation, and if an error occurs, add its attributes to the span and set the span's status to ERROR. ```typescript import { trace } from '@opentelemetry/api' import { toSpanAttributes } from '@jenova-marie/ts-rust-result/observability' const span = trace.getActiveSpan() const result = performOperation() if (!result.ok) { // Add error attributes to span span?.setAttributes(toSpanAttributes(result.error)) span?.setStatus({ code: SpanStatusCode.ERROR }) } ``` -------------------------------- ### Express API Error Handling with OpenTelemetry Tracing Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/OPENTELEMETRY.md Provides an example of an Express.js API endpoint that integrates OpenTelemetry for tracing. It demonstrates how to start a span for each request, add relevant HTTP attributes, handle errors by setting span status and attributes, and send appropriate HTTP responses. Dependencies: 'express', '@opentelemetry/api', '@jenova-marie/ts-rust-result/observability'. ```typescript import express from 'express' import { trace, SpanStatusCode } from '@opentelemetry/api' import { toSpanAttributes, recordErrorEvent } from '@jenova-marie/ts-rust-result/observability' const app = express() const tracer = trace.getTracer('api-service') app.get('/api/users/:id', async (req, res) => { const span = tracer.startSpan('get_user', { attributes: { 'http.method': req.method, 'http.route': req.route.path, 'http.target': req.url } }) const result = await loadUser(req.params.id) if (!result.ok) { const error = result.error as DomainError // Add error to span span.setAttributes(toSpanAttributes(error)) span.setStatus({ code: SpanStatusCode.ERROR, message: error.message }) recordErrorEvent(span, error) // HTTP response span.setAttribute('http.status_code', error.kind === 'NotFound' ? 404 : 500) span.end() return res.status(error.kind === 'NotFound' ? 404 : 500).json({ error: error.message }) } span.setStatus({ code: SpanStatusCode.OK }) span.setAttribute('http.status_code', 200) span.end() res.json(result.value) }) ``` -------------------------------- ### Correctly Get and Use Active Span in OpenTelemetry Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/OPENTELEMETRY.md This code highlights the correct way to retrieve and use an active OpenTelemetry span. It emphasizes checking if a span exists (`if (span)`) before calling methods like `setAttributes` to prevent runtime errors. The incorrect example shows a common pitfall of assuming a span is always available, which can lead to exceptions. ```typescript // ✅ GOOD: Get active span first import { trace } from '@opentelemetry/api'; // Assuming trace is imported const span = trace.getActiveSpan(); if (span) { // Assuming toSpanAttributes is defined elsewhere span.setAttributes(toSpanAttributes(error)); } // ❌ BAD: Assuming span exists // trace.getActiveSpan().setAttributes(toSpanAttributes(error)); // May throw if no active span ``` -------------------------------- ### npm package.json 'documentation' Field Configuration Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md A custom field in package.json providing programmatic access to documentation paths. It maps descriptive keys (e.g., 'quick-start', 'api-reference') to their corresponding file or directory locations within the package. ```json { "documentation": { "quick-start": "./README.md", "api-reference": "./docs/index.html", "guides": "./content/", "changelog": "./CHANGELOG.md", "index": "./DOCUMENTATION.md", "patterns": "./content/PATTERNS.md", "error-design": "./content/ERROR_DESIGN.md", "opentelemetry": "./content/OPENTELEMETRY.md", "sentry": "./content/SENTRY.md", "zod": "./content/ZOD.md" } } ``` -------------------------------- ### Pattern: Validate API Requests with Zod and ts-rust-result Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/ZOD.md Provides an example of validating incoming API request bodies using Zod and ts-rust-result within an Express.js application. If validation fails, it returns a 400 status with detailed issues; otherwise, it proceeds with the validated data. ```typescript import express from 'express' import { z } from 'zod' import { fromZodSchema } from '@jenova-marie/ts-rust-result/errors' const CreatePostSchema = z.object({ title: z.string().min(1).max(200), content: z.string().min(1), tags: z.array(z.string()).optional(), published: z.boolean().default(false) }) app.post('/api/posts', async (req, res) => { // Validate request body const validationResult = fromZodSchema(CreatePostSchema, req.body) if (!validationResult.ok) { const error = validationResult.error return res.status(400).json({ error: 'Validation failed', issues: error.context.issues }) } // Create post with validated data const post = await createPost(validationResult.value) res.json(post) }) ``` -------------------------------- ### Complete Publish Workflow (pnpm make) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DEVELOPMENT.md This script orchestrates the complete workflow for publishing a new version of the package to the npm registry. It encompasses documentation generation, building, testing, and the necessary pre-publish hooks. ```bash pnpm make ``` -------------------------------- ### Accessing Markdown Documentation from Node.js (ES Modules) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DOCUMENTATION_SETUP.md Demonstrates how to programmatically read markdown documentation files from within a Node.js ES Module environment, including resolving the package path and using the file system module. ```javascript import { readFileSync } from 'fs' import { join, dirname } from 'path' import { fileURLToPath } from 'url' const pkgPath = import.meta.resolve('@jenova-marie/ts-rust-result/package.json') const pkgDir = dirname(fileURLToPath(pkgPath)) const docPaths = (await import('@jenova-marie/ts-rust-result/package.json', { assert: { type: 'json' } })).default.documentation // Example: Reading PATTERNS.md const patternsDocPath = join(pkgDir, docPaths.patterns) const patternsDoc = readFileSync(patternsDocPath, 'utf-8') console.log(patternsDoc) ``` -------------------------------- ### Union Error Types for Multi-Source Errors in TypeScript Source: https://github.com/jenova-marie/ts-rust-result/blob/main/API.md Defines domain errors using union types and demonstrates exhaustive pattern matching for handling errors from multiple sources within a TypeScript function. It includes examples of custom error types and the use of domain wrappers for cleaner error handling. ```typescript // Define domain errors (auth-errors.ts) import { type NetworkError, type ValidationError, error } from '@jenova-marie/ts-rust-result/errors' export interface InvalidCredentialsError { readonly kind: 'InvalidCredentials' readonly message: string } export type AuthError = NetworkError | ValidationError | InvalidCredentialsError // Use domain wrapper import { createDomainResult } from '@jenova-marie/ts-rust-result/helpers' const { ok, err } = createDomainResult() export type AuthResult = Result // Implement functions export async function authenticate(username: string, password: string): AuthResult { // Validation step if (!username || !password) { return err(requiredFieldMissing('username or password')) } // Network call const response = await tryResultSafe(async () => { return await fetch('/api/auth', { method: 'POST', body: JSON.stringify({ username, password }) }).then(r => r.json()) }) if (!response.ok) return response // ✅ NetworkError flows through // Custom validation if (!response.value.token) { return err(createInvalidCredentialsError('Invalid credentials')) } return ok(response.value.user) } // Exhaustive error handling with pattern matching function handleAuthError(result: AuthResult) { if (result.ok) { console.log('User authenticated:', result.value) return } // TypeScript enforces all error kinds are handled switch (result.error.kind) { case 'RequiredFieldMissing': console.error('Missing field:', result.error.field) break case 'NetworkError': console.error('Network failed:', result.error.message) break case 'SchemaValidation': console.error('Validation failed:', result.error.context.issues) break case 'InvalidCredentials': console.error('Bad credentials') break default: // TypeScript enforces exhaustiveness const _exhaustive: never = result.error throw new Error(`Unknown error: ${_exhaustive}`) } } ``` -------------------------------- ### Manual Release Steps (Bash) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/RELEASING.md This section outlines the commands for performing a release manually if the automated GitHub Actions workflow is unavailable. It includes fetching the latest code, running tests, building the package, publishing to npm, and instructions for manually creating a GitHub Release. ```bash # Ensure you're on main with latest code git checkout main git pull origin main # Run tests pnpm test # Build pnpm build # Generate docs pnpm docs # Publish (requires npm login) npm login pnpm publish --access public # Create GitHub release manually # Go to https://github.com/jenova-marie/ts-rust-result/releases/new ``` -------------------------------- ### Sentry Error Handling for HTTP API Endpoints Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/SENTRY.md Example of handling errors within an Express.js HTTP API route using ts-rust-result and Sentry. Errors are logged locally and selectively reported to Sentry, with appropriate HTTP status codes returned to the client. Dependencies include 'express', '@sentry/node', '@jenova-marie/ts-rust-result/errors', '@jenova-marie/ts-rust-result/observability', and 'pino'. ```typescript import express from 'express' import * as Sentry from '@sentry/node' import { toSentryError, type DomainError } from '@jenova-marie/ts-rust-result/errors' import { toLogContext } from '@jenova-marie/ts-rust-result/observability' import pino from 'pino' const logger = pino() const app = express() app.get('/api/users/:id', async (req, res) => { const result = await loadUser(req.params.id) if (!result.ok) { const error = result.error as DomainError // Always log logger.error(toLogContext(error), 'Failed to load user') // Send to Sentry (filtered) if (error.kind !== 'NotFound') { Sentry.captureException(toSentryError(error), { extra: { user_id: req.params.id, request_id: req.headers['x-request-id'] } }) } // Send appropriate HTTP response if (error.kind === 'NotFound') { return res.status(404).json({ error: 'User not found' }) } return res.status(500).json({ error: 'Internal server error' }) } res.json(result.value) }) ``` -------------------------------- ### NPM Publish Workflow via GitHub Actions Source: https://github.com/jenova-marie/ts-rust-result/blob/main/CLAUDE.md Details the command to trigger the full build pipeline and publish the package to npm, typically executed via GitHub Actions. Mentions hooks for pre-publishing steps. ```bash pnpm make # Complete build pipeline + publish to npm # Pipeline: docs → build → test → npm publish # Note: Publishing to npm happens via GitHub Actions. Use `pnpm pack` for local development and testing. # The `prepublishOnly` hook automatically runs `docs`, `build`, and `test` before publishing. ``` -------------------------------- ### Mock OpenTelemetry API for Jest Tests Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/OPENTELEMETRY.md This snippet demonstrates how to mock the OpenTelemetry API, specifically `trace.getActiveSpan` and `trace.getTracer`, using Jest. It allows you to simulate span creation and manipulation within your tests by providing mock functions for `setAttributes`, `setStatus`, `addEvent`, and `end`. This is useful for verifying how your code interacts with OpenTelemetry spans without needing a live OpenTelemetry setup. ```typescript import { jest } from '@jest/globals' const mockSetAttributes = jest.fn() const mockSetStatus = jest.fn() const mockAddEvent = jest.fn() const mockEnd = jest.fn() jest.mock('@opentelemetry/api', () => ({ trace: { getActiveSpan: () => ({ setAttributes: mockSetAttributes, setStatus: mockSetStatus, addEvent: mockAddEvent, end: mockEnd }), getTracer: () => ({ startSpan: () => ({ setAttributes: mockSetAttributes, setStatus: mockSetStatus, addEvent: mockAddEvent, end: mockEnd }) }) } })) // Test example: it('should add error attributes to span', () => { const error = fileNotFound('/missing.txt') // Assuming fileNotFound is defined elsewhere handleError(error) // Assuming handleError uses the mocked span expect(mockSetAttributes).toHaveBeenCalledWith( expect.objectContaining({ 'error.kind': 'FileNotFound', 'error.message': expect.stringContaining('File not found') }) ) }) ``` -------------------------------- ### Build, Test, and Lint Project (PNPM) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/README.md Commands to build the project, run tests, execute tests in watch mode, and lint the code using PNPM. These are essential commands for development and maintaining code quality. ```bash pnpm build pnpm test pnpm test:watch pnpm lint ``` -------------------------------- ### Create and Push Git Tag (Bash) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/RELEASING.md This command creates a Git tag for the release version (prefixed with 'v') and pushes it to the remote repository. Pushing this tag triggers the automated release workflow in GitHub Actions. ```bash # Create version tag (must start with 'v') git tag v2.1.0 # Push tag to trigger release workflow git push origin v2.1.0 ``` -------------------------------- ### Core Module Exports for ts-rust-result Source: https://github.com/jenova-marie/ts-rust-result/blob/main/API.md Lists the core constructors, type guards, utility functions, and types exported from the main '@jenova-marie/ts-rust-result' package. This includes functions for creating `Result` objects, checking their state, extracting values, and transforming them. ```typescript // Core import { ok, err, // Constructors isOk, isErr, // Type guards unwrap, // Extract or throw map, mapErr, // Functional transforms assert, assertOr, assertNotNil, // Assertions tryResult, // Async wrapper type Ok, type Err, type Result // Types } from '@jenova-marie/ts-rust-result' ``` -------------------------------- ### Simplify Zod Validation with fromZodSchema Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/ZOD.md Introduces `fromZodSchema`, a convenience function that combines Zod's `safeParse` and the conversion to a ts-rust-result `Result` in a single step for cleaner validation logic. ```typescript import { fromZodSchema } from '@jenova-marie/ts-rust-result/errors' const ConfigSchema = z.object({ port: z.number().min(1).max(65535), host: z.string(), debug: z.boolean() }) // One-liner validation const result = fromZodSchema(ConfigSchema, rawData) // Result ``` -------------------------------- ### Run Tests (pnpm test) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/DEVELOPMENT.md Executes the test suite for the project. This is a standard command for verifying the correctness of the code during development and before committing changes. ```bash pnpm test ``` -------------------------------- ### Build and Development Commands for ts-rust-result Source: https://github.com/jenova-marie/ts-rust-result/blob/main/CLAUDE.md Provides essential commands for building, developing, and cleaning the TypeScript project. Uses `pnpm` as the package manager. ```bash # Building pnpm build # Compile TypeScript to dist/ pnpm dev # Watch mode compilation pnpm clean # Remove dist/ directory # Testing pnpm test # Run all tests with Vitest pnpm test:watch # Run tests in watch mode pnpm test:coverage # Generate coverage report pnpm test:tsx # Test tsx compatibility (smoke test) # Quality & Documentation pnpm lint # Lint TypeScript files with ESLint pnpm docs # Generate TypeDoc documentation ``` -------------------------------- ### Basic Error Chaining Example Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/ERROR_DESIGN.md Illustrates basic error chaining where a high-level error (`ConfigParseError`) is created with a lower-level error (`FileNotFound`) as its cause, preserving the context of the original failure. ```typescript import { error, fileNotFound } from '@jenova-marie/ts-rust-result/errors' // Inner error (low-level) const innerError = fileNotFound('/app/config.json') // Outer error (high-level) const outerError = error('ConfigParseError') .withMessage('Failed to load application config') .withCause(innerError) .build() // Result: // outerError.cause === innerError // Full error chain preserved! ``` -------------------------------- ### Convert Zod Parse Results to Results (TypeScript) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/README.md Example of converting the outcome of a Zod schema parsing operation into a Result type. This facilitates type-safe validation and error handling within the Result pattern. ```typescript import { Result, Err, Ok } from "@ts-rust-result/core"; import { z, ZodError } from "zod"; const schema = z.object({ name: z.string() }); function parseWithZod(data: unknown): Result<{ name: string }, ZodError> { const parseResult = schema.safeParse(data); if (parseResult.success) { return Ok(parseResult.data); } return Err(parseResult.error); } ``` -------------------------------- ### Type Inference Best Practices with Result in TypeScript Source: https://github.com/jenova-marie/ts-rust-result/blob/main/API.md Illustrates how to leverage TypeScript's type inference to write cleaner code when using the Result type, avoiding explicit generic parameters. It shows the preferred methods for defining return types and handling successful and error outcomes. ```typescript // ❌ Avoid: Explicit generics at return type function bad(): Result { return ok(value) as Result } // ✅ GOOD: Let ok() infer from function return type function good(): Result { return ok(value) // Inferred as Result } // ✅ BEST: Use domain wrappers (no generics at all!) const { ok } = createDomainResult() function best(): ConfigResult { return ok(value) // ✅ Perfect! } // ✅ For err(), be explicit when needed function failure(): Result { return err(myError) } ``` -------------------------------- ### Convert Zod SafeParse Results to ts-rust-result Source: https://github.com/jenova-marie/ts-rust-result/blob/main/content/ZOD.md Shows how to use the `fromZodSafeParse` function to convert Zod's `SafeParseReturnType` into ts-rust-result's `Result` type, providing structured error information. ```typescript import { z } from 'zod' import { fromZodSafeParse } from '@jenova-marie/ts-rust-result/errors' const schema = z.string().email() const zodResult = schema.safeParse('not-an-email') const result = fromZodSafeParse(zodResult) // Result if (!result.ok) { console.log(result.error.kind) // 'SchemaValidation' console.log(result.error.message) // 'Validation failed: 1 issue(s)' console.log(result.error.context.issues) // [ // { // path: [], // message: 'Invalid email' // } // ] } ``` -------------------------------- ### Recommended Pattern: Wrap Third-Party Calls with tryResult Source: https://github.com/jenova-marie/ts-rust-result/blob/main/API.md Highlights the best practice of using 'tryResult' to wrap calls to third-party libraries or external APIs that might throw exceptions. This ensures that all potential errors are converted into the Result type, maintaining a consistent error handling strategy. ```typescript // GOOD: Wrap external code that throws async function fetchRemoteData(): Promise> { return await tryResult(async () => { const response = await fetch('https://api.example.com/data') return await response.json() }) } ``` -------------------------------- ### Core Result Types Definition (TypeScript) Source: https://github.com/jenova-marie/ts-rust-result/blob/main/README.md Defines the basic Result types (Ok, Err, Result) for handling success and error states in TypeScript. This version supports generic error types starting from v2.1.0. ```typescript type Ok = { ok: true; value: T }; type Err = { ok: false; error: E }; type Result = Ok | Err; ```