sxng-cli 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +102 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +14 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +121 -0
- package/dist/init.js.map +1 -0
- package/dist/protocol.d.ts +23 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +26 -0
- package/dist/protocol.js.map +1 -0
- package/dist/runCli.d.ts +6 -0
- package/dist/runCli.d.ts.map +1 -0
- package/dist/runCli.js +276 -0
- package/dist/runCli.js.map +1 -0
- package/dist/service.d.ts +51 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +127 -0
- package/dist/service.js.map +1 -0
- package/package.json +42 -0
- package/sxng.config.example.json +9 -0
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# SearXNG CLI
|
|
2
|
+
|
|
3
|
+
A command-line interface for searching with SearXNG, a privacy-respecting meta search engine.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g sxng-cli
|
|
9
|
+
# or
|
|
10
|
+
pnpm add -g sxng-cli
|
|
11
|
+
# or
|
|
12
|
+
yarn global add sxng-cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
1. Set up a SearXNG server:
|
|
18
|
+
```bash
|
|
19
|
+
docker run -d --name searxng -p 8080:8080 searxng/searxng
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
2. Create a configuration file:
|
|
23
|
+
```bash
|
|
24
|
+
cp searxng.config.example.json searxng.config.json
|
|
25
|
+
# Edit the file with your settings
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
3. Run a search:
|
|
29
|
+
```bash
|
|
30
|
+
sxng "your search query"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Configuration
|
|
34
|
+
|
|
35
|
+
Configuration can be provided via:
|
|
36
|
+
1. Environment variables (highest priority)
|
|
37
|
+
2. Config file: `./searxng.config.json`
|
|
38
|
+
3. Default values (lowest priority)
|
|
39
|
+
|
|
40
|
+
See `searxng.config.example.json` for an example configuration.
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Simple search
|
|
46
|
+
sxng "TypeScript tutorial"
|
|
47
|
+
|
|
48
|
+
# Limit results
|
|
49
|
+
sxng "TypeScript tutorial" --limit 5
|
|
50
|
+
|
|
51
|
+
# Use specific engines
|
|
52
|
+
sxng --engines google,github "react hooks"
|
|
53
|
+
|
|
54
|
+
# Search in specific categories
|
|
55
|
+
sxng --categories it,science "machine learning"
|
|
56
|
+
|
|
57
|
+
# Recent results only
|
|
58
|
+
sxng --time week "latest news"
|
|
59
|
+
|
|
60
|
+
# Output as CSV
|
|
61
|
+
sxng "docker tutorial" --format csv > results.csv
|
|
62
|
+
|
|
63
|
+
# Check server health
|
|
64
|
+
sxng --health
|
|
65
|
+
|
|
66
|
+
# List available engines
|
|
67
|
+
sxng --engines-list
|
|
68
|
+
|
|
69
|
+
# List available categories
|
|
70
|
+
sxng --categories-list
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Environment Variables
|
|
74
|
+
|
|
75
|
+
| Variable | Description | Default |
|
|
76
|
+
|----------|-------------|---------|
|
|
77
|
+
| `SEARXNG_BASE_URL` | SearXNG server URL | `http://localhost:8080` |
|
|
78
|
+
| `SEARXNG_DEFAULT_LIMIT` | Default result limit | `10` |
|
|
79
|
+
| `SEARXNG_TIMEOUT` | Request timeout in ms | `10000` |
|
|
80
|
+
| `SEARXNG_USE_PROXY` | Use proxy (`true`/`false`) | `false` |
|
|
81
|
+
| `SEARXNG_PROXY_URL` | Proxy URL | (none) |
|
|
82
|
+
|
|
83
|
+
## License
|
|
84
|
+
|
|
85
|
+
MIT
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearXNG CLI - Configuration
|
|
3
|
+
*
|
|
4
|
+
* Configuration priority (highest to lowest):
|
|
5
|
+
* 1. Environment variables
|
|
6
|
+
* 2. Config file (./sxng.config.json)
|
|
7
|
+
* 3. Default values (localhost only)
|
|
8
|
+
*/
|
|
9
|
+
export interface SearXNGConfig {
|
|
10
|
+
baseUrl: string;
|
|
11
|
+
defaultEngine: string;
|
|
12
|
+
allowedEngines: string[];
|
|
13
|
+
defaultLimit: number;
|
|
14
|
+
useProxy: boolean;
|
|
15
|
+
proxyUrl: string;
|
|
16
|
+
timeout: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const config: SearXNGConfig;
|
|
19
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACnB;AAiGD,eAAO,MAAM,MAAM,EAAE,aAA6B,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearXNG CLI - Configuration
|
|
3
|
+
*
|
|
4
|
+
* Configuration priority (highest to lowest):
|
|
5
|
+
* 1. Environment variables
|
|
6
|
+
* 2. Config file (./sxng.config.json)
|
|
7
|
+
* 3. Default values (localhost only)
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, existsSync } from 'fs';
|
|
10
|
+
const DEFAULT_CONFIG = {
|
|
11
|
+
baseUrl: '',
|
|
12
|
+
defaultEngine: '',
|
|
13
|
+
allowedEngines: [],
|
|
14
|
+
defaultLimit: 10,
|
|
15
|
+
useProxy: false,
|
|
16
|
+
proxyUrl: '',
|
|
17
|
+
timeout: 10000
|
|
18
|
+
};
|
|
19
|
+
function readOptionalEnv(name, defaultValue) {
|
|
20
|
+
const value = process.env[name]?.trim();
|
|
21
|
+
return value ? value : defaultValue;
|
|
22
|
+
}
|
|
23
|
+
function readIntEnv(name, defaultValue) {
|
|
24
|
+
const value = process.env[name];
|
|
25
|
+
if (!value)
|
|
26
|
+
return defaultValue;
|
|
27
|
+
const parsed = parseInt(value, 10);
|
|
28
|
+
return Number.isFinite(parsed) ? parsed : defaultValue;
|
|
29
|
+
}
|
|
30
|
+
function readBoolEnv(name, defaultValue) {
|
|
31
|
+
const value = process.env[name];
|
|
32
|
+
if (value === undefined)
|
|
33
|
+
return defaultValue;
|
|
34
|
+
return value === 'true' || value === '1';
|
|
35
|
+
}
|
|
36
|
+
function findConfigFile() {
|
|
37
|
+
const localConfig = './sxng.config.json';
|
|
38
|
+
if (existsSync(localConfig)) {
|
|
39
|
+
return localConfig;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
function loadConfigFile() {
|
|
44
|
+
const configPath = findConfigFile();
|
|
45
|
+
if (!configPath) {
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
50
|
+
const parsed = JSON.parse(content);
|
|
51
|
+
return parsed;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function mergeConfig() {
|
|
58
|
+
const config = { ...DEFAULT_CONFIG };
|
|
59
|
+
const fileConfig = loadConfigFile();
|
|
60
|
+
if (fileConfig.baseUrl !== undefined)
|
|
61
|
+
config.baseUrl = fileConfig.baseUrl;
|
|
62
|
+
if (fileConfig.defaultEngine !== undefined)
|
|
63
|
+
config.defaultEngine = fileConfig.defaultEngine;
|
|
64
|
+
if (fileConfig.allowedEngines !== undefined)
|
|
65
|
+
config.allowedEngines = fileConfig.allowedEngines;
|
|
66
|
+
if (fileConfig.defaultLimit !== undefined)
|
|
67
|
+
config.defaultLimit = fileConfig.defaultLimit;
|
|
68
|
+
if (fileConfig.useProxy !== undefined)
|
|
69
|
+
config.useProxy = fileConfig.useProxy;
|
|
70
|
+
if (fileConfig.proxyUrl !== undefined)
|
|
71
|
+
config.proxyUrl = fileConfig.proxyUrl;
|
|
72
|
+
if (fileConfig.timeout !== undefined)
|
|
73
|
+
config.timeout = fileConfig.timeout;
|
|
74
|
+
const envBaseUrl = readOptionalEnv('SEARXNG_BASE_URL');
|
|
75
|
+
if (envBaseUrl)
|
|
76
|
+
config.baseUrl = envBaseUrl;
|
|
77
|
+
const envDefaultEngine = readOptionalEnv('SEARXNG_DEFAULT_ENGINE');
|
|
78
|
+
if (envDefaultEngine !== undefined)
|
|
79
|
+
config.defaultEngine = envDefaultEngine;
|
|
80
|
+
const envAllowedEngines = process.env.SEARXNG_ALLOWED_ENGINES;
|
|
81
|
+
if (envAllowedEngines !== undefined) {
|
|
82
|
+
config.allowedEngines = envAllowedEngines.split(',').map(e => e.trim()).filter(Boolean);
|
|
83
|
+
}
|
|
84
|
+
const envDefaultLimit = process.env.SEARXNG_DEFAULT_LIMIT;
|
|
85
|
+
if (envDefaultLimit !== undefined) {
|
|
86
|
+
config.defaultLimit = readIntEnv('SEARXNG_DEFAULT_LIMIT', config.defaultLimit);
|
|
87
|
+
}
|
|
88
|
+
const envUseProxy = process.env.SEARXNG_USE_PROXY;
|
|
89
|
+
if (envUseProxy !== undefined) {
|
|
90
|
+
config.useProxy = readBoolEnv('SEARXNG_USE_PROXY', config.useProxy);
|
|
91
|
+
}
|
|
92
|
+
const envProxyUrl = readOptionalEnv('SEARXNG_PROXY_URL');
|
|
93
|
+
if (envProxyUrl)
|
|
94
|
+
config.proxyUrl = envProxyUrl;
|
|
95
|
+
const envTimeout = process.env.SEARXNG_TIMEOUT;
|
|
96
|
+
if (envTimeout !== undefined) {
|
|
97
|
+
config.timeout = readIntEnv('SEARXNG_TIMEOUT', config.timeout);
|
|
98
|
+
}
|
|
99
|
+
return config;
|
|
100
|
+
}
|
|
101
|
+
export const config = mergeConfig();
|
|
102
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;GAEG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* SearXNG CLI - Main Entry Point
|
|
4
|
+
*/
|
|
5
|
+
import { runCli } from './runCli.js';
|
|
6
|
+
import { SearXNGService } from './service.js';
|
|
7
|
+
async function main() {
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
const service = new SearXNGService();
|
|
10
|
+
try {
|
|
11
|
+
const exitCode = await runCli(args, service);
|
|
12
|
+
if (exitCode !== null) {
|
|
13
|
+
process.exit(exitCode);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
console.error(`Fatal error: ${error instanceof Error ? error.message : String(error)}`);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
main();
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,KAAK,UAAU,IAAI;IACf,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,cAAc,EAAE,CAAC;IAErC,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3B,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC"}
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearXNG CLI - Interactive Configuration Setup
|
|
3
|
+
*/
|
|
4
|
+
export interface SearXNGConfig {
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
defaultEngine: string;
|
|
7
|
+
allowedEngines: string[];
|
|
8
|
+
defaultLimit: number;
|
|
9
|
+
useProxy: boolean;
|
|
10
|
+
proxyUrl: string;
|
|
11
|
+
timeout: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function initConfig(): Promise<number>;
|
|
14
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACnB;AAsDD,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAiGlD"}
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearXNG CLI - Interactive Configuration Setup
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
5
|
+
import { resolve } from 'path';
|
|
6
|
+
import readline from 'readline';
|
|
7
|
+
const DEFAULT_CONFIG = {
|
|
8
|
+
baseUrl: 'http://localhost:8080',
|
|
9
|
+
defaultEngine: '',
|
|
10
|
+
allowedEngines: [],
|
|
11
|
+
defaultLimit: 10,
|
|
12
|
+
useProxy: false,
|
|
13
|
+
proxyUrl: '',
|
|
14
|
+
timeout: 10000
|
|
15
|
+
};
|
|
16
|
+
class ConfiguratorInterface {
|
|
17
|
+
rl;
|
|
18
|
+
constructor() {
|
|
19
|
+
this.rl = readline.createInterface({
|
|
20
|
+
input: process.stdin,
|
|
21
|
+
output: process.stdout
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
async question(prompt, defaultValue) {
|
|
25
|
+
return new Promise((resolve) => {
|
|
26
|
+
const displayPrompt = defaultValue ? `${prompt} [${defaultValue}]: ` : `${prompt}: `;
|
|
27
|
+
this.rl.question(displayPrompt, (answer) => {
|
|
28
|
+
resolve(answer.trim() || defaultValue || '');
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async confirm(prompt, defaultValue = true) {
|
|
33
|
+
const answer = await this.question(`${prompt} (${defaultValue ? 'Y/n' : 'y/N'})`, defaultValue ? 'y' : 'n');
|
|
34
|
+
return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
|
|
35
|
+
}
|
|
36
|
+
async multilineInput(prompt) {
|
|
37
|
+
console.log(prompt);
|
|
38
|
+
console.log('(Enter items separated by commas, or press Enter to skip)');
|
|
39
|
+
const input = await this.question('> ');
|
|
40
|
+
return input
|
|
41
|
+
.split(',')
|
|
42
|
+
.map(item => item.trim())
|
|
43
|
+
.filter(item => item.length > 0);
|
|
44
|
+
}
|
|
45
|
+
close() {
|
|
46
|
+
this.rl.close();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export async function initConfig() {
|
|
50
|
+
const configPath = resolve('./sxng.config.json');
|
|
51
|
+
const configurator = new ConfiguratorInterface();
|
|
52
|
+
console.log('\n📝 SearXNG CLI Configuration Setup\n');
|
|
53
|
+
console.log('This will guide you through setting up your SearXNG configuration.\n');
|
|
54
|
+
let config = { ...DEFAULT_CONFIG };
|
|
55
|
+
// Load existing config if available
|
|
56
|
+
if (existsSync(configPath)) {
|
|
57
|
+
const useExisting = await configurator.confirm('Found existing config. Use it as base');
|
|
58
|
+
if (useExisting) {
|
|
59
|
+
try {
|
|
60
|
+
const existing = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
61
|
+
config = { ...DEFAULT_CONFIG, ...existing };
|
|
62
|
+
console.log('✓ Loaded existing configuration\n');
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.log('⚠ Failed to parse existing config, starting fresh\n');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Configure baseUrl
|
|
70
|
+
console.log('--- SearXNG Server Configuration ---');
|
|
71
|
+
config.baseUrl = await configurator.question('SearXNG server URL', config.baseUrl);
|
|
72
|
+
// Configure default engine
|
|
73
|
+
const engineChoice = await configurator.question('Default search engine (leave blank for none)', config.defaultEngine);
|
|
74
|
+
config.defaultEngine = engineChoice;
|
|
75
|
+
// Configure allowed engines
|
|
76
|
+
const allowedEnginesInput = await configurator.multilineInput('Allowed engines (leave blank to allow all)');
|
|
77
|
+
if (allowedEnginesInput.length > 0) {
|
|
78
|
+
config.allowedEngines = allowedEnginesInput;
|
|
79
|
+
}
|
|
80
|
+
// Configure default limit
|
|
81
|
+
console.log('\n--- Result Settings ---');
|
|
82
|
+
const limitStr = await configurator.question('Default result limit', String(config.defaultLimit));
|
|
83
|
+
config.defaultLimit = Math.max(1, parseInt(limitStr, 10) || 10);
|
|
84
|
+
// Configure timeout
|
|
85
|
+
const timeoutStr = await configurator.question('Request timeout (milliseconds)', String(config.timeout));
|
|
86
|
+
config.timeout = Math.max(1000, parseInt(timeoutStr, 10) || 10000);
|
|
87
|
+
// Configure proxy
|
|
88
|
+
console.log('\n--- Proxy Configuration ---');
|
|
89
|
+
const useProxy = await configurator.confirm('Use HTTP proxy', config.useProxy);
|
|
90
|
+
config.useProxy = useProxy;
|
|
91
|
+
if (useProxy) {
|
|
92
|
+
config.proxyUrl = await configurator.question('Proxy URL', config.proxyUrl);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
config.proxyUrl = '';
|
|
96
|
+
}
|
|
97
|
+
// Review and confirm
|
|
98
|
+
console.log('\n--- Configuration Summary ---');
|
|
99
|
+
console.log(JSON.stringify(config, null, 2));
|
|
100
|
+
const confirm = await configurator.confirm('\nSave this configuration');
|
|
101
|
+
configurator.close();
|
|
102
|
+
if (confirm) {
|
|
103
|
+
try {
|
|
104
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
105
|
+
console.log(`\n✓ Configuration saved to ${configPath}`);
|
|
106
|
+
console.log('\n✨ Setup complete! You can now use sxng to search.\n');
|
|
107
|
+
console.log('Try it out:');
|
|
108
|
+
console.log(' sxng "TypeScript tutorial"\n');
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
console.error(`\n✗ Failed to save configuration: ${error instanceof Error ? error.message : String(error)}`);
|
|
113
|
+
return 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
console.log('\n❌ Configuration not saved.');
|
|
118
|
+
return 1;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearXNG CLI - Protocol Definitions
|
|
3
|
+
* Standardized envelope format for CLI communication
|
|
4
|
+
*/
|
|
5
|
+
export type CliEnvelopeError = {
|
|
6
|
+
code: string;
|
|
7
|
+
message: string;
|
|
8
|
+
retryable: boolean;
|
|
9
|
+
details?: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
export type CliEnvelope<T> = {
|
|
12
|
+
status: 'ok' | 'error';
|
|
13
|
+
data: T | null;
|
|
14
|
+
error: CliEnvelopeError | null;
|
|
15
|
+
hint: string | null;
|
|
16
|
+
};
|
|
17
|
+
export declare function createSuccessEnvelope<T>(data: T): CliEnvelope<T>;
|
|
18
|
+
export declare function createErrorEnvelope(code: string, message: string, options?: {
|
|
19
|
+
retryable?: boolean;
|
|
20
|
+
details?: Record<string, unknown>;
|
|
21
|
+
hint?: string | null;
|
|
22
|
+
}): CliEnvelope<null>;
|
|
23
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,gBAAgB,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IACzB,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAOhE;AAED,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACL,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnB,GACP,WAAW,CAAC,IAAI,CAAC,CAYnB"}
|
package/dist/protocol.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearXNG CLI - Protocol Definitions
|
|
3
|
+
* Standardized envelope format for CLI communication
|
|
4
|
+
*/
|
|
5
|
+
export function createSuccessEnvelope(data) {
|
|
6
|
+
return {
|
|
7
|
+
status: 'ok',
|
|
8
|
+
data,
|
|
9
|
+
error: null,
|
|
10
|
+
hint: null
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function createErrorEnvelope(code, message, options = {}) {
|
|
14
|
+
return {
|
|
15
|
+
status: 'error',
|
|
16
|
+
data: null,
|
|
17
|
+
error: {
|
|
18
|
+
code,
|
|
19
|
+
message,
|
|
20
|
+
retryable: options.retryable ?? false,
|
|
21
|
+
details: options.details
|
|
22
|
+
},
|
|
23
|
+
hint: options.hint ?? null
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,MAAM,UAAU,qBAAqB,CAAI,IAAO;IAC5C,OAAO;QACH,MAAM,EAAE,IAAI;QACZ,IAAI;QACJ,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;KACb,CAAC;AACN,CAAC;AAED,MAAM,UAAU,mBAAmB,CAC/B,IAAY,EACZ,OAAe,EACf,UAII,EAAE;IAEN,OAAO;QACH,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE;YACH,IAAI;YACJ,OAAO;YACP,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK;YACrC,OAAO,EAAE,OAAO,CAAC,OAAO;SAC3B;QACD,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;KAC7B,CAAC;AACN,CAAC"}
|
package/dist/runCli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runCli.d.ts","sourceRoot":"","sources":["../src/runCli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAiB,MAAM,cAAc,CAAC;AAgM7D,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsJ5F"}
|
package/dist/runCli.js
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearXNG CLI - CLI Runner
|
|
3
|
+
*/
|
|
4
|
+
import { createSuccessEnvelope, createErrorEnvelope } from './protocol.js';
|
|
5
|
+
import { config } from './config.js';
|
|
6
|
+
import { initConfig } from './init.js';
|
|
7
|
+
const HELP_TEXT = `SearXNG CLI - Web Search Tool
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
sxng <query> [options]
|
|
11
|
+
sxng init
|
|
12
|
+
sxng --engines <engine1,engine2> <query>
|
|
13
|
+
sxng --categories <category> <query>
|
|
14
|
+
sxng --health
|
|
15
|
+
|
|
16
|
+
Commands:
|
|
17
|
+
init Interactive configuration setup
|
|
18
|
+
<query> Perform a web search with the given query
|
|
19
|
+
|
|
20
|
+
Options:
|
|
21
|
+
-e, --engines <engines> Comma-separated list of search engines
|
|
22
|
+
-c, --categories <cats> Comma-separated list of categories
|
|
23
|
+
-l, --limit <n> Maximum number of results (default: ${config.defaultLimit})
|
|
24
|
+
-p, --page <n> Page number for pagination
|
|
25
|
+
--lang <code> Language code (e.g., en, zh, ja)
|
|
26
|
+
--time <range> Time range: day, week, month, year, all
|
|
27
|
+
-f, --format <fmt> Output format: json, csv, html (default: json)
|
|
28
|
+
--engines-list List available search engines
|
|
29
|
+
--categories-list List available categories
|
|
30
|
+
--health Check SearXNG server health
|
|
31
|
+
-h, --help Show this help message
|
|
32
|
+
|
|
33
|
+
Examples:
|
|
34
|
+
sxng init
|
|
35
|
+
sxng "TypeScript tutorial"
|
|
36
|
+
sxng --engines google,github "react hooks"
|
|
37
|
+
sxng --categories it,science "machine learning"
|
|
38
|
+
sxng --limit 5 --time week "latest news"
|
|
39
|
+
|
|
40
|
+
Environment Variables:
|
|
41
|
+
SEARXNG_BASE_URL SearXNG server URL
|
|
42
|
+
SEARXNG_DEFAULT_ENGINE Default search engine
|
|
43
|
+
SEARXNG_ALLOWED_ENGINES Comma-separated allowed engines
|
|
44
|
+
SEARXNG_DEFAULT_LIMIT Default result limit
|
|
45
|
+
SEARXNG_USE_PROXY Use proxy (true/false)
|
|
46
|
+
SEARXNG_PROXY_URL Proxy URL
|
|
47
|
+
SEARXNG_TIMEOUT Request timeout in ms
|
|
48
|
+
`;
|
|
49
|
+
function parseArgs(args) {
|
|
50
|
+
const options = {
|
|
51
|
+
init: false,
|
|
52
|
+
enginesList: false,
|
|
53
|
+
categoriesList: false,
|
|
54
|
+
health: false,
|
|
55
|
+
help: false
|
|
56
|
+
};
|
|
57
|
+
const positional = [];
|
|
58
|
+
for (let i = 0; i < args.length; i++) {
|
|
59
|
+
const arg = args[i];
|
|
60
|
+
switch (arg) {
|
|
61
|
+
case '-h':
|
|
62
|
+
case '--help':
|
|
63
|
+
options.help = true;
|
|
64
|
+
break;
|
|
65
|
+
case 'init':
|
|
66
|
+
options.init = true;
|
|
67
|
+
break;
|
|
68
|
+
case '-e':
|
|
69
|
+
case '--engines':
|
|
70
|
+
options.engines = args[++i]?.split(',').map(e => e.trim()).filter(Boolean);
|
|
71
|
+
break;
|
|
72
|
+
case '-c':
|
|
73
|
+
case '--categories':
|
|
74
|
+
options.categories = args[++i]?.split(',').map(c => c.trim()).filter(Boolean);
|
|
75
|
+
break;
|
|
76
|
+
case '-l':
|
|
77
|
+
case '--limit':
|
|
78
|
+
options.limit = parseInt(args[++i], 10);
|
|
79
|
+
break;
|
|
80
|
+
case '-p':
|
|
81
|
+
case '--page':
|
|
82
|
+
options.page = parseInt(args[++i], 10);
|
|
83
|
+
break;
|
|
84
|
+
case '--lang':
|
|
85
|
+
options.language = args[++i];
|
|
86
|
+
break;
|
|
87
|
+
case '--time':
|
|
88
|
+
const timeVal = args[++i];
|
|
89
|
+
if (['day', 'week', 'month', 'year', 'all'].includes(timeVal)) {
|
|
90
|
+
options.timeRange = timeVal;
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
case '-f':
|
|
94
|
+
case '--format':
|
|
95
|
+
const fmt = args[++i];
|
|
96
|
+
if (['json', 'csv', 'html'].includes(fmt)) {
|
|
97
|
+
options.format = fmt;
|
|
98
|
+
}
|
|
99
|
+
break;
|
|
100
|
+
case '--engines-list':
|
|
101
|
+
options.enginesList = true;
|
|
102
|
+
break;
|
|
103
|
+
case '--categories-list':
|
|
104
|
+
options.categoriesList = true;
|
|
105
|
+
break;
|
|
106
|
+
case '--health':
|
|
107
|
+
options.health = true;
|
|
108
|
+
break;
|
|
109
|
+
default:
|
|
110
|
+
if (!arg.startsWith('-')) {
|
|
111
|
+
positional.push(arg);
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (positional.length > 0) {
|
|
117
|
+
options.query = positional.join(' ');
|
|
118
|
+
}
|
|
119
|
+
return options;
|
|
120
|
+
}
|
|
121
|
+
function formatAsCsv(results) {
|
|
122
|
+
if (results.length === 0)
|
|
123
|
+
return '';
|
|
124
|
+
const headers = ['title', 'url', 'content', 'engine', 'category'];
|
|
125
|
+
const lines = [headers.join(',')];
|
|
126
|
+
for (const r of results) {
|
|
127
|
+
const row = headers.map(h => {
|
|
128
|
+
const val = String(r[h] || '').replace(/"/g, '""');
|
|
129
|
+
return `"${val}"`;
|
|
130
|
+
});
|
|
131
|
+
lines.push(row.join(','));
|
|
132
|
+
}
|
|
133
|
+
return lines.join('\n');
|
|
134
|
+
}
|
|
135
|
+
function formatAsHtml(results) {
|
|
136
|
+
const rows = results.map(r => `
|
|
137
|
+
<tr>
|
|
138
|
+
<td><a href="${r.url}">${r.title}</a></td>
|
|
139
|
+
<td>${r.content}</td>
|
|
140
|
+
<td>${r.engine}</td>
|
|
141
|
+
</tr>
|
|
142
|
+
`).join('');
|
|
143
|
+
return `<!DOCTYPE html>
|
|
144
|
+
<html>
|
|
145
|
+
<head><title>Search Results</title></head>
|
|
146
|
+
<body>
|
|
147
|
+
<table border="1">
|
|
148
|
+
<tr><th>Title</th><th>Content</th><th>Engine</th></tr>
|
|
149
|
+
${rows}
|
|
150
|
+
</table>
|
|
151
|
+
</body>
|
|
152
|
+
</html>`;
|
|
153
|
+
}
|
|
154
|
+
function formatOutput(data, format) {
|
|
155
|
+
switch (format) {
|
|
156
|
+
case 'csv':
|
|
157
|
+
return formatAsCsv(data.results || []);
|
|
158
|
+
case 'html':
|
|
159
|
+
return formatAsHtml(data.results || []);
|
|
160
|
+
case 'json':
|
|
161
|
+
default:
|
|
162
|
+
return JSON.stringify(data, null, 2);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
export async function runCli(args, service) {
|
|
166
|
+
const options = parseArgs(args);
|
|
167
|
+
if (options.help) {
|
|
168
|
+
console.log(HELP_TEXT);
|
|
169
|
+
return 0;
|
|
170
|
+
}
|
|
171
|
+
if (options.init) {
|
|
172
|
+
return await initConfig();
|
|
173
|
+
}
|
|
174
|
+
if (options.health) {
|
|
175
|
+
const health = await service.healthCheck();
|
|
176
|
+
const envelope = health.status === 'healthy'
|
|
177
|
+
? createSuccessEnvelope(health)
|
|
178
|
+
: createErrorEnvelope('HEALTH_CHECK_FAILED', health.error || 'SearXNG server is not responding', { hint: `Check if SearXNG is running at ${config.baseUrl}` });
|
|
179
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
180
|
+
return health.status === 'healthy' ? 0 : 1;
|
|
181
|
+
}
|
|
182
|
+
if (options.enginesList) {
|
|
183
|
+
try {
|
|
184
|
+
const engines = await service.getEngines();
|
|
185
|
+
if (engines.length === 0) {
|
|
186
|
+
const envelope = createErrorEnvelope('ENGINES_FETCH_EMPTY', 'No engines returned from SearXNG server', { hint: 'Check if SearXNG server is properly configured' });
|
|
187
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
188
|
+
return 1;
|
|
189
|
+
}
|
|
190
|
+
const envelope = createSuccessEnvelope({
|
|
191
|
+
engines,
|
|
192
|
+
source: 'server'
|
|
193
|
+
});
|
|
194
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
195
|
+
return 0;
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
const envelope = createErrorEnvelope('ENGINES_FETCH_FAILED', error instanceof Error ? error.message : 'Failed to fetch engines', { hint: 'Check your network connection and SearXNG server status' });
|
|
199
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
200
|
+
return 1;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (options.categoriesList) {
|
|
204
|
+
try {
|
|
205
|
+
const categories = await service.getCategories();
|
|
206
|
+
if (categories.length === 0) {
|
|
207
|
+
const envelope = createErrorEnvelope('CATEGORIES_FETCH_EMPTY', 'No categories returned from SearXNG server', { hint: 'Check if SearXNG server is properly configured' });
|
|
208
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
209
|
+
return 1;
|
|
210
|
+
}
|
|
211
|
+
const envelope = createSuccessEnvelope({
|
|
212
|
+
categories,
|
|
213
|
+
source: 'server'
|
|
214
|
+
});
|
|
215
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
216
|
+
return 0;
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
const envelope = createErrorEnvelope('CATEGORIES_FETCH_FAILED', error instanceof Error ? error.message : 'Failed to fetch categories', { hint: 'Check your network connection and SearXNG server status' });
|
|
220
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
221
|
+
return 1;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (!options.query) {
|
|
225
|
+
const envelope = createErrorEnvelope('MISSING_QUERY', 'No search query provided', { hint: 'Use: sxng "your search query"' });
|
|
226
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
227
|
+
return 1;
|
|
228
|
+
}
|
|
229
|
+
if (options.engines && config.allowedEngines.length > 0) {
|
|
230
|
+
const invalid = options.engines.filter(e => !config.allowedEngines.includes(e));
|
|
231
|
+
if (invalid.length > 0) {
|
|
232
|
+
const envelope = createErrorEnvelope('INVALID_ENGINES', `Engines not allowed: ${invalid.join(', ')}`, { hint: `Allowed engines: ${config.allowedEngines.join(', ')}` });
|
|
233
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
234
|
+
return 1;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const searchOptions = {
|
|
238
|
+
query: options.query,
|
|
239
|
+
engines: options.engines,
|
|
240
|
+
categories: options.categories,
|
|
241
|
+
limit: options.limit ?? config.defaultLimit,
|
|
242
|
+
page: options.page,
|
|
243
|
+
language: options.language,
|
|
244
|
+
timeRange: options.timeRange,
|
|
245
|
+
format: options.format || 'json'
|
|
246
|
+
};
|
|
247
|
+
try {
|
|
248
|
+
const results = await service.search(searchOptions);
|
|
249
|
+
const envelope = createSuccessEnvelope({
|
|
250
|
+
query: results.query,
|
|
251
|
+
totalResults: results.numberOfResults,
|
|
252
|
+
returnedResults: results.results.length,
|
|
253
|
+
results: results.results,
|
|
254
|
+
suggestions: results.suggestions,
|
|
255
|
+
answers: results.answers,
|
|
256
|
+
unresponsiveEngines: results.unresponsiveEngines
|
|
257
|
+
});
|
|
258
|
+
if (options.format && options.format !== 'json') {
|
|
259
|
+
console.error(JSON.stringify(envelope, null, 2));
|
|
260
|
+
console.log(formatOutput(results, options.format));
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
264
|
+
}
|
|
265
|
+
return 0;
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
const envelope = createErrorEnvelope('SEARCH_FAILED', error instanceof Error ? error.message : 'Search request failed', {
|
|
269
|
+
retryable: true,
|
|
270
|
+
hint: 'Check your network connection and SearXNG server status'
|
|
271
|
+
});
|
|
272
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
273
|
+
return 1;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=runCli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runCli.js","sourceRoot":"","sources":["../src/runCli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearXNG CLI - Search Service
|
|
3
|
+
*/
|
|
4
|
+
export interface SearchOptions {
|
|
5
|
+
query: string;
|
|
6
|
+
engines?: string[];
|
|
7
|
+
categories?: string[];
|
|
8
|
+
limit?: number;
|
|
9
|
+
page?: number;
|
|
10
|
+
language?: string;
|
|
11
|
+
timeRange?: 'day' | 'week' | 'month' | 'year' | 'all';
|
|
12
|
+
format?: 'json' | 'csv' | 'html';
|
|
13
|
+
}
|
|
14
|
+
export interface SearchResult {
|
|
15
|
+
title: string;
|
|
16
|
+
url: string;
|
|
17
|
+
content: string;
|
|
18
|
+
engine: string;
|
|
19
|
+
category: string;
|
|
20
|
+
publishedDate?: string;
|
|
21
|
+
thumbnail?: string;
|
|
22
|
+
score?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface SearchResponse {
|
|
25
|
+
query: string;
|
|
26
|
+
numberOfResults: number;
|
|
27
|
+
results: SearchResult[];
|
|
28
|
+
suggestions: string[];
|
|
29
|
+
answers: string[];
|
|
30
|
+
corrections: string[];
|
|
31
|
+
infoboxes: Array<{
|
|
32
|
+
infobox: string;
|
|
33
|
+
content: string;
|
|
34
|
+
engine: string;
|
|
35
|
+
}>;
|
|
36
|
+
unresponsiveEngines: string[];
|
|
37
|
+
}
|
|
38
|
+
export declare class SearXNGService {
|
|
39
|
+
private client;
|
|
40
|
+
constructor();
|
|
41
|
+
getEngines(): Promise<string[]>;
|
|
42
|
+
getCategories(): Promise<string[]>;
|
|
43
|
+
search(options: SearchOptions): Promise<SearchResponse>;
|
|
44
|
+
healthCheck(): Promise<{
|
|
45
|
+
status: 'healthy' | 'unhealthy';
|
|
46
|
+
baseUrl: string;
|
|
47
|
+
engines?: string[];
|
|
48
|
+
error?: string;
|
|
49
|
+
}>;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;IACtD,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,KAAK,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,mBAAmB,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAgB;;IAyBxB,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAa/B,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAWlC,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IA+DvD,WAAW,IAAI,OAAO,CAAC;QACzB,MAAM,EAAE,SAAS,GAAG,WAAW,CAAC;QAChC,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CAiBL"}
|
package/dist/service.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearXNG CLI - Search Service
|
|
3
|
+
*/
|
|
4
|
+
import axios from 'axios';
|
|
5
|
+
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
6
|
+
import { config } from './config.js';
|
|
7
|
+
export class SearXNGService {
|
|
8
|
+
client;
|
|
9
|
+
constructor() {
|
|
10
|
+
const axiosConfig = {
|
|
11
|
+
baseURL: config.baseUrl,
|
|
12
|
+
timeout: config.timeout,
|
|
13
|
+
headers: {
|
|
14
|
+
'Accept': 'application/json',
|
|
15
|
+
'User-Agent': 'searxng-cli/1.0.0'
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
if (config.useProxy && config.proxyUrl) {
|
|
19
|
+
try {
|
|
20
|
+
const proxyAgent = new HttpsProxyAgent(config.proxyUrl);
|
|
21
|
+
axiosConfig.httpsAgent = proxyAgent;
|
|
22
|
+
axiosConfig.httpAgent = proxyAgent;
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
console.error(`Failed to configure proxy: ${error instanceof Error ? error.message : String(error)}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
this.client = axios.create(axiosConfig);
|
|
29
|
+
}
|
|
30
|
+
async getEngines() {
|
|
31
|
+
try {
|
|
32
|
+
const response = await this.client.get('/config');
|
|
33
|
+
const engines = response.data.engines || [];
|
|
34
|
+
return engines
|
|
35
|
+
.filter((e) => e.enabled)
|
|
36
|
+
.map((e) => e.name);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.error(`Failed to fetch engines: ${error instanceof Error ? error.message : String(error)}`);
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async getCategories() {
|
|
44
|
+
try {
|
|
45
|
+
const response = await this.client.get('/config');
|
|
46
|
+
const categories = response.data.categories || [];
|
|
47
|
+
return categories.map((c) => typeof c === 'string' ? c : c?.name).filter(Boolean);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error(`Failed to fetch categories: ${error instanceof Error ? error.message : String(error)}`);
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async search(options) {
|
|
55
|
+
const params = {
|
|
56
|
+
q: options.query,
|
|
57
|
+
format: 'json'
|
|
58
|
+
};
|
|
59
|
+
if (options.engines && options.engines.length > 0) {
|
|
60
|
+
params.engines = options.engines.join(',');
|
|
61
|
+
}
|
|
62
|
+
if (options.categories && options.categories.length > 0) {
|
|
63
|
+
params.categories = options.categories.join(',');
|
|
64
|
+
}
|
|
65
|
+
if (options.language) {
|
|
66
|
+
params.language = options.language;
|
|
67
|
+
}
|
|
68
|
+
if (options.timeRange) {
|
|
69
|
+
params.time_range = options.timeRange;
|
|
70
|
+
}
|
|
71
|
+
if (options.page && options.page > 1) {
|
|
72
|
+
params.pageno = String(options.page);
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const response = await this.client.get('/search', { params });
|
|
76
|
+
const data = response.data;
|
|
77
|
+
const results = (data.results || []).map((item) => ({
|
|
78
|
+
title: item.title || '',
|
|
79
|
+
url: item.url || '',
|
|
80
|
+
content: item.content || item.snippet || '',
|
|
81
|
+
engine: item.engine || 'unknown',
|
|
82
|
+
category: item.category || 'general',
|
|
83
|
+
publishedDate: item.publishedDate,
|
|
84
|
+
thumbnail: item.thumbnail,
|
|
85
|
+
score: item.score
|
|
86
|
+
}));
|
|
87
|
+
const limitedResults = options.limit && options.limit > 0
|
|
88
|
+
? results.slice(0, options.limit)
|
|
89
|
+
: results;
|
|
90
|
+
return {
|
|
91
|
+
query: data.query || options.query,
|
|
92
|
+
numberOfResults: data.numberOfResults || limitedResults.length,
|
|
93
|
+
results: limitedResults,
|
|
94
|
+
suggestions: data.suggestions || [],
|
|
95
|
+
answers: data.answers || [],
|
|
96
|
+
corrections: data.corrections || [],
|
|
97
|
+
infoboxes: data.infoboxes || [],
|
|
98
|
+
unresponsiveEngines: data.unresponsive_engines || []
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (axios.isAxiosError(error)) {
|
|
103
|
+
throw new Error(`Search failed: ${error.response?.statusText || error.message}`);
|
|
104
|
+
}
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async healthCheck() {
|
|
109
|
+
try {
|
|
110
|
+
const response = await this.client.get('/healthz', { timeout: 5000 });
|
|
111
|
+
const engines = await this.getEngines();
|
|
112
|
+
return {
|
|
113
|
+
status: 'healthy',
|
|
114
|
+
baseUrl: config.baseUrl,
|
|
115
|
+
engines
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
return {
|
|
120
|
+
status: 'unhealthy',
|
|
121
|
+
baseUrl: config.baseUrl,
|
|
122
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sxng-cli",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "SearXNG CLI - Web Search Tool",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"sxng": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/",
|
|
13
|
+
"sxng.config.example.json",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc && chmod +x dist/index.js",
|
|
18
|
+
"dev": "tsc --watch",
|
|
19
|
+
"start": "node dist/index.js",
|
|
20
|
+
"prepublishOnly": "npm run build",
|
|
21
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"searxng",
|
|
25
|
+
"search",
|
|
26
|
+
"cli",
|
|
27
|
+
"web-search"
|
|
28
|
+
],
|
|
29
|
+
"author": "",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"axios": "^1.6.0",
|
|
33
|
+
"https-proxy-agent": "^7.0.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^20.0.0",
|
|
37
|
+
"typescript": "^5.3.0"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18.0.0"
|
|
41
|
+
}
|
|
42
|
+
}
|