This commit is contained in:
2025-01-04 00:34:03 +01:00
parent 41829408dc
commit 0ca14bbc19
18111 changed files with 1871397 additions and 0 deletions

View File

@@ -0,0 +1 @@
export const booleanEquals = (value1, value2) => value1 === value2;

View File

@@ -0,0 +1,11 @@
import { EndpointError } from "../types";
import { getAttrPathList } from "./getAttrPathList";
export const getAttr = (value, path) => getAttrPathList(path).reduce((acc, index) => {
if (typeof acc !== "object") {
throw new EndpointError(`Index '${index}' in '${path}' not found in '${JSON.stringify(value)}'`);
}
else if (Array.isArray(acc)) {
return acc[parseInt(index)];
}
return acc[index];
}, value);

View File

@@ -0,0 +1,25 @@
import { EndpointError } from "../types";
export const getAttrPathList = (path) => {
const parts = path.split(".");
const pathList = [];
for (const part of parts) {
const squareBracketIndex = part.indexOf("[");
if (squareBracketIndex !== -1) {
if (part.indexOf("]") !== part.length - 1) {
throw new EndpointError(`Path: '${path}' does not end with ']'`);
}
const arrayIndex = part.slice(squareBracketIndex + 1, -1);
if (Number.isNaN(parseInt(arrayIndex))) {
throw new EndpointError(`Invalid array index: '${arrayIndex}' in path: '${path}'`);
}
if (squareBracketIndex !== 0) {
pathList.push(part.slice(0, squareBracketIndex));
}
pathList.push(arrayIndex);
}
else {
pathList.push(part);
}
}
return pathList;
};

View File

@@ -0,0 +1,9 @@
export * from "./booleanEquals";
export * from "./getAttr";
export * from "./isSet";
export * from "./isValidHostLabel";
export * from "./not";
export * from "./parseURL";
export * from "./stringEquals";
export * from "./substring";
export * from "./uriEncode";

View File

@@ -0,0 +1,2 @@
const IP_V4_REGEX = new RegExp(`^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}$`);
export const isIpAddress = (value) => IP_V4_REGEX.test(value) || (value.startsWith("[") && value.endsWith("]"));

View File

@@ -0,0 +1 @@
export const isSet = (value) => value != null;

View File

@@ -0,0 +1,13 @@
const VALID_HOST_LABEL_REGEX = new RegExp(`^(?!.*-$)(?!-)[a-zA-Z0-9-]{1,63}$`);
export const isValidHostLabel = (value, allowSubDomains = false) => {
if (!allowSubDomains) {
return VALID_HOST_LABEL_REGEX.test(value);
}
const labels = value.split(".");
for (const label of labels) {
if (!isValidHostLabel(label)) {
return false;
}
}
return true;
};

View File

@@ -0,0 +1 @@
export const not = (value) => !value;

View File

@@ -0,0 +1,51 @@
import { EndpointURLScheme } from "@smithy/types";
import { isIpAddress } from "./isIpAddress";
const DEFAULT_PORTS = {
[EndpointURLScheme.HTTP]: 80,
[EndpointURLScheme.HTTPS]: 443,
};
export const parseURL = (value) => {
const whatwgURL = (() => {
try {
if (value instanceof URL) {
return value;
}
if (typeof value === "object" && "hostname" in value) {
const { hostname, port, protocol = "", path = "", query = {} } = value;
const url = new URL(`${protocol}//${hostname}${port ? `:${port}` : ""}${path}`);
url.search = Object.entries(query)
.map(([k, v]) => `${k}=${v}`)
.join("&");
return url;
}
return new URL(value);
}
catch (error) {
return null;
}
})();
if (!whatwgURL) {
console.error(`Unable to parse ${JSON.stringify(value)} as a whatwg URL.`);
return null;
}
const urlString = whatwgURL.href;
const { host, hostname, pathname, protocol, search } = whatwgURL;
if (search) {
return null;
}
const scheme = protocol.slice(0, -1);
if (!Object.values(EndpointURLScheme).includes(scheme)) {
return null;
}
const isIp = isIpAddress(hostname);
const inputContainsDefaultPort = urlString.includes(`${host}:${DEFAULT_PORTS[scheme]}`) ||
(typeof value === "string" && value.includes(`${host}:${DEFAULT_PORTS[scheme]}`));
const authority = `${host}${inputContainsDefaultPort ? `:${DEFAULT_PORTS[scheme]}` : ``}`;
return {
scheme,
authority,
path: pathname,
normalizedPath: pathname.endsWith("/") ? pathname : `${pathname}/`,
isIp,
};
};

View File

@@ -0,0 +1 @@
export const stringEquals = (value1, value2) => value1 === value2;

View File

@@ -0,0 +1,9 @@
export const substring = (input, start, stop, reverse) => {
if (start >= stop || input.length < stop) {
return null;
}
if (!reverse) {
return input.substring(start, stop);
}
return input.substring(input.length - stop, input.length - start);
};

View File

@@ -0,0 +1 @@
export const uriEncode = (value) => encodeURIComponent(value).replace(/[!*'()]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);