Back to packages list

Vals using ky

Description from the NPM package:
Tiny and elegant HTTP client based on the browser Fetch API

Google Feeling Lucky auto-redirect !lucky

DuckDuckGo !Bangs offer the following shortcuts for Google's Feeling Lucky (going straight to the first result) search option:

Unfortunately, they don't work anymore due to redirect notices that get shown. This service enables you to skip redirect notice by altering your search from the original query e.g.:
https://www.google.com/search?q=site:developer.mozilla.org+Object.hasOwn&btnI

To the modified one made against this val's HTTP endpoint:
https://vladimyr-googlefeelinglucky.web.val.run/?q=site:developer.mozilla.org+Object.hasOwn

Additionally, you can define custom search shortcut inside your browser to allow a local bang-like experience:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import { DOMParser, Element, initParser } from "https://deno.land/x/deno_dom/deno-dom-wasm-noinit.ts";
import ky from "npm:ky";
const DEFAULT_USER_AGENT =
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36";
export default async function(req: Request): Promise<Response> {
const { searchParams } = new URL(req.url);
const query = searchParams.get("q");
if (!query) return Response.redirect("https://www.google.com");
try {
const resultUrl = await search(query);
return Response.redirect(resultUrl);
} catch {
return Response.redirect("https://www.google.com");
}
}
export function search(query: string, userAgent = DEFAULT_USER_AGENT) {
const searchUrl = createSearchUrl(query);
return getRedirectUrl(searchUrl, userAgent);
}
export function createSearchUrl(query: string, buttonName = "") {
const searchURL = new URL("https://www.google.com/search");
searchURL.searchParams.set("q", query);
searchURL.searchParams.set("btnI", buttonName);
return searchURL.href;
}
export async function getRedirectUrl(searchUrl: string | URL, userAgent = DEFAULT_USER_AGENT) {
const resp = await ky.get(searchUrl, { headers: { "user-agent": userAgent } });
const { searchParams } = new URL(resp.url);
const redirectURL = new URL(searchParams.get("q"));
return redirectURL.href;
}
export async function signSearchUrl(searchUrl: string | URL) {
const signedURL = new URL(searchUrl);
const params = await getSearchParams();
Object.entries(params).forEach(([name, value]) => signedURL.searchParams.set(name, String(value)));
return signedURL.href;
}
export async function getSearchParams(userAgent = DEFAULT_USER_AGENT) {
await initParser();
const html = await ky.get("https://www.google.com", { headers: { "user-agent": userAgent } }).text();
const doc = new DOMParser().parseFromString(html, "text/html");
const inputs: Array<Element> = Array.from(doc.querySelectorAll("form input[type=hidden]"));
const entries = inputs.map((input) => [input.getAttribute("name"), input.getAttribute("value")]);
return Object.fromEntries(entries);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { jwkToDidKey } from "https://esm.town/v/vladimyr/jwkToDidKey";
import ky from "npm:ky";
let jwk, did, resolvedJwk;
// @see: https://w3c-ccg.github.io/did-method-key/#example-5
jwk = {
kty: "OKP",
crv: "Ed25519",
x: "O2onvM62pC1io6jQKm8Nc2UyFXcd4kOmOsBIoYtZ2ik",
} as const;
did = jwkToDidKey(jwk);
console.log(did);
console.assert(did === "did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp");
resolvedJwk = await resolveDid(did);
console.log(JSON.stringify(resolvedJwk));
console.assert(jwk.kty === resolvedJwk.kty);
console.assert(jwk.crv === resolvedJwk.crv);
console.assert(jwk.x === resolvedJwk.x);
if (jwk.y) console.assert(jwk.y === resolvedJwk.y);
jwk = {
kty: "OKP",
crv: "Ed25519",
x: "TLWr9q15-_WrvMr8wmnYXNJlHtS4hbWGnyQa7fCluik",
} as const;
did = jwkToDidKey(jwk);
console.log(did);
console.assert(did === "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG");
resolvedJwk = await resolveDid(did);
console.log(JSON.stringify(resolvedJwk));
console.assert(jwk.kty === resolvedJwk.kty);
console.assert(jwk.crv === resolvedJwk.crv);
console.assert(jwk.x === resolvedJwk.x);
if (jwk.y) console.assert(jwk.y === resolvedJwk.y);
jwk = {
kty: "OKP",
crv: "Ed25519",
x: "dCK5iHWYBo4yxESKlJrbKQ0PTjW54BsO5fGh5gD-JnQ",
} as const;
did = jwkToDidKey(jwk);
console.log(did);
console.assert(did === "did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf");
resolvedJwk = await resolveDid(did);
console.log(JSON.stringify(resolvedJwk));
console.assert(jwk.kty === resolvedJwk.kty);
console.assert(jwk.crv === resolvedJwk.crv);
console.assert(jwk.x === resolvedJwk.x);
if (jwk.y) console.assert(jwk.y === resolvedJwk.y);
console.log("---");
jwk = {
kty: "OKP",
crv: "X25519",
x: "L-V9o0fNYkMVKNqsX7spBzD_9oSvxM_C7ZCZX1jLO3Q",
} as const;
did = jwkToDidKey(jwk);
console.log(did);
console.assert(did === "did:key:z6LSeu9HkTHSfLLeUs2nnzUSNedgDUevfNQgQjQC23ZCit6F");
// resolvedJwk = await resolveDid(did);
// console.log(JSON.stringify(resolvedJwk));
// console.assert(jwk.kty === resolvedJwk.kty);
// console.assert(jwk.crv === resolvedJwk.crv);
// console.assert(jwk.x === resolvedJwk.x);
// if (jwk.y) console.assert(jwk.y === resolvedJwk.y);
jwk = {
kty: "OKP",
crv: "X25519",
x: "_TOE4TKtAqVsePRVR-5AA43HkAK5DSntkOCO7nYq5xU",
} as const;
did = jwkToDidKey(jwk);
console.log(did);
console.assert(did === "did:key:z6LStiZsmxiK4odS4Sb6JmdRFuJ6e1SYP157gtiCyJKfrYha");
// resolvedJwk = await resolveDid(did);
// console.log(JSON.stringify(resolvedJwk));
// console.assert(jwk.kty === resolvedJwk.kty);
// console.assert(jwk.crv === resolvedJwk.crv);
// console.assert(jwk.x === resolvedJwk.x);
// if (jwk.y) console.assert(jwk.y === resolvedJwk.y);
jwk = {
kty: "OKP",
crv: "X25519",
x: "rYxIwmdlrqetxTYolgXBq-qVBQCT29IYyWq9JIGgNWU",
} as const;
did = jwkToDidKey(jwk);
console.log(did);
console.assert(did === "did:key:z6LSoMdmJz2Djah2P4L9taDmtqeJ6wwd2HhKZvNToBmvaczQ");
// resolvedJwk = await resolveDid(did);
// console.log(JSON.stringify(resolvedJwk));
// console.assert(jwk.kty === resolvedJwk.kty);
// console.assert(jwk.crv === resolvedJwk.crv);
// console.assert(jwk.x === resolvedJwk.x);
// if (jwk.y) console.assert(jwk.y === resolvedJwk.y);
console.log("---");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// SPDX-License-Identifier: 0BSD
import ky from "npm:ky";
import stripJsonComments from "npm:strip-json-comments";
import * as v from "npm:valibot";
const client = ky.create({ prefixUrl: "https://jsr.io" });
const configFiles = [
"jsr.json",
"jsr.jsonc",
"deno.json",
"deno.jsonc",
];
// @see: https://jsr.io/docs/api#package-metadata
const PkgMetaSchema = v.object({
scope: v.string(),
name: v.string(),
latest: v.string(),
});
// @see: https://jsr.io/docs/api#package-version-metadata
const PkgVerMetaSchema = v.object({
manifest: v.record(
v.string([v.startsWith("/")]),
v.object({
size: v.number([v.integer(), v.minValue(0)]),
checksum: v.string([v.startsWith("sha")]),
}),
),
});
// @see: https://jsr.io/docs/package-configuration
const PkgConfSchema = v.object({
name: v.string(),
version: v.string(),
valtownExample: v.optional(v.string()),
valtownExampleFilename: v.optional(v.string()),
});
export async function getLatestVersion(scope: string, name: string) {
scope = normalizeScope(scope);
const data = await client.get(`@${scope}/${name}/meta.json`).json();
return v.parse(PkgMetaSchema, data).latest;
}
export async function getManifest(scope: string, name: string, version = "latest") {
scope = normalizeScope(scope);
if (version === "latest") {
version = await getLatestVersion(scope, name);
}
const data = await client.get(`@${scope}/${name}/${version}_meta.json`).json();
return v.parse(PkgVerMetaSchema, data).manifest;
}
export async function getConfig(scope: string, name: string, version: string) {
scope = normalizeScope(scope);
const manifest = await getManifest(scope, name, version);
const configFile = configFiles.find(filename => Object.hasOwn(manifest, `/${filename}`));
const data = await client.get(`@${scope}/${name}/${version}/${configFile}`, {
parseJson: (text) => JSON.parse(stripJsonComments(text)),
}).json();
return v.parse(PkgConfSchema, data);
}
function normalizeScope(input: string) {
if (!input.startsWith("@")) return input;
return input.slice(1);
}

Try on Val Town

This service enables quick generation of new val with specified jsr package. Package authors can provide custom examples by setting either:

  • valtownExample property of jsr.json/deno.json to contain example js/ts code
  • valtownExampleFilename property of jsr.json/deno.json to point to the file with example js/ts code

If no example is found val will be created with the default snippet, using @luca/flag as an example :

Create valimport * as flag from "jsr:@luca/flag";

Go ahead ↗️ try it (on Val Town)! 🎉

Additionally, the service supports ?code=<base64code> query param that allows overriding extracted/generated example code. For example one might want to override @luca/flag's snippet with:

Create valimport { printProgress } from "jsr:@luca/flag@1"; printProgress();

In order to do so first you need to convert it to base64:

$ printf 'import { printProgress } from "jsr:@luca/flag@1";\n\nprintProgress();' | base64 -w0
# ==> aW1wb3J0IHsgcHJpbnRQcm9ncmVzcyB9IGZyb20gImpzcjpAbHVjYS9mbGFnQDEiOwoKcHJpbnRQcm9ncmVzcygpOw==

Then you simply construct the URL by setting the returned value to code query param:
↗️ https://vladimyr-jsr.web.val.run?code=aW1wb3J0IHsgcH...

Usage

  • https://vladimyr-jsr.web.val.run/<scope>/<name>[@<version>]
  • https://vladimyr-jsr.web.val.run?code=<base64code>

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// SPDX-License-Identifier: 0BSD
import { getConfig } from "https://esm.town/v/vladimyr/jsrApi";
import { newValURL } from "https://esm.town/v/vladimyr/newValURL";
import { type HtmlProcessor, serveReadme } from "https://esm.town/v/vladimyr/serveReadme";
import ky from "npm:ky";
export default async function(req: Request, options?: {
transformReadme: HtmlProcessor;
}): Promise<Response> {
const { pathname, searchParams } = new URL(req.url);
let code = searchParams.get("code");
if (code) {
const url = newValURL();
url.searchParams.set("code64", code);
return Response.redirect(url);
}
if (pathname === "/") {
return serveReadme(import.meta.url, options?.transformReadme)();
}
const [scope, name, version = "latest"] = pathname.split(/[/@]/g).filter(Boolean);
if (!scope || !name) {
return Response.redirect(newValURL());
}
let example;
try {
example = await fetchValtownExample(scope, name, version);
} catch {}
if (example) {
return Response.redirect(newValURL(example));
}
let importSpec;
if (version !== "latest") {
importSpec = `jsr:@${scope}/${name}@${version}`;
} else {
importSpec = `jsr:@${scope}/${name}`;
}
code = `import * as ${name} from "${importSpec}";`;
return Response.redirect(newValURL(code));
}
async function fetchValtownExample(scope: string, name: string, version: string) {
const pkgConfig = await getConfig(scope, name, version);
version = pkgConfig.version;
if (pkgConfig.valtownExample) {
return pkgConfig.valtownExample;
}
if (!pkgConfig.valtownExampleFilename) {
return;
}
const exampleFile = new URL(`file://${pkgConfig.valtownExampleFilename}`).pathname.slice(1);
return ky.get(exampleFile, {
prefixUrl: new URL(`https://jsr.io/@${scope}/${name}/${version}/`),
}).text();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// SPDX-License-Identifier: 0BSD
import ky from "npm:ky";
import * as v from "npm:valibot";
export { HTTPError } from "npm:ky";
const PositiveIntegerSchema = v.number([v.integer(), v.minValue(0)]);
const ValSchema = v.transform(
v.object({
initialData: v.object({
id: v.string([v.uuid()]),
user: v.object({
handle: v.string(),
}),
name: v.string(),
code: v.string(),
version: PositiveIntegerSchema,
runEndAt: v.nullish(v.coerce(v.date(), (d) => new Date(d))),
readme: v.nullish(v.string()),
likeCount: PositiveIntegerSchema,
referenceCount: PositiveIntegerSchema,
commentCount: PositiveIntegerSchema,
forkCount: PositiveIntegerSchema,
prCount: PositiveIntegerSchema,
forkedVal: v.nullish(v.unknown()),
}),
}),
(input) => input.initialData,
);
const PageSchema = v.object({
page: PositiveIntegerSchema,
hasNext: v.boolean(),
vals: v.array(ValSchema),
});
export async function fetchNewestVals({ page = 0 } = {}) {
const url = new URL("https://www.val.town/newest");
url.searchParams.set("_data", "routes/_app.newest");
if (page) url.searchParams.set("page", `${page}`);
const resp = await ky.get(url).json();
return v.parse(PageSchema, resp);
}
1
2
3
4
5
6
7
8
9
10
11
12
import { fetch as fetch_ } from "https://esm.town/v/std/fetch?v=4";
import { fetch } from "https://esm.town/v/vladimyr/fetch";
import ky from "npm:ky";
const ip = await ky("https://httpbun.com/ip.json", { fetch }).json();
console.log(ip);
{
console.log();
const ip = await ky("https://httpbun.com/ip.json", { fetch: fetch_ }).json();
console.log(ip);
}
1
2
3
4
5
6
7
8
9
10
11
import ky from "npm:ky";
export async function shortenURL(url: URL | string) {
const json = {
domain: "dub.sh",
url: new URL(url).href,
publicStats: false,
};
const { shortLink } = await ky.post("https://dub.co/api/links", { json }).json<any>();
return new URL(shortLink);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// SPDX-License-Identifier: 0BSD
import ky from "npm:ky";
export async function convertUrlToDataURL(url: string | URL): Promise<string> {
const blob = await ky.get(url).blob();
return convertBlobToDataURL(blob);
}
export function convertBlobToDataURL(blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener("load", () => resolve(reader.result.toString()));
reader.addEventListener("error", () => reject(reader.error));
reader.readAsDataURL(blob);
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// SPDX-License-Identifier: 0BSD
import { API_URL } from "https://esm.town/v/std/API_URL?v=5";
import ky from "npm:ky";
import * as v from "npm:valibot";
export { HTTPError } from "npm:ky";
const PositiveIntegerSchema = v.number([v.integer(), v.minValue(0)]);
const ValSchema = v.object({
id: v.string([v.uuid()]),
author: v.object({
id: v.string([v.uuid()]),
username: v.string(),
}),
name: v.string(),
code: v.string(),
version: PositiveIntegerSchema,
runEndAt: v.nullish(v.coerce(v.date(), (d) => new Date(d))),
createdAt: v.coerce(v.date(), (d) => new Date(d)),
readme: v.nullish(v.string()),
likeCount: PositiveIntegerSchema,
referenceCount: PositiveIntegerSchema,
});
export async function fetchVal(author: string, name: string) {
const prefixUrl = new URL("/v1/alias", API_URL);
const resp = await ky.get(`${author}/${name}`, { prefixUrl }).json();
return v.parse(ValSchema, resp);
}

jsr2gh

Redirect to jsr package's GitHub repository page, like vladimyr-jsr2gh.web.val.run/@luca/flag

Usage

https://vladimyr-jsr2gh.web.val.run/<scope>/<name>

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// SPDX-License-Identifier: 0BSD
import { serveReadme } from "https://esm.town/v/vladimyr/serveReadme";
import { toHonoHandler } from "https://esm.town/v/vladimyr/toHonoHandler";
import { Hono } from "jsr:@kyiro/hono";
import ky from "npm:ky";
import * as v from "npm:valibot";
const PackageDataSchema = v.object({
githubRepository: v.nullable(v.object({
owner: v.string(),
name: v.string(),
})),
});
const app = new Hono();
app.get("/", toHonoHandler(serveReadme(import.meta.url)));
app.get("/:scope{@[^/]+}/:name", async (c) => {
const scope = c.req.param("scope").slice(1);
const name = c.req.param("name");
const { githubRepository: repo } = await fetchPackageData(scope, name);
if (repo) {
const githubURL = new URL(`https://github.com/${repo.owner}/${repo.name}`);
return c.redirect(githubURL);
}
const jsrURL = new URL(`https://jsr.io/@${scope}/${name}`);
return c.redirect(jsrURL);
});
export default app.fetch;
export async function fetchPackageData(scope: string, name: string) {
const prefixUrl = "https://api.jsr.io/";
const data = await ky.get(`scopes/${scope}/packages/${name}`, { prefixUrl }).json();
return v.parse(PackageDataSchema, data);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { getPostThread, resolveHandle } from "https://esm.town/v/vladimyr/libbluesky";
import { toPairs } from "https://esm.town/v/vladimyr/toPairs";
import ky from "npm:ky";
export async function fetchPost(url: string | URL) {
const postURL = new URL(url);
if (postURL.hostname !== "bsky.app") {
throw new TypeError("Invalid post URL");
}
const pathSegments = postURL.pathname.split("/").filter(Boolean);
const pairs = toPairs(pathSegments);
const { profile, post } = Object.fromEntries(pairs as Iterable<[PropertyKey, string]>);
const { did } = await resolveHandle(profile);
const { thread } = await getPostThread(`at://${did}/app.bsky.feed.post/${post}`);
return thread.post;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import ky from "npm:ky";
const prefixUrl = "https://public.api.bsky.app/xrpc/";
// @see: https://docs.bsky.app/docs/api/com-atproto-identity-resolve-handle
export function resolveHandle(handle: string) {
return ky.get("com.atproto.identity.resolveHandle", {
searchParams: { handle },
prefixUrl,
}).json();
}
// @see: https://docs.bsky.app/docs/api/app-bsky-feed-get-post-thread
export function getPostThread(uri: string) {
return ky.get("app.bsky.feed.getPostThread", {
searchParams: { uri },
prefixUrl,
}).json();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
import ky from "npm:ky@1.2.0";
function resolveDidKey(did) {
return ky.get(`https://dev.uniresolver.io/1.0/identifiers/${did}`, {
headers: {
accept: "application/ld+json; profile=\"https://w3id.org/did-resolution\"",
},
}).json();
}
export function getResolver() {
return { key: resolveDidKey };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import {
array,
boolean,
object,
parse,
string,
toCustom,
transform,
url,
} from "https://deno.land/x/valibot@v0.22.0/mod.ts";
import ky, { HTTPError } from "npm:ky@1.1.3";
import { joinURL } from "npm:ufo@1.3.2";
const API_URL = "https://crates.io/api/v1/";
const VersionSchema = transform(
object({
num: string(),
dl_path: string([toCustom(input => (new URL(input, API_URL)).href)]),
yanked: boolean(),
}),
({ num: version, dl_path: downloadUrl, ...other }) => ({ version, downloadUrl, ...other }),
);
const CrateInfoSchema = object({
versions: array(VersionSchema),
});
export async function getCrateInfo(crateName: string, version?: string) {
const createURL = joinURL(API_URL, `/crates/${crateName}`);
const crateInfo = parse(CrateInfoSchema, await ky.get(createURL).json());
const versions = crateInfo.versions.filter(it => !it.yanked);
if (!version) return versions.at(0);
return versions.find(it => it.version === version);
}
export { HTTPError };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { object, optional, parse, record, string, url } from "https://deno.land/x/valibot@v0.22.0/mod.ts";
import ky, { HTTPError } from "npm:ky@1.1.3";
const REGISTRY_URL = "https://registry.npmjs.org/";
const VersionSchema = object({
version: string(),
dist: object({
tarball: string([url()]),
}),
deprecated: optional(string()),
});
const PkgInfoSchema = object({
name: string(),
"dist-tags": record(string()),
versions: record(VersionSchema),
});
export async function getPkgInfo(pkgName: string, version = "latest") {
const pkgURL = new URL(encodeURIComponent(pkgName).replace(/^%40/, "@"), REGISTRY_URL);
const headers = {
accept: "application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*",
};
const pkgInfo = parse(PkgInfoSchema, await ky.get(pkgURL, { headers }).json());
if (pkgInfo["dist-tags"][version]) {
version = pkgInfo["dist-tags"][version];
}
return pkgInfo.versions[version];
}
export { HTTPError };