A
arktype14mo ago
Bas950

Validate string is URL

What would be the easiest way to validate that the url in here is an actual valid url?
const button = type({
label: "2<=string<=32",
url: "2<=string<=512",
})
const button = type({
label: "2<=string<=32",
url: "2<=string<=512",
})
19 Replies
TizzySaurus
TizzySaurus14mo ago
Use a morph that checks the string length and regex it I guess Depending on what you want to consider a valid URL
Bas950
Bas95014mo ago
I mean seeing if it would parse in new URL()
TizzySaurus
TizzySaurus14mo ago
If the given base URL or the resulting URL are not valid URLs, the JavaScript TypeError exception is thrown.
Since an error is thrown when it's invalid, you can just try/catch
Bas950
Bas95014mo ago
yea but how can I do that inside of the type({...}) ? Or is that not possible
TizzySaurus
TizzySaurus14mo ago
import { Problems, type } from "arktype";

function validateUrl(url: string, problems: Problems) {
if (url.length < 2 || url.length > 512) {
problems.mustBe("of length 2-512 inclusive");
return false;
}

try {
new URL(url);
} catch (err) {
problems.mustBe("a valid url");
return false;
}
return true;
}

const button = type({
url: ["string", |>, validateUrl]
})
import { Problems, type } from "arktype";

function validateUrl(url: string, problems: Problems) {
if (url.length < 2 || url.length > 512) {
problems.mustBe("of length 2-512 inclusive");
return false;
}

try {
new URL(url);
} catch (err) {
problems.mustBe("a valid url");
return false;
}
return true;
}

const button = type({
url: ["string", |>, validateUrl]
})
something like this I guess You could ofc have the function in-line if you wanted @Bas950 ^
Bas950
Bas95014mo ago
hmmm, okay thanks. Never used those morphs before, but that should work I guess, thanks. Might be nice if @ssalbdivad can add url as a thing itself just like dates etc.
TizzySaurus
TizzySaurus14mo ago
Yeah, it might even be planned
Bas950
Bas95014mo ago
For now I will use:
const urlMorph = (options?: {
minLength: number;
maxLength: number;
}) => morph("string", (value, problems) => {
if (options) {
if (value.length < options.minLength) {
problems.mustBe(`of length ${options.minLength} or more characters`);
return false;
}
if (value.length > options.maxLength) {
problems.mustBe(`of length ${options.maxLength} or less characters`);
return false;
}
}

try {
new URL(value);
return true;
} catch {
problems.mustBe("a valid URL");
return false;
}
});
const urlMorph = (options?: {
minLength: number;
maxLength: number;
}) => morph("string", (value, problems) => {
if (options) {
if (value.length < options.minLength) {
problems.mustBe(`of length ${options.minLength} or more characters`);
return false;
}
if (value.length > options.maxLength) {
problems.mustBe(`of length ${options.maxLength} or less characters`);
return false;
}
}

try {
new URL(value);
return true;
} catch {
problems.mustBe("a valid URL");
return false;
}
});
TizzySaurus
TizzySaurus14mo ago
Looks good 👍
ssalbdivad
ssalbdivad14mo ago
Awesome, thanks for helping @TizzySaurus. I'll probably add url as just validating the string format, then parse.url would be validate it and then transform? Something like that
TizzySaurus
TizzySaurus14mo ago
Sounds good!
Dimava
Dimava14mo ago
isnt this narrow?
Dimava
Dimava14mo ago
Also I doubt you would want
No description
ssalbdivad
ssalbdivad14mo ago
Yeah you're right haha I didn't actually double check 😬 This would convert it to a boolean At least that would be clear when you tried to use the type though because your output data would be a boolean
Bas950
Bas95014mo ago
oh yea thanks, forgot, you just have to check if the protocol is http: or https:
Want results from more Discord servers?
Add your server