{"id":15083852,"url":"https://github.com/j3lte/macos-say","last_synced_at":"2026-01-03T00:58:07.222Z","repository":{"id":249718166,"uuid":"832332846","full_name":"j3lte/macos-say","owner":"j3lte","description":"This is a simple module to use the `say` command in MacOS. It is a wrapper around the `say` command, which is a text-to-speech command in MacOS.","archived":false,"fork":false,"pushed_at":"2024-07-22T22:22:26.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-23T10:28:46.843Z","etag":null,"topics":["bun","deno","macos","nodejs","say"],"latest_commit_sha":null,"homepage":"https://jsr.io/@j3lte/macos-say","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/j3lte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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}},"created_at":"2024-07-22T20:04:44.000Z","updated_at":"2024-07-22T22:20:49.000Z","dependencies_parsed_at":"2024-07-23T00:14:27.982Z","dependency_job_id":null,"html_url":"https://github.com/j3lte/macos-say","commit_stats":null,"previous_names":["j3lte/macos-say"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j3lte%2Fmacos-say","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j3lte%2Fmacos-say/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j3lte%2Fmacos-say/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j3lte%2Fmacos-say/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/j3lte","download_url":"https://codeload.github.com/j3lte/macos-say/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243955715,"owners_count":20374372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["bun","deno","macos","nodejs","say"],"created_at":"2024-09-25T07:00:19.392Z","updated_at":"2026-01-03T00:58:07.217Z","avatar_url":"https://github.com/j3lte.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @j3lte/macos-say\n\n[![JSR](https://jsr.io/badges/@j3lte/macos-say)](https://jsr.io/@j3lte/macos-say)\n[![GitHub Release](https://img.shields.io/github/v/release/j3lte/macos-say)](https://github.com/j3lte/macos-say/releases/latest)\n[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/j3lte/macos-say/ci.yml)](https://github.com/j3lte/macos-say/actions)\n\n## Overview\n\nThis is a comprehensive module to use the `say` command in MacOS, which is a [text-to-speech command in MacOS](https://ss64.com/mac/say.html). The library provides a type-safe, feature-rich wrapper with enhanced functionality including voice management, validation, caching, and configuration management.\n\n## Features\n\n- ✅ **Type-safe API** with full TypeScript support\n- ✅ **Voice management** with caching and filtering\n- ✅ **Enhanced error handling** with custom error types\n- ✅ **Configuration management** for saving/loading preferences\n- ✅ **Batch operations** for multiple text-to-speech tasks\n- ✅ **Utility methods** for common operations\n- ✅ **Validation** for voices and options\n- ✅ **Event-driven architecture** (planned)\n\n## Basic Usage\n\n```typescript\nimport { MacOsSay } from '@j3lte/macos-say';\n\n// Create a new instance of MacOsSay\nconst sayer = new MacOsSay();\nconst output = await sayer.say('Hello, World!').exec();\n\n// You can also use a static method\nawait MacOsSay.say('Hello, World!');\n\n// Use options\nconst sayer = new MacOsSay({ voice: 'Daniel', rate: 200 });\nconst output = await sayer.say('Hello, World!').exec();\n\n// Chain options\nconst sayer = new MacOsSay().setVoice('Daniel').setRate(200);\nconst output = await sayer.say('Hello, World!').exec();\n```\n\n## Enhanced Features\n\n### Voice Management\n\n```typescript\n// Get all available voices\nconst voices = await MacOsSay.getVoices();\n\n// Get voices by locale\nconst englishVoices = await MacOsSay.getVoicesByLocale('en_US');\n\n// Get voices by language\nconst frenchVoices = await MacOsSay.getVoicesByLanguage('fr');\n\n// Validate a voice exists\nconst isValid = await MacOsSay.validateVoice('Daniel');\n\n// Set voice with validation\nawait sayer.setVoiceWithValidation('Daniel');\n```\n\n### Error Handling\n\n```typescript\nimport { VoiceNotFoundError, InvalidOptionError } from '@j3lte/macos-say';\n\ntry {\n  await MacOsSay.say('Hello', { voice: 'NonExistentVoice' });\n} catch (error) {\n  if (error instanceof VoiceNotFoundError) {\n    console.log('Voice not found:', error.message);\n  } else if (error instanceof InvalidOptionError) {\n    console.log('Invalid option:', error.message);\n  }\n}\n```\n\n### Configuration Management\n\n```typescript\n// Save configuration\nconst config = {\n  defaultVoice: 'Daniel',\n  defaultRate: 150,\n  defaultQuality: 127,\n  cacheVoices: true,\n  autoValidate: true\n};\n\nawait MacOsSay.saveConfig(config, './macos-say-config.json');\n\n// Load configuration\nconst loadedConfig = await MacOsSay.loadConfig('./macos-say-config.json');\n\n// Create instance from configuration\nconst sayer = await MacOsSay.fromConfig(loadedConfig);\n```\n\n### Batch Operations\n\n```typescript\n// Speak multiple texts with delay\nconst texts = ['Hello', 'World', 'How are you?'];\nconst outputs = await MacOsSay.sayBatch(texts, { voice: 'Daniel' }, 2000);\n\n// Estimate duration\nconst duration = MacOsSay.estimateDuration('This is a test message', 150);\nconsole.log(`Estimated duration: ${duration}ms`);\n```\n\n### Utility Methods\n\n```typescript\n// Stop current speech\nawait MacOsSay.stopSpeech();\n\n// Check if speech is playing\nconst isPlaying = await MacOsSay.isSpeaking();\n\n// Get default system voice\nconst defaultVoice = await MacOsSay.getDefaultVoice();\n\n// Get audio devices\nconst audioDevices = await MacOsSay.getAudioDevices();\n```\n\n### Validation\n\n```typescript\n// Validate all options\nconst validation = await sayer.validateOptions();\nif (!validation.isValid) {\n  console.log('Validation errors:', validation.errors);\n}\n```\n\n## API Reference\n\n### Main Class: `MacOsSay`\n\n#### Constructor\n```typescript\nnew MacOsSay(options?: Partial\u003cNonNullableOptions\u003cOptions\u003e\u003e)\n```\n\n#### Instance Methods\n- `say(text: string, commandOptions?: CommandOptions): MacOsSayOutput`\n- `sayFile(file: string, commandOptions?: CommandOptions): MacOsSayOutput`\n- `setVoice(voice?: string): MacOsSay`\n- `setVoiceWithValidation(voice: string): Promise\u003cMacOsSay\u003e`\n- `setRate(rate?: number): MacOsSay`\n- `setQuality(quality?: number): MacOsSay`\n- `setOutputFile(outputFile?: string): MacOsSay`\n- `setNetwork(network?: string): MacOsSay`\n- `setAudioDeviceID(audioDeviceID?: string): MacOsSay`\n- `setFileFormat(fileFormat?: string): MacOsSay`\n- `validateOptions(): Promise\u003cValidationResult\u003e`\n- `get opts(): Options`\n\n#### Static Methods\n- `say(text: string, options?: Partial\u003cNonNullableOptions\u003cOptions\u003e\u003e): Promise\u003cOutput\u003e`\n- `getVoices(): Promise\u003cVoice[]\u003e`\n- `getVoicesByLocale(locale: string): Promise\u003cVoice[]\u003e`\n- `getVoicesByLanguage(language: string): Promise\u003cVoice[]\u003e`\n- `validateVoice(voiceName: string): Promise\u003cboolean\u003e`\n- `clearVoicesCache(): void`\n- `stopSpeech(): Promise\u003cOutput\u003e`\n- `isSpeaking(): Promise\u003cboolean\u003e`\n- `getAudioDevices(): Promise\u003cstring[]\u003e`\n- `sayBatch(texts: string[], options?: Partial\u003cNonNullableOptions\u003cOptions\u003e\u003e, delayMs?: number): Promise\u003cOutput[]\u003e`\n- `estimateDuration(text: string, rate?: number): number`\n- `getDefaultVoice(): Promise\u003cstring\u003e`\n- `saveConfig(config: MacOsSayConfig, filePath: string): Promise\u003cvoid\u003e`\n- `loadConfig(filePath: string): Promise\u003cMacOsSayConfig\u003e`\n- `fromConfig(config: MacOsSayConfig): Promise\u003cMacOsSay\u003e`\n\n## License\n\n[MIT License](./LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj3lte%2Fmacos-say","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fj3lte%2Fmacos-say","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj3lte%2Fmacos-say/lists"}