@alisio/plugin-web-search 0.1.0
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/LICENSE +21 -0
- package/README.md +61 -0
- package/cover.svg +6 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +166 -0
- package/dist/index.js.map +1 -0
- package/dist/providers.d.ts +18 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +348 -0
- package/dist/providers.js.map +1 -0
- package/dist/validation.d.ts +31 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +143 -0
- package/dist/validation.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Gustavo Gutiérrez Mercado
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# @alisio/plugin-web-search
|
|
2
|
+
|
|
3
|
+
Provider-neutral `web_search` and `web_fetch` tools for [Alisio](https://github.com/GustavoGutierrez/alisio).
|
|
4
|
+
|
|
5
|
+
## Privacy and permissions
|
|
6
|
+
|
|
7
|
+
Both tools have the `external` effect. A search query or fetch URL is sent to the selected remote
|
|
8
|
+
provider; result content is returned only to the current tool call and is not cached or logged by
|
|
9
|
+
this plugin. Keyless Exa MCP access is best-effort and rate-limited. The remote provider may process
|
|
10
|
+
queries, so it is neither confidential nor guaranteed.
|
|
11
|
+
|
|
12
|
+
`web_fetch` is disabled by default. Enable it only in a non-secret profile after considering the
|
|
13
|
+
outbound URL flow. The plugin accepts only public HTTP(S) URLs, rejects credentials, fragments and
|
|
14
|
+
private/reserved network ranges, validates DNS answers, and returns bounded text. It does not use a
|
|
15
|
+
browser, cookies, custom headers, proxies, or direct arbitrary-page scraping.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
alisio install npm:@alisio/plugin-web-search
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The default route is keyless hosted Exa MCP. It requires no API key, but availability is best-effort.
|
|
24
|
+
To configure another route, provide a non-secret `ALISIO_WEB_SEARCH_PROFILE` JSON object and place
|
|
25
|
+
keys in Alisio credentials where the host supports them, or use the named environment fallbacks:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
export ALISIO_WEB_SEARCH_PROFILE='{"providerRoute":"searxng,exaMcp","searxngUrl":"https://search.example.net","enableFetch":false}'
|
|
29
|
+
export BRAVE_SEARCH_API_KEY='…' # or TAVILY_API_KEY, JINA_API_KEY, FIRECRAWL_API_KEY, EXA_API_KEY
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
An explicit comma-separated route is tried strictly in its declared order for search. A request with
|
|
33
|
+
`provider` uses only that provider. No failed request is relayed to an unrelated provider.
|
|
34
|
+
|
|
35
|
+
## Providers
|
|
36
|
+
|
|
37
|
+
| Provider | Search | Fetch | Configuration |
|
|
38
|
+
| --- | --- | --- | --- |
|
|
39
|
+
| Exa MCP | Yes, default | Yes, when `enableFetch` is true | Keyless best-effort hosted MCP |
|
|
40
|
+
| SearXNG | Yes | No | Explicit self-hosted `searxngUrl` |
|
|
41
|
+
| Brave | Yes | No | `BRAVE_SEARCH_API_KEY` or credential |
|
|
42
|
+
| Tavily | Yes | Yes, when `enableFetch` is true | `TAVILY_API_KEY` or credential |
|
|
43
|
+
| Jina | Yes | Yes, when `enableFetch` is true | `JINA_API_KEY` or credential |
|
|
44
|
+
| Firecrawl | Yes | Yes, when `enableFetch` is true | `FIRECRAWL_API_KEY` or credential |
|
|
45
|
+
| Exa API | Yes | No | `EXA_API_KEY` or credential |
|
|
46
|
+
|
|
47
|
+
SearXNG has no public default: choose and operate an instance you trust. The plugin makes no
|
|
48
|
+
unlimited-free claim and deliberately does not scrape unsupported search engines.
|
|
49
|
+
|
|
50
|
+
## Inputs and output
|
|
51
|
+
|
|
52
|
+
`web_search` requires `query` (1–512 characters) and accepts `maxResults` (1–20, default 5),
|
|
53
|
+
`language`, `country`, `safeSearch`, `freshness`, `includeDomains`, `excludeDomains`, and `provider`.
|
|
54
|
+
It returns only normalized source results: title, canonical public URL, optional snippet/date/score/site
|
|
55
|
+
name, and provider identity—never a generated answer or raw provider payload.
|
|
56
|
+
|
|
57
|
+
Node.js **>= 22.16** and an Alisio host with `@alisio/sdk` `>=0.1.0-alpha.10` are required.
|
|
58
|
+
|
|
59
|
+
## License
|
|
60
|
+
|
|
61
|
+
MIT.
|
package/cover.svg
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">Web Search</title><desc id="desc">A search lens connected to a public web grid.</desc>
|
|
3
|
+
<rect width="1600" height="900" fill="#0b1220"/><circle cx="800" cy="430" r="205" fill="none" stroke="#38bdf8" stroke-width="38"/><path d="M950 580l210 210" stroke="#f8fafc" stroke-width="42" stroke-linecap="round"/>
|
|
4
|
+
<path d="M520 170h560M350 430h900M520 690h560M800 170v520M540 250l520 360M1060 250L540 610" stroke="#1e3a5f" stroke-width="8"/>
|
|
5
|
+
<text x="800" y="800" fill="#f8fafc" font-family="sans-serif" font-size="72" font-weight="700" text-anchor="middle">WEB SEARCH</text>
|
|
6
|
+
</svg>
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Plugin, type ToolDefinition } from "@alisio/sdk";
|
|
2
|
+
import { type Settings } from "./providers.js";
|
|
3
|
+
export declare const VERSION = "0.1.0";
|
|
4
|
+
export declare function settings(profile: Record<string, string | boolean | number>, credentials: Record<string, string>): Settings;
|
|
5
|
+
export declare function createTools(config: Settings, fetcher?: typeof fetch): ToolDefinition[];
|
|
6
|
+
export declare function createWebSearchPlugin(): Plugin;
|
|
7
|
+
export { adapters } from "./providers.js";
|
|
8
|
+
export { assertPublicUrl, parsePublicUrl, parseSearchInput } from "./validation.js";
|
|
9
|
+
declare const _default: Plugin;
|
|
10
|
+
export default _default;
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,KAAK,cAAc,EAAmB,MAAM,aAAa,CAAC;AAC9F,OAAO,EAAsB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AASnE,eAAO,MAAM,OAAO,UAAU,CAAC;AAmB/B,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,EAClD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,QAAQ,CAuBV;AACD,wBAAgB,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAE,OAAO,KAAa,GAAG,cAAc,EAAE,CAoG7F;AACD,wBAAgB,qBAAqB,IAAI,MAAM,CAkB9C;AACD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { definePlugin } from "@alisio/sdk";
|
|
2
|
+
import { adapters, markdown } from "./providers.js";
|
|
3
|
+
import { assertPublicUrl, PROVIDERS, parseSearchInput, parseSearxngOrigin, } from "./validation.js";
|
|
4
|
+
export const VERSION = "0.1.0";
|
|
5
|
+
const stringProfile = (profile, key) => typeof profile[key] === "string" ? profile[key].trim() : undefined;
|
|
6
|
+
const credential = (credentials, name, env) => credentials[name] || process.env[env] || undefined;
|
|
7
|
+
const privateCredentials = (credentials) => {
|
|
8
|
+
const values = {};
|
|
9
|
+
for (const [provider, field, env] of [
|
|
10
|
+
["brave", "braveApiKey", "BRAVE_SEARCH_API_KEY"],
|
|
11
|
+
["tavily", "tavilyApiKey", "TAVILY_API_KEY"],
|
|
12
|
+
["jina", "jinaApiKey", "JINA_API_KEY"],
|
|
13
|
+
["firecrawl", "firecrawlApiKey", "FIRECRAWL_API_KEY"],
|
|
14
|
+
["exaApi", "exaApiKey", "EXA_API_KEY"],
|
|
15
|
+
]) {
|
|
16
|
+
const value = credential(credentials, field, env);
|
|
17
|
+
if (value)
|
|
18
|
+
Object.defineProperty(values, provider, { value, enumerable: false });
|
|
19
|
+
}
|
|
20
|
+
return values;
|
|
21
|
+
};
|
|
22
|
+
export function settings(profile, credentials) {
|
|
23
|
+
const rawRoute = stringProfile(profile, "providerRoute") || "exaMcp";
|
|
24
|
+
const route = rawRoute
|
|
25
|
+
.split(",")
|
|
26
|
+
.map((x) => x.trim())
|
|
27
|
+
.filter((x) => PROVIDERS.includes(x));
|
|
28
|
+
if (!route.length ||
|
|
29
|
+
route.length !==
|
|
30
|
+
rawRoute
|
|
31
|
+
.split(",")
|
|
32
|
+
.map((x) => x.trim())
|
|
33
|
+
.filter(Boolean).length)
|
|
34
|
+
throw new Error("providerRoute contains an unsupported provider");
|
|
35
|
+
const searxngUrl = stringProfile(profile, "searxngUrl");
|
|
36
|
+
if (searxngUrl)
|
|
37
|
+
parseSearxngOrigin(searxngUrl);
|
|
38
|
+
return {
|
|
39
|
+
route,
|
|
40
|
+
searxngUrl,
|
|
41
|
+
enableFetch: profile.enableFetch === true,
|
|
42
|
+
credentials: privateCredentials(credentials),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export function createTools(config, fetcher = fetch) {
|
|
46
|
+
const all = adapters(fetcher);
|
|
47
|
+
const search = {
|
|
48
|
+
name: "web_search",
|
|
49
|
+
description: "Search the web with the selected provider. The query and optional filters are sent to that remote provider.",
|
|
50
|
+
effect: "external",
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: "object",
|
|
53
|
+
additionalProperties: false,
|
|
54
|
+
required: ["query"],
|
|
55
|
+
properties: {
|
|
56
|
+
query: { type: "string", minLength: 1, maxLength: 512 },
|
|
57
|
+
maxResults: { type: "integer", minimum: 1, maximum: 20, default: 5 },
|
|
58
|
+
language: { type: "string" },
|
|
59
|
+
country: { type: "string" },
|
|
60
|
+
safeSearch: { type: "boolean" },
|
|
61
|
+
freshness: { type: "string" },
|
|
62
|
+
includeDomains: { type: "array", items: { type: "string" } },
|
|
63
|
+
excludeDomains: { type: "array", items: { type: "string" } },
|
|
64
|
+
provider: { type: "string", enum: PROVIDERS },
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
async execute(input, context) {
|
|
68
|
+
try {
|
|
69
|
+
const parsed = parseSearchInput(input);
|
|
70
|
+
const selected = parsed.provider ? [parsed.provider] : config.route;
|
|
71
|
+
for (const id of selected) {
|
|
72
|
+
const adapter = all[id];
|
|
73
|
+
if (!adapter.active(config)) {
|
|
74
|
+
if (parsed.provider || selected.length === 1)
|
|
75
|
+
throw new Error(`${id} is not configured`);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const results = await adapter.search(parsed, config, context.signal);
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{ type: "text", text: markdown(results) },
|
|
82
|
+
{
|
|
83
|
+
type: "ui",
|
|
84
|
+
block: {
|
|
85
|
+
kind: "table",
|
|
86
|
+
caption: `Web search via ${id}`,
|
|
87
|
+
columns: ["Title", "URL", "Provider"],
|
|
88
|
+
rows: results.map((r) => [r.title, r.url, r.provider]),
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
throw new Error("no configured search provider is available");
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
isError: true,
|
|
99
|
+
content: [
|
|
100
|
+
{ type: "text", text: error instanceof Error ? error.message : "web search failed" },
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
const fetchTool = {
|
|
107
|
+
name: "web_fetch",
|
|
108
|
+
description: "Fetch a public URL through the selected configured provider. The URL is sent to that remote provider; this tool is disabled unless explicitly enabled.",
|
|
109
|
+
effect: "external",
|
|
110
|
+
inputSchema: {
|
|
111
|
+
type: "object",
|
|
112
|
+
additionalProperties: false,
|
|
113
|
+
required: ["url"],
|
|
114
|
+
properties: {
|
|
115
|
+
url: { type: "string", maxLength: 2048 },
|
|
116
|
+
provider: { type: "string", enum: PROVIDERS },
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
async execute(input, context) {
|
|
120
|
+
try {
|
|
121
|
+
if (!config.enableFetch)
|
|
122
|
+
throw new Error("web_fetch is disabled; enableFetch must be set in the non-secret profile");
|
|
123
|
+
const url = await assertPublicUrl(input.url);
|
|
124
|
+
const id = input.provider ?? config.route[0];
|
|
125
|
+
if (!id)
|
|
126
|
+
throw new Error("no configured fetch provider is available");
|
|
127
|
+
const adapter = all[id];
|
|
128
|
+
if (!adapter?.active(config) || !adapter.fetch)
|
|
129
|
+
throw new Error("the selected provider has no policy-compatible fetch capability");
|
|
130
|
+
const text = await adapter.fetch(url, config, context.signal);
|
|
131
|
+
return { content: [{ type: "text", text: text.slice(0, 20_000) }] };
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
return {
|
|
135
|
+
isError: true,
|
|
136
|
+
content: [
|
|
137
|
+
{ type: "text", text: error instanceof Error ? error.message : "web fetch failed" },
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
return [search, fetchTool];
|
|
144
|
+
}
|
|
145
|
+
export function createWebSearchPlugin() {
|
|
146
|
+
return definePlugin({
|
|
147
|
+
id: "web-search",
|
|
148
|
+
name: "Web Search",
|
|
149
|
+
description: "Provider-neutral external web search and opt-in fetch tools",
|
|
150
|
+
categories: ["search", "tools"],
|
|
151
|
+
version: VERSION,
|
|
152
|
+
apiVersion: 1,
|
|
153
|
+
setup(api) {
|
|
154
|
+
const profile = (process.env.ALISIO_WEB_SEARCH_PROFILE
|
|
155
|
+
? JSON.parse(process.env.ALISIO_WEB_SEARCH_PROFILE)
|
|
156
|
+
: {});
|
|
157
|
+
const config = settings(profile, {});
|
|
158
|
+
for (const tool of createTools(config))
|
|
159
|
+
api.tools.register(tool);
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
export { adapters } from "./providers.js";
|
|
164
|
+
export { assertPublicUrl, parsePublicUrl, parseSearchInput } from "./validation.js";
|
|
165
|
+
export default createWebSearchPlugin();
|
|
166
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ProviderId, SearchInput, SearchItem } from "./validation.js";
|
|
2
|
+
export type FetchLike = typeof fetch;
|
|
3
|
+
export type Settings = {
|
|
4
|
+
route: ProviderId[];
|
|
5
|
+
searxngUrl?: string | undefined;
|
|
6
|
+
enableFetch: boolean;
|
|
7
|
+
credentials: Partial<Record<Exclude<ProviderId, "exaMcp" | "searxng">, string | undefined>>;
|
|
8
|
+
};
|
|
9
|
+
export type Adapter = {
|
|
10
|
+
id: ProviderId;
|
|
11
|
+
active(settings: Settings): boolean;
|
|
12
|
+
search(input: SearchInput, settings: Settings, signal: AbortSignal): Promise<SearchItem[]>;
|
|
13
|
+
fetch?(url: URL, settings: Settings, signal: AbortSignal): Promise<string>;
|
|
14
|
+
};
|
|
15
|
+
export declare function adapters(fetcher?: FetchLike): Record<ProviderId, Adapter>;
|
|
16
|
+
export declare function markdown(results: SearchItem[]): string;
|
|
17
|
+
export declare const fetchedText: (value: unknown) => string;
|
|
18
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG3E,MAAM,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC;AACrC,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,GAAG,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;CAC7F,CAAC;AACF,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,UAAU,CAAC;IACf,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC;IACpC,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC3F,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5E,CAAC;AAuDF,wBAAgB,QAAQ,CAAC,OAAO,GAAE,SAAiB,GAAG,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAiXhF;AACD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,UAS7C;AACD,eAAO,MAAM,WAAW,UAAW,OAAO,WAAmC,CAAC"}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { cleanText, item } from "./validation.js";
|
|
2
|
+
const deadline = (signal) => AbortSignal.any([signal, AbortSignal.timeout(12_000)]);
|
|
3
|
+
async function json(fetcher, url, init, signal) {
|
|
4
|
+
const response = await fetcher(url, { ...init, signal: deadline(signal), redirect: "error" });
|
|
5
|
+
if (response.status === 429)
|
|
6
|
+
throw new Error("provider rate limited this request; try again later");
|
|
7
|
+
if (!response.ok)
|
|
8
|
+
throw new Error(response.status >= 500
|
|
9
|
+
? "provider is temporarily unavailable"
|
|
10
|
+
: "provider rejected the request");
|
|
11
|
+
const length = Number(response.headers.get("content-length") ?? 0);
|
|
12
|
+
if (length > 1_048_576)
|
|
13
|
+
throw new Error("provider response is too large");
|
|
14
|
+
return response.json();
|
|
15
|
+
}
|
|
16
|
+
async function readText(fetcher, url, init, signal) {
|
|
17
|
+
const response = await fetcher(url, { ...init, signal: deadline(signal), redirect: "error" });
|
|
18
|
+
if (response.status === 429)
|
|
19
|
+
throw new Error("provider rate limited this request; try again later");
|
|
20
|
+
if (!response.ok)
|
|
21
|
+
throw new Error(response.status >= 500
|
|
22
|
+
? "provider is temporarily unavailable"
|
|
23
|
+
: "provider rejected the request");
|
|
24
|
+
if (Number(response.headers.get("content-length") ?? 0) > 1_048_576)
|
|
25
|
+
throw new Error("provider response is too large");
|
|
26
|
+
const reader = response.body?.getReader();
|
|
27
|
+
if (!reader)
|
|
28
|
+
return "";
|
|
29
|
+
const chunks = [];
|
|
30
|
+
let total = 0;
|
|
31
|
+
while (true) {
|
|
32
|
+
const next = await reader.read();
|
|
33
|
+
if (next.done)
|
|
34
|
+
break;
|
|
35
|
+
total += next.value.byteLength;
|
|
36
|
+
if (total > 1_048_576) {
|
|
37
|
+
await reader.cancel();
|
|
38
|
+
throw new Error("provider response is too large");
|
|
39
|
+
}
|
|
40
|
+
chunks.push(next.value);
|
|
41
|
+
}
|
|
42
|
+
return new TextDecoder().decode(Buffer.concat(chunks));
|
|
43
|
+
}
|
|
44
|
+
const list = (values, provider) => values
|
|
45
|
+
.map((value) => typeof value === "object" && value
|
|
46
|
+
? item(value, provider)
|
|
47
|
+
: undefined)
|
|
48
|
+
.filter((x) => Boolean(x));
|
|
49
|
+
const key = (settings, id) => settings.credentials[id];
|
|
50
|
+
export function adapters(fetcher = fetch) {
|
|
51
|
+
const exaMcp = {
|
|
52
|
+
id: "exaMcp",
|
|
53
|
+
active: () => true,
|
|
54
|
+
async search(input, _settings, signal) {
|
|
55
|
+
const call = async (method, params, session) => {
|
|
56
|
+
const response = await fetcher("https://mcp.exa.ai/mcp", {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: {
|
|
59
|
+
"content-type": "application/json",
|
|
60
|
+
accept: "application/json, text/event-stream",
|
|
61
|
+
...(session ? { "mcp-session-id": session } : {}),
|
|
62
|
+
},
|
|
63
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
|
|
64
|
+
signal: deadline(signal),
|
|
65
|
+
redirect: "error",
|
|
66
|
+
});
|
|
67
|
+
if (response.status === 429)
|
|
68
|
+
throw new Error("provider rate limited this request; try again later");
|
|
69
|
+
if (!response.ok)
|
|
70
|
+
throw new Error(response.status >= 500
|
|
71
|
+
? "provider is temporarily unavailable"
|
|
72
|
+
: "provider protocol request failed");
|
|
73
|
+
if (Number(response.headers.get("content-length") ?? 0) > 1_048_576)
|
|
74
|
+
throw new Error("provider response is too large");
|
|
75
|
+
const body = await response.text();
|
|
76
|
+
const jsonText = response.headers.get("content-type")?.includes("text/event-stream")
|
|
77
|
+
? body
|
|
78
|
+
.split("\n")
|
|
79
|
+
.filter((line) => line.startsWith("data:"))
|
|
80
|
+
.map((line) => line.slice(5).trim())
|
|
81
|
+
.find((line) => line !== "[DONE]")
|
|
82
|
+
: body;
|
|
83
|
+
if (!jsonText)
|
|
84
|
+
throw new Error("provider returned an empty protocol response");
|
|
85
|
+
let data;
|
|
86
|
+
try {
|
|
87
|
+
data = JSON.parse(jsonText);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
throw new Error("provider returned malformed protocol data");
|
|
91
|
+
}
|
|
92
|
+
if (!data ||
|
|
93
|
+
typeof data !== "object" ||
|
|
94
|
+
data.jsonrpc !== "2.0")
|
|
95
|
+
throw new Error("provider returned an incompatible protocol response");
|
|
96
|
+
return {
|
|
97
|
+
data: data,
|
|
98
|
+
session: response.headers.get("mcp-session-id") ?? session,
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
const initialized = await call("initialize", {
|
|
102
|
+
protocolVersion: "2025-03-26",
|
|
103
|
+
capabilities: {},
|
|
104
|
+
clientInfo: { name: "alisio-web-search", version: "0.1.0" },
|
|
105
|
+
});
|
|
106
|
+
const session = initialized.session;
|
|
107
|
+
await call("notifications/initialized", {}, session);
|
|
108
|
+
const tools = (await call("tools/list", {}, session)).data;
|
|
109
|
+
const toolList = tools.result?.tools;
|
|
110
|
+
const found = Array.isArray(toolList) &&
|
|
111
|
+
toolList.some((tool) => typeof tool === "object" &&
|
|
112
|
+
tool !== null &&
|
|
113
|
+
tool.name === "web_search_exa");
|
|
114
|
+
if (!found)
|
|
115
|
+
throw new Error("provider protocol does not offer web search");
|
|
116
|
+
const response = (await call("tools/call", {
|
|
117
|
+
name: "web_search_exa",
|
|
118
|
+
arguments: { query: input.query, numResults: input.maxResults },
|
|
119
|
+
}, session)).data;
|
|
120
|
+
const content = response.result?.content;
|
|
121
|
+
const text = Array.isArray(content)
|
|
122
|
+
? content
|
|
123
|
+
.map((part) => typeof part === "object" && part ? part.text : "")
|
|
124
|
+
.filter((part) => typeof part === "string")
|
|
125
|
+
.join("\n")
|
|
126
|
+
: "";
|
|
127
|
+
try {
|
|
128
|
+
const parsed = JSON.parse(text);
|
|
129
|
+
const results = Array.isArray(parsed)
|
|
130
|
+
? parsed
|
|
131
|
+
: parsed.results;
|
|
132
|
+
return list(Array.isArray(results)
|
|
133
|
+
? results.map((x) => {
|
|
134
|
+
const o = x;
|
|
135
|
+
return {
|
|
136
|
+
title: o.title,
|
|
137
|
+
url: o.url,
|
|
138
|
+
snippet: o.text ?? o.snippet,
|
|
139
|
+
date: o.publishedDate,
|
|
140
|
+
score: o.score,
|
|
141
|
+
};
|
|
142
|
+
})
|
|
143
|
+
: [], "exaMcp").slice(0, input.maxResults);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
throw new Error("provider returned malformed search results");
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
async fetch(url, _settings, signal) {
|
|
150
|
+
let session;
|
|
151
|
+
const call = async (method, params) => {
|
|
152
|
+
const response = await fetcher("https://mcp.exa.ai/mcp", {
|
|
153
|
+
method: "POST",
|
|
154
|
+
headers: {
|
|
155
|
+
"content-type": "application/json",
|
|
156
|
+
accept: "application/json, text/event-stream",
|
|
157
|
+
...(session ? { "mcp-session-id": session } : {}),
|
|
158
|
+
},
|
|
159
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
|
|
160
|
+
signal: deadline(signal),
|
|
161
|
+
redirect: "error",
|
|
162
|
+
});
|
|
163
|
+
if (response.status === 429)
|
|
164
|
+
throw new Error("provider rate limited this request; try again later");
|
|
165
|
+
if (!response.ok)
|
|
166
|
+
throw new Error("provider protocol request failed");
|
|
167
|
+
const body = await response.text();
|
|
168
|
+
const payload = response.headers.get("content-type")?.includes("text/event-stream")
|
|
169
|
+
? body
|
|
170
|
+
.split("\n")
|
|
171
|
+
.find((line) => line.startsWith("data:"))
|
|
172
|
+
?.slice(5)
|
|
173
|
+
.trim()
|
|
174
|
+
: body;
|
|
175
|
+
try {
|
|
176
|
+
const value = JSON.parse(payload ?? "");
|
|
177
|
+
if (value.jsonrpc !== "2.0")
|
|
178
|
+
throw new Error();
|
|
179
|
+
session = response.headers.get("mcp-session-id") ?? session;
|
|
180
|
+
return value;
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
throw new Error("provider returned malformed protocol data");
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
await call("initialize", {
|
|
187
|
+
protocolVersion: "2025-03-26",
|
|
188
|
+
capabilities: {},
|
|
189
|
+
clientInfo: { name: "alisio-web-search", version: "0.1.0" },
|
|
190
|
+
});
|
|
191
|
+
await call("notifications/initialized", {});
|
|
192
|
+
const discovered = await call("tools/list", {});
|
|
193
|
+
const available = discovered.result?.tools;
|
|
194
|
+
if (!Array.isArray(available) ||
|
|
195
|
+
!available.some((entry) => typeof entry === "object" &&
|
|
196
|
+
entry !== null &&
|
|
197
|
+
entry.name === "web_fetch_exa"))
|
|
198
|
+
throw new Error("provider has no policy-compatible fetch capability");
|
|
199
|
+
const result = await call("tools/call", {
|
|
200
|
+
name: "web_fetch_exa",
|
|
201
|
+
arguments: { url: url.toString() },
|
|
202
|
+
});
|
|
203
|
+
const content = result.result?.content;
|
|
204
|
+
const output = cleanText(Array.isArray(content)
|
|
205
|
+
? content
|
|
206
|
+
.map((part) => typeof part === "object" && part ? part.text : "")
|
|
207
|
+
.filter((part) => typeof part === "string")
|
|
208
|
+
.join("\n")
|
|
209
|
+
: "", 20_000);
|
|
210
|
+
if (!output)
|
|
211
|
+
throw new Error("provider returned no valid fetched text");
|
|
212
|
+
return output;
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
const searxng = {
|
|
216
|
+
id: "searxng",
|
|
217
|
+
active: (s) => Boolean(s.searxngUrl),
|
|
218
|
+
async search(input, settings, signal) {
|
|
219
|
+
const url = new URL("/search", settings.searxngUrl);
|
|
220
|
+
url.searchParams.set("q", input.query);
|
|
221
|
+
url.searchParams.set("format", "json");
|
|
222
|
+
url.searchParams.set("pageno", "1");
|
|
223
|
+
if (input.language)
|
|
224
|
+
url.searchParams.set("language", input.language);
|
|
225
|
+
if (input.safeSearch !== undefined)
|
|
226
|
+
url.searchParams.set("safesearch", input.safeSearch ? "1" : "0");
|
|
227
|
+
const data = (await json(fetcher, url.toString(), { headers: { accept: "application/json" } }, signal));
|
|
228
|
+
return list((data.results ?? []).map((x) => {
|
|
229
|
+
const o = x;
|
|
230
|
+
return {
|
|
231
|
+
title: o.title,
|
|
232
|
+
url: o.url,
|
|
233
|
+
snippet: o.content,
|
|
234
|
+
date: o.publishedDate,
|
|
235
|
+
siteName: o.engine,
|
|
236
|
+
};
|
|
237
|
+
}), "searxng").slice(0, input.maxResults);
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
const restful = (id) => ({
|
|
241
|
+
id,
|
|
242
|
+
active: (s) => Boolean(key(s, id)),
|
|
243
|
+
async search(input, settings, signal) {
|
|
244
|
+
const credential = key(settings, id);
|
|
245
|
+
if (!credential)
|
|
246
|
+
throw new Error("provider is not configured");
|
|
247
|
+
let data;
|
|
248
|
+
if (id === "brave") {
|
|
249
|
+
const url = new URL("https://api.search.brave.com/res/v1/web/search");
|
|
250
|
+
url.searchParams.set("q", input.query);
|
|
251
|
+
url.searchParams.set("count", String(input.maxResults));
|
|
252
|
+
if (input.country)
|
|
253
|
+
url.searchParams.set("country", input.country);
|
|
254
|
+
if (input.safeSearch !== undefined)
|
|
255
|
+
url.searchParams.set("safesearch", input.safeSearch ? "strict" : "off");
|
|
256
|
+
data = await json(fetcher, url.toString(), { headers: { accept: "application/json", "x-subscription-token": credential } }, signal);
|
|
257
|
+
return list((data.web?.results ?? []).map((x) => {
|
|
258
|
+
const o = x;
|
|
259
|
+
return { title: o.title, url: o.url, snippet: o.description, date: o.age };
|
|
260
|
+
}), id).slice(0, input.maxResults);
|
|
261
|
+
}
|
|
262
|
+
if (id === "tavily")
|
|
263
|
+
data = await json(fetcher, "https://api.tavily.com/search", {
|
|
264
|
+
method: "POST",
|
|
265
|
+
headers: { "content-type": "application/json" },
|
|
266
|
+
body: JSON.stringify({
|
|
267
|
+
api_key: credential,
|
|
268
|
+
query: input.query,
|
|
269
|
+
max_results: input.maxResults,
|
|
270
|
+
search_depth: "basic",
|
|
271
|
+
}),
|
|
272
|
+
}, signal);
|
|
273
|
+
else if (id === "firecrawl")
|
|
274
|
+
data = await json(fetcher, "https://api.firecrawl.dev/v2/search", {
|
|
275
|
+
method: "POST",
|
|
276
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${credential}` },
|
|
277
|
+
body: JSON.stringify({ query: input.query, limit: input.maxResults }),
|
|
278
|
+
}, signal);
|
|
279
|
+
else if (id === "exaApi")
|
|
280
|
+
data = await json(fetcher, "https://api.exa.ai/search", {
|
|
281
|
+
method: "POST",
|
|
282
|
+
headers: { "content-type": "application/json", "x-api-key": credential },
|
|
283
|
+
body: JSON.stringify({ query: input.query, numResults: input.maxResults }),
|
|
284
|
+
}, signal);
|
|
285
|
+
else
|
|
286
|
+
data = await json(fetcher, `https://s.jina.ai/?q=${encodeURIComponent(input.query)}`, { headers: { authorization: `Bearer ${credential}`, accept: "application/json" } }, signal);
|
|
287
|
+
const root = data;
|
|
288
|
+
return list((root.results ?? root.data ?? []).map((x) => {
|
|
289
|
+
const o = x;
|
|
290
|
+
return {
|
|
291
|
+
title: o.title ?? o.name,
|
|
292
|
+
url: o.url ?? o.link,
|
|
293
|
+
snippet: o.content ?? o.snippet ?? o.text,
|
|
294
|
+
date: o.published_date,
|
|
295
|
+
score: o.score,
|
|
296
|
+
};
|
|
297
|
+
}), id).slice(0, input.maxResults);
|
|
298
|
+
},
|
|
299
|
+
async fetch(url, settings, signal) {
|
|
300
|
+
const credential = key(settings, id);
|
|
301
|
+
if (!credential || !["tavily", "jina", "firecrawl"].includes(id))
|
|
302
|
+
throw new Error("the selected provider has no policy-compatible fetch capability");
|
|
303
|
+
let data;
|
|
304
|
+
if (id === "tavily")
|
|
305
|
+
data = await json(fetcher, "https://api.tavily.com/extract", {
|
|
306
|
+
method: "POST",
|
|
307
|
+
headers: { "content-type": "application/json" },
|
|
308
|
+
body: JSON.stringify({ api_key: credential, urls: [url.toString()] }),
|
|
309
|
+
}, signal);
|
|
310
|
+
else if (id === "firecrawl")
|
|
311
|
+
data = await json(fetcher, "https://api.firecrawl.dev/v2/scrape", {
|
|
312
|
+
method: "POST",
|
|
313
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${credential}` },
|
|
314
|
+
body: JSON.stringify({ url: url.toString(), formats: ["markdown"] }),
|
|
315
|
+
}, signal);
|
|
316
|
+
else
|
|
317
|
+
data = {
|
|
318
|
+
content: await readText(fetcher, `https://r.jina.ai/${url.toString()}`, { headers: { authorization: `Bearer ${credential}`, accept: "text/plain" } }, signal),
|
|
319
|
+
};
|
|
320
|
+
const root = data;
|
|
321
|
+
const text = id === "tavily"
|
|
322
|
+
? root.results?.[0]?.raw_content
|
|
323
|
+
: id === "firecrawl"
|
|
324
|
+
? (root.data?.markdown ?? root.data?.content)
|
|
325
|
+
: root.content;
|
|
326
|
+
const output = cleanText(text, 20_000);
|
|
327
|
+
if (!output)
|
|
328
|
+
throw new Error("provider returned no valid fetched text");
|
|
329
|
+
return output;
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
return {
|
|
333
|
+
exaMcp,
|
|
334
|
+
searxng,
|
|
335
|
+
brave: restful("brave"),
|
|
336
|
+
tavily: restful("tavily"),
|
|
337
|
+
jina: restful("jina"),
|
|
338
|
+
firecrawl: restful("firecrawl"),
|
|
339
|
+
exaApi: restful("exaApi"),
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
export function markdown(results) {
|
|
343
|
+
return (results
|
|
344
|
+
.map((r, i) => `${i + 1}. [${r.title}](${r.url})${r.snippet ? ` — ${r.snippet}` : ""}\n Provider: ${r.provider}`)
|
|
345
|
+
.join("\n\n") || "No valid public results were returned.");
|
|
346
|
+
}
|
|
347
|
+
export const fetchedText = (value) => cleanText(value, 20_000) ?? "";
|
|
348
|
+
//# sourceMappingURL=providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { lookup } from "node:dns/promises";
|
|
2
|
+
export declare const PROVIDERS: readonly ["exaMcp", "searxng", "brave", "tavily", "jina", "firecrawl", "exaApi"];
|
|
3
|
+
export type ProviderId = (typeof PROVIDERS)[number];
|
|
4
|
+
export type SearchInput = {
|
|
5
|
+
query: string;
|
|
6
|
+
maxResults: number;
|
|
7
|
+
language?: string | undefined;
|
|
8
|
+
country?: string | undefined;
|
|
9
|
+
safeSearch?: boolean | undefined;
|
|
10
|
+
freshness?: string | undefined;
|
|
11
|
+
includeDomains: string[];
|
|
12
|
+
excludeDomains: string[];
|
|
13
|
+
provider?: ProviderId | undefined;
|
|
14
|
+
};
|
|
15
|
+
export type SearchItem = {
|
|
16
|
+
title: string;
|
|
17
|
+
url: string;
|
|
18
|
+
snippet?: string | undefined;
|
|
19
|
+
date?: string | undefined;
|
|
20
|
+
score?: number | undefined;
|
|
21
|
+
siteName?: string | undefined;
|
|
22
|
+
provider: ProviderId;
|
|
23
|
+
};
|
|
24
|
+
export declare function parseSearchInput(value: Record<string, unknown>): SearchInput;
|
|
25
|
+
export declare function assertPublicAddress(address: string): void;
|
|
26
|
+
export declare function parsePublicUrl(value: unknown): URL;
|
|
27
|
+
export declare function parseSearxngOrigin(value: unknown): URL;
|
|
28
|
+
export declare function assertPublicUrl(value: unknown, resolve?: typeof lookup): Promise<URL>;
|
|
29
|
+
export declare function cleanText(value: unknown, maximum?: number): string | undefined;
|
|
30
|
+
export declare function item(value: Record<string, unknown>, provider: ProviderId): SearchItem | undefined;
|
|
31
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,eAAO,MAAM,SAAS,YACpB,QAAQ,EACR,SAAS,EACT,OAAO,EACP,QAAQ,EACR,MAAM,EACN,WAAW,EACX,QAAQ,CACA,CAAC;AACX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AACpD,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACnC,CAAC;AACF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,UAAU,CAAC;CACtB,CAAC;AAeF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,CAgC5E;AAOD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,QAGlD;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAelD;AACD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAoBtD;AACD,wBAAsB,eAAe,CACnC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,OAAO,MAAe,GAC9B,OAAO,CAAC,GAAG,CAAC,CASd;AACD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,SAAO,sBAQvD;AACD,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAmBjG"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { lookup } from "node:dns/promises";
|
|
2
|
+
import { isIP } from "node:net";
|
|
3
|
+
export const PROVIDERS = [
|
|
4
|
+
"exaMcp",
|
|
5
|
+
"searxng",
|
|
6
|
+
"brave",
|
|
7
|
+
"tavily",
|
|
8
|
+
"jina",
|
|
9
|
+
"firecrawl",
|
|
10
|
+
"exaApi",
|
|
11
|
+
];
|
|
12
|
+
const bounded = (value, max) => typeof value === "string" && value.length <= max ? value.trim() : undefined;
|
|
13
|
+
const domainList = (value, label) => {
|
|
14
|
+
if (value === undefined)
|
|
15
|
+
return [];
|
|
16
|
+
if (!Array.isArray(value) || value.length > 30)
|
|
17
|
+
throw new Error(`${label} must contain at most 30 domains`);
|
|
18
|
+
return value.map((item) => {
|
|
19
|
+
const domain = bounded(item, 253)?.toLowerCase();
|
|
20
|
+
if (!domain || !/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/.test(domain))
|
|
21
|
+
throw new Error(`${label} contains an invalid domain`);
|
|
22
|
+
return domain;
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
export function parseSearchInput(value) {
|
|
26
|
+
const query = bounded(value.query, 512);
|
|
27
|
+
if (!query || query.length < 1)
|
|
28
|
+
throw new Error("query must be 1 to 512 characters");
|
|
29
|
+
const maxResults = value.maxResults === undefined ? 5 : value.maxResults;
|
|
30
|
+
if (!Number.isInteger(maxResults) || maxResults < 1 || maxResults > 20)
|
|
31
|
+
throw new Error("maxResults must be an integer from 1 to 20");
|
|
32
|
+
const provider = value.provider;
|
|
33
|
+
if (provider !== undefined && !PROVIDERS.includes(provider))
|
|
34
|
+
throw new Error("provider is not supported");
|
|
35
|
+
const language = value.language === undefined ? undefined : bounded(value.language, 35);
|
|
36
|
+
const country = value.country === undefined ? undefined : bounded(value.country, 3)?.toUpperCase();
|
|
37
|
+
const freshness = value.freshness === undefined ? undefined : bounded(value.freshness, 32);
|
|
38
|
+
if ((value.language !== undefined && !language) ||
|
|
39
|
+
(value.country !== undefined && !/^[A-Z]{2}$/.test(country ?? "")) ||
|
|
40
|
+
(value.freshness !== undefined && !freshness))
|
|
41
|
+
throw new Error("a search filter is invalid");
|
|
42
|
+
if (value.safeSearch !== undefined && typeof value.safeSearch !== "boolean")
|
|
43
|
+
throw new Error("safeSearch must be a boolean");
|
|
44
|
+
return {
|
|
45
|
+
query,
|
|
46
|
+
maxResults: maxResults,
|
|
47
|
+
language,
|
|
48
|
+
country,
|
|
49
|
+
safeSearch: value.safeSearch,
|
|
50
|
+
freshness,
|
|
51
|
+
includeDomains: domainList(value.includeDomains, "includeDomains"),
|
|
52
|
+
excludeDomains: domainList(value.excludeDomains, "excludeDomains"),
|
|
53
|
+
provider: provider,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const unsafeV4 = (ip) => /^(0|10|127|169\.254|172\.(1[6-9]|2\d|3[01])|192\.168|100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])|198\.(1[89]|5[01])|2(?:2[4-9]|3\d)|240)\./.test(ip);
|
|
57
|
+
const unsafeV6 = (ip) => ip === "::1" || /^(?:fc|fd|fe[89ab]|ff)/i.test(ip) || ip === "::";
|
|
58
|
+
export function assertPublicAddress(address) {
|
|
59
|
+
if ((isIP(address) === 4 && unsafeV4(address)) || (isIP(address) === 6 && unsafeV6(address)))
|
|
60
|
+
throw new Error("URL resolves to a non-public address");
|
|
61
|
+
}
|
|
62
|
+
export function parsePublicUrl(value) {
|
|
63
|
+
if (typeof value !== "string" || value.length > 2048)
|
|
64
|
+
throw new Error("URL is invalid");
|
|
65
|
+
let url;
|
|
66
|
+
try {
|
|
67
|
+
url = new URL(value);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new Error("URL is invalid");
|
|
71
|
+
}
|
|
72
|
+
if (!/^https?:$/.test(url.protocol) || url.username || url.password || url.hash || !url.hostname)
|
|
73
|
+
throw new Error("URL is not an allowed public HTTP URL");
|
|
74
|
+
if (url.hostname === "localhost" || url.hostname.endsWith(".localhost"))
|
|
75
|
+
throw new Error("URL is not public");
|
|
76
|
+
const host = url.hostname.replace(/^\[|\]$/g, "");
|
|
77
|
+
if (isIP(host))
|
|
78
|
+
assertPublicAddress(host);
|
|
79
|
+
return url;
|
|
80
|
+
}
|
|
81
|
+
export function parseSearxngOrigin(value) {
|
|
82
|
+
if (typeof value !== "string")
|
|
83
|
+
throw new Error("searxngUrl is invalid");
|
|
84
|
+
let url;
|
|
85
|
+
try {
|
|
86
|
+
url = new URL(value);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
throw new Error("searxngUrl is invalid");
|
|
90
|
+
}
|
|
91
|
+
const loopback = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "::1";
|
|
92
|
+
if (url.username ||
|
|
93
|
+
url.password ||
|
|
94
|
+
url.pathname !== "/" ||
|
|
95
|
+
url.search ||
|
|
96
|
+
url.hash ||
|
|
97
|
+
(url.protocol !== "https:" && !(url.protocol === "http:" && loopback)))
|
|
98
|
+
throw new Error("searxngUrl must be HTTPS, or HTTP loopback");
|
|
99
|
+
return url;
|
|
100
|
+
}
|
|
101
|
+
export async function assertPublicUrl(value, resolve = lookup) {
|
|
102
|
+
const url = parsePublicUrl(value);
|
|
103
|
+
const host = url.hostname.replace(/^\[|\]$/g, "");
|
|
104
|
+
if (!isIP(host)) {
|
|
105
|
+
const records = await resolve(host, { all: true, verbatim: true });
|
|
106
|
+
if (!records.length)
|
|
107
|
+
throw new Error("URL has no public address");
|
|
108
|
+
for (const record of records)
|
|
109
|
+
assertPublicAddress(record.address);
|
|
110
|
+
}
|
|
111
|
+
return url;
|
|
112
|
+
}
|
|
113
|
+
export function cleanText(value, maximum = 2000) {
|
|
114
|
+
return typeof value === "string"
|
|
115
|
+
? [...value]
|
|
116
|
+
.map((character) => ((character.codePointAt(0) ?? 32) < 32 ? " " : character))
|
|
117
|
+
.join("")
|
|
118
|
+
.trim()
|
|
119
|
+
.slice(0, maximum)
|
|
120
|
+
: undefined;
|
|
121
|
+
}
|
|
122
|
+
export function item(value, provider) {
|
|
123
|
+
try {
|
|
124
|
+
const url = parsePublicUrl(value.url).toString();
|
|
125
|
+
const title = cleanText(value.title, 300);
|
|
126
|
+
if (!title)
|
|
127
|
+
return undefined;
|
|
128
|
+
const score = typeof value.score === "number" && Number.isFinite(value.score) ? value.score : undefined;
|
|
129
|
+
return {
|
|
130
|
+
title,
|
|
131
|
+
url,
|
|
132
|
+
snippet: cleanText(value.snippet),
|
|
133
|
+
date: cleanText(value.date, 80),
|
|
134
|
+
score,
|
|
135
|
+
siteName: cleanText(value.siteName, 160),
|
|
136
|
+
provider,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,QAAQ;IACR,SAAS;IACT,OAAO;IACP,QAAQ;IACR,MAAM;IACN,WAAW;IACX,QAAQ;CACA,CAAC;AAuBX,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,GAAW,EAAE,EAAE,CAC9C,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9E,MAAM,UAAU,GAAG,CAAC,KAAc,EAAE,KAAa,EAAE,EAAE;IACnD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAC5C,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,kCAAkC,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,CAAC;QACjD,IAAI,CAAC,MAAM,IAAI,CAAC,0DAA0D,CAAC,IAAI,CAAC,MAAM,CAAC;YACrF,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,6BAA6B,CAAC,CAAC;QACzD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AACF,MAAM,UAAU,gBAAgB,CAAC,KAA8B;IAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACrF,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;IACzE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAK,UAAqB,GAAG,CAAC,IAAK,UAAqB,GAAG,EAAE;QAC5F,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAsB,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACxF,MAAM,OAAO,GACX,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IACrF,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC3F,IACE,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC;QAC3C,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC;QAE7C,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,SAAS;QACzE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,OAAO;QACL,KAAK;QACL,UAAU,EAAE,UAAoB;QAChC,QAAQ;QACR,OAAO;QACP,UAAU,EAAE,KAAK,CAAC,UAAiC;QACnD,SAAS;QACT,cAAc,EAAE,UAAU,CAAC,KAAK,CAAC,cAAc,EAAE,gBAAgB,CAAC;QAClE,cAAc,EAAE,UAAU,CAAC,KAAK,CAAC,cAAc,EAAE,gBAAgB,CAAC;QAClE,QAAQ,EAAE,QAAkC;KAC7C,CAAC;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAE,EAAE,CAC9B,sIAAsI,CAAC,IAAI,CACzI,EAAE,CACH,CAAC;AACJ,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,EAAE,KAAK,KAAK,IAAI,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC;AACnG,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1F,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;AAC5D,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACxF,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ;QAC9F,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAClD,IAAI,IAAI,CAAC,IAAI,CAAC;QAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,GAAG,CAAC;AACb,CAAC;AACD,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACxE,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,QAAQ,GACZ,GAAG,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,CAAC;IACzF,IACE,GAAG,CAAC,QAAQ;QACZ,GAAG,CAAC,QAAQ;QACZ,GAAG,CAAC,QAAQ,KAAK,GAAG;QACpB,GAAG,CAAC,MAAM;QACV,GAAG,CAAC,IAAI;QACR,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,CAAC;QAEtE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,OAAO,GAAG,CAAC;AACb,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAc,EACd,OAAO,GAAkB,MAAM;IAE/B,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAClE,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AACD,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,OAAO,GAAG,IAAI;IACtD,OAAO,OAAO,KAAK,KAAK,QAAQ;QAC9B,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;aACP,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;aAC7E,IAAI,CAAC,EAAE,CAAC;aACR,IAAI,EAAE;aACN,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC;QACtB,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AACD,MAAM,UAAU,IAAI,CAAC,KAA8B,EAAE,QAAoB;IACvE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,MAAM,KAAK,GACT,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5F,OAAO;YACL,KAAK;YACL,GAAG;YACH,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;YACjC,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/B,KAAK;YACL,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC;YACxC,QAAQ;SACT,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@alisio/plugin-web-search",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Privacy-conscious, provider-neutral web search tools for Alisio.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"alisio-plugin",
|
|
7
|
+
"web-search",
|
|
8
|
+
"search",
|
|
9
|
+
"tools"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/GustavoGutierrez/alisio-plugins.git",
|
|
15
|
+
"directory": "packages/plugin-web-search"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/GustavoGutierrez/alisio-plugins/tree/main/packages/plugin-web-search#readme",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/GustavoGutierrez/alisio-plugins/issues"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=22.16"
|
|
24
|
+
},
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE",
|
|
35
|
+
"cover.svg"
|
|
36
|
+
],
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@alisio/sdk": ">=0.1.0-alpha.10 <0.2.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@alisio/sdk": "0.1.0-alpha.11",
|
|
42
|
+
"typescript": "7.0.2",
|
|
43
|
+
"vitest": "5.0.1"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsc -p tsconfig.json",
|
|
47
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
48
|
+
"test": "vitest run"
|
|
49
|
+
}
|
|
50
|
+
}
|