feat(dictionary): add dictionary search, synonyms, and examples adapters (#241)
* feat(dictionary): add dictionary search, synonyms, and examples adapters * feat: Improve dictionary commands with positional word arguments, URL encoding, enhanced phonetic parsing, and new E2E tests.
This commit is contained in:
@@ -145,6 +145,7 @@ Run `opencli list` for the live registry.
|
||||
| **bloomberg** | `main` `markets` `economics` `industries` `tech` `politics` `businessweek` `opinions` `feeds` `news` | Public / Browser |
|
||||
| **ctrip** | `search` | Browser |
|
||||
| **devto** | `top` `tag` `user` | Public |
|
||||
| **dictionary** | `search` `synonyms` `examples` | Public |
|
||||
| **arxiv** | `search` `paper` | Public |
|
||||
| **wikipedia** | `search` `summary` `random` `trending` | Public |
|
||||
| **hackernews** | `top` `new` `best` `ask` `show` `jobs` `search` `user` | Public |
|
||||
|
||||
@@ -147,6 +147,7 @@ npm install -g @jackwener/opencli@latest
|
||||
| **bloomberg** | `main` `markets` `economics` `industries` `tech` `politics` `businessweek` `opinions` `feeds` `news` | 公共 API / 浏览器 |
|
||||
| **ctrip** | `search` | 浏览器 |
|
||||
| **devto** | `top` `tag` `user` | 公开 |
|
||||
| **dictionary** | `search` `synonyms` `examples` | 公开 |
|
||||
| **arxiv** | `search` `paper` | 公开 |
|
||||
| **wikipedia** | `search` `summary` `random` `trending` | 公开 |
|
||||
| **hackernews** | `top` `new` `best` `ask` `show` `jobs` `search` `user` | 公共 API |
|
||||
|
||||
@@ -81,6 +81,7 @@ export default defineConfig({
|
||||
items: [
|
||||
{ text: 'HackerNews', link: '/adapters/browser/hackernews' },
|
||||
{ text: 'Dev.to', link: '/adapters/browser/devto' },
|
||||
{ text: 'Dictionary', link: '/adapters/browser/dictionary' },
|
||||
{ text: 'BBC', link: '/adapters/browser/bbc' },
|
||||
{ text: 'Apple Podcasts', link: '/adapters/browser/apple-podcasts' },
|
||||
{ text: 'Xiaoyuzhou', link: '/adapters/browser/xiaoyuzhou' },
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# Dictionary
|
||||
|
||||
**Mode**: 🌐 Public · **Domain**: `api.dictionaryapi.dev`
|
||||
|
||||
Search the open dictionary to quickly fetch native definitions, part of speech contexts, and phonetic pronunciations directly in your IDE terminal.
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `opencli dictionary search` | Fetch the exact definition of a word |
|
||||
| `opencli dictionary synonyms` | Find related synonyms for a word |
|
||||
| `opencli dictionary examples` | Read real-world sentence usage examples |
|
||||
|
||||
## Usage Examples
|
||||
|
||||
```bash
|
||||
# Look up a complex term
|
||||
opencli dictionary search serendipity
|
||||
|
||||
# Discover phonetics
|
||||
opencli dictionary search ephemeral
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- No browser required — utilizes the fast, open JSON definitions API.
|
||||
@@ -45,6 +45,7 @@ Run `opencli list` for the live registry.
|
||||
| **[hackernews](/adapters/browser/hackernews)** | `top` `new` `best` `ask` `show` `jobs` `search` `user` | 🌐 Public |
|
||||
| **[bbc](/adapters/browser/bbc)** | `news` | 🌐 Public |
|
||||
| **[devto](/adapters/browser/devto)** | `top` `tag` `user` | 🌐 Public |
|
||||
| **[dictionary](/adapters/browser/dictionary)** | `search` `synonyms` `examples` | 🌐 Public |
|
||||
| **[apple-podcasts](/adapters/browser/apple-podcasts)** | `search` `episodes` `top` | 🌐 Public |
|
||||
| **[xiaoyuzhou](/adapters/browser/xiaoyuzhou)** | `podcast` `podcast-episodes` `episode` | 🌐 Public |
|
||||
| **[yahoo-finance](/adapters/browser/yahoo-finance)** | `quote` | 🌐 Public |
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
site: dictionary
|
||||
name: examples
|
||||
description: Read real-world example sentences utilizing the word
|
||||
domain: api.dictionaryapi.dev
|
||||
strategy: public
|
||||
browser: false
|
||||
|
||||
args:
|
||||
word:
|
||||
type: string
|
||||
required: true
|
||||
positional: true
|
||||
description: Word to get example sentences for
|
||||
|
||||
pipeline:
|
||||
- fetch:
|
||||
url: "https://api.dictionaryapi.dev/api/v2/entries/en/${{ args.word | urlencode }}"
|
||||
|
||||
- map:
|
||||
word: "${{ item.word }}"
|
||||
example: "${{ (() => { if (item.meanings) { for (const m of item.meanings) { if (m.definitions) { for (const d of m.definitions) { if (d.example) return d.example; } } } } return 'No example found in API.'; })() }}"
|
||||
|
||||
- limit: 1
|
||||
|
||||
columns: [word, example]
|
||||
@@ -0,0 +1,27 @@
|
||||
site: dictionary
|
||||
name: search
|
||||
description: Search the Free Dictionary API for definitions, parts of speech, and pronunciations.
|
||||
domain: api.dictionaryapi.dev
|
||||
strategy: public
|
||||
browser: false
|
||||
|
||||
args:
|
||||
word:
|
||||
type: string
|
||||
required: true
|
||||
positional: true
|
||||
description: Word to define (e.g., serendipity)
|
||||
|
||||
pipeline:
|
||||
- fetch:
|
||||
url: "https://api.dictionaryapi.dev/api/v2/entries/en/${{ args.word | urlencode }}"
|
||||
|
||||
- map:
|
||||
word: "${{ item.word }}"
|
||||
phonetic: "${{ (() => { if (item.phonetic) return item.phonetic; if (item.phonetics) { for (const p of item.phonetics) { if (p.text) return p.text; } } return ''; })() }}"
|
||||
type: "${{ item.meanings[0].partOfSpeech }}"
|
||||
definition: "${{ item.meanings[0].definitions[0].definition }}"
|
||||
|
||||
- limit: 1
|
||||
|
||||
columns: [word, phonetic, type, definition]
|
||||
@@ -0,0 +1,25 @@
|
||||
site: dictionary
|
||||
name: synonyms
|
||||
description: Find synonyms for a specific word
|
||||
domain: api.dictionaryapi.dev
|
||||
strategy: public
|
||||
browser: false
|
||||
|
||||
args:
|
||||
word:
|
||||
type: string
|
||||
required: true
|
||||
positional: true
|
||||
description: Word to find synonyms for (e.g., serendipity)
|
||||
|
||||
pipeline:
|
||||
- fetch:
|
||||
url: "https://api.dictionaryapi.dev/api/v2/entries/en/${{ args.word | urlencode }}"
|
||||
|
||||
- map:
|
||||
word: "${{ item.word }}"
|
||||
synonyms: "${{ (() => { const s = new Set(); if (item.meanings) { for (const m of item.meanings) { if (m.synonyms) { for (const syn of m.synonyms) s.add(syn); } if (m.definitions) { for (const d of m.definitions) { if (d.synonyms) { for (const syn of d.synonyms) s.add(syn); } } } } } const arr = Array.from(s); return arr.length > 0 ? arr.slice(0, 5).join(', ') : 'No synonyms found in API.'; })() }}"
|
||||
|
||||
- limit: 1
|
||||
|
||||
columns: [word, synonyms]
|
||||
@@ -489,4 +489,37 @@ describe('public commands E2E', () => {
|
||||
expect(data.length).toBeGreaterThan(0);
|
||||
expect(data.every((d: any) => d.type === 'image')).toBe(true);
|
||||
}, 30_000);
|
||||
|
||||
// ── dictionary (public API, browser: false) ──
|
||||
it('dictionary search returns word definitions', async () => {
|
||||
const { stdout, code } = await runCli(['dictionary', 'search', 'serendipity', '-f', 'json']);
|
||||
expect(code).toBe(0);
|
||||
const data = parseJsonOutput(stdout);
|
||||
expect(Array.isArray(data)).toBe(true);
|
||||
expect(data.length).toBeGreaterThanOrEqual(1);
|
||||
expect(data[0]).toHaveProperty('word', 'serendipity');
|
||||
expect(data[0]).toHaveProperty('phonetic');
|
||||
expect(data[0]).toHaveProperty('definition');
|
||||
}, 30_000);
|
||||
|
||||
it('dictionary synonyms returns synonyms', async () => {
|
||||
const { stdout, code } = await runCli(['dictionary', 'synonyms', 'serendipity', '-f', 'json']);
|
||||
expect(code).toBe(0);
|
||||
const data = parseJsonOutput(stdout);
|
||||
expect(Array.isArray(data)).toBe(true);
|
||||
expect(data.length).toBeGreaterThanOrEqual(1);
|
||||
expect(data[0]).toHaveProperty('word', 'serendipity');
|
||||
expect(data[0]).toHaveProperty('synonyms');
|
||||
}, 30_000);
|
||||
|
||||
it('dictionary examples returns examples', async () => {
|
||||
const { stdout, code } = await runCli(['dictionary', 'examples', 'perfect', '-f', 'json']);
|
||||
expect(code).toBe(0);
|
||||
const data = parseJsonOutput(stdout);
|
||||
expect(Array.isArray(data)).toBe(true);
|
||||
expect(data.length).toBeGreaterThanOrEqual(1);
|
||||
expect(data[0]).toHaveProperty('word', 'perfect');
|
||||
expect(data[0]).toHaveProperty('example');
|
||||
}, 30_000);
|
||||
}, 30_000);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user