shelving 1.167.2 → 1.168.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/util/url.js CHANGED
@@ -1,11 +1,15 @@
1
1
  import { RequiredError } from "../error/RequiredError.js";
2
- import { ValueError } from "../error/ValueError.js";
3
- import { getDictionaryItems, isDictionary } from "./dictionary.js";
4
2
  import { notNullish } from "./null.js";
5
- import { getString, isString } from "./string.js";
6
- /** Is an unknown value a URL object? */
3
+ export const URL = globalThis.URL;
4
+ /**
5
+ * Is an unknown value a URL object?
6
+ * - Must be a `URL` instance and its origin must start with `scheme://`
7
+ */
7
8
  export function isURL(value) {
8
- return value instanceof URL;
9
+ return value instanceof globalThis.URL && _isValidURL(value);
10
+ }
11
+ function _isValidURL(url) {
12
+ return url.href.startsWith(`${url.protocol}//`);
9
13
  }
10
14
  /** Assert that an unknown value is a URL object. */
11
15
  export function assertURL(value, caller = assertURL) {
@@ -15,13 +19,19 @@ export function assertURL(value, caller = assertURL) {
15
19
  /** Convert a possible URL to a URL, or return `undefined` if conversion fails. */
16
20
  export function getURL(possible, base = _BASE) {
17
21
  if (notNullish(possible)) {
18
- if (isURL(possible))
19
- return possible;
20
- try {
21
- return new URL(possible, base);
22
+ if (possible instanceof globalThis.URL) {
23
+ if (_isValidURL(possible))
24
+ return possible;
22
25
  }
23
- catch {
24
- return undefined;
26
+ else {
27
+ try {
28
+ const url = new globalThis.URL(possible, base);
29
+ if (_isValidURL(url))
30
+ return url;
31
+ }
32
+ catch {
33
+ //
34
+ }
25
35
  }
26
36
  }
27
37
  }
@@ -32,87 +42,3 @@ export function requireURL(possible, base, caller = requireURL) {
32
42
  assertURL(url, caller);
33
43
  return url;
34
44
  }
35
- /**
36
- * Get a set of entries for a set of possible URL params.
37
- *
38
- * Note: Not as simple as just converting with `Object.fromEntries()`:
39
- * 1. When `URLSearchParams` contains multiple values for the same key, calling `params.get()` will return the _first_ value.
40
- * 2. So when converting this to a simple data object, only one value per key can be represented, but it needs to be the _first_ one.
41
- * 3. Since we're looping through anyway, we also take the time to convert values to strings, so we can accept a wider range of input types.
42
- */
43
- export function* getURLEntries(input, caller = getURLParams) {
44
- if (input instanceof URLSearchParams) {
45
- yield* input;
46
- }
47
- else if (isString(input) || isURL(input)) {
48
- yield* requireURL(input, undefined, caller).searchParams;
49
- }
50
- else {
51
- const done = [];
52
- for (const [key, value] of getDictionaryItems(input)) {
53
- if (done.includes(key))
54
- continue;
55
- done.push(key);
56
- const str = getString(value);
57
- if (str === undefined)
58
- throw new ValueError(`URL param "${key}" must be string`, { received: value, caller });
59
- yield [key, str];
60
- }
61
- }
62
- }
63
- /** Get a set of params for a URL as a dictionary. */
64
- export function getURLParams(input, caller = getURLParams) {
65
- const output = {};
66
- for (const [key, str] of getURLEntries(input, caller))
67
- output[key] = str;
68
- return output;
69
- }
70
- /** Get a single named param from a URL. */
71
- export function getURLParam(input, key) {
72
- if (input instanceof URLSearchParams)
73
- return input.get(key) || undefined;
74
- if (isDictionary(input))
75
- return getString(input[key]);
76
- return getURLParams(input)[key];
77
- }
78
- /** Get a single named param from a URL. */
79
- export function requireURLParam(input, key, caller = requireURLParam) {
80
- const value = getURLParam(input, key);
81
- if (value === undefined)
82
- throw new RequiredError(`URL param "${key}" is required`, { received: input, caller });
83
- return value;
84
- }
85
- /**
86
- * Return a URL with a new param set (or same URL if no changes were made).
87
- * - Throws `ValueError` if the value could not be converted to a string.
88
- */
89
- export function withURLParam(url, key, value, caller = withURLParam) {
90
- const input = requireURL(url);
91
- const output = new URL(input);
92
- const str = getString(value);
93
- if (str === undefined)
94
- throw new ValueError(`URL param "${key}" must be string`, { received: value, caller });
95
- output.searchParams.set(key, str);
96
- return input.href === output.href ? input : output;
97
- }
98
- /**
99
- * Return a URL with several new params set (or same URL if no changes were made).
100
- * - Throws `ValueError` if any of the values could not be converted to strings.
101
- */
102
- export function withURLParams(url, params, caller = withURLParams) {
103
- const input = requireURL(url);
104
- const output = new URL(input);
105
- for (const [key, str] of getURLEntries(params, caller))
106
- output.searchParams.set(key, str);
107
- return input.href === output.href ? input : output;
108
- }
109
- /** Return a URL without one or more params (or same URL if no changes were made). */
110
- export function omitURLParams(url, ...keys) {
111
- const input = requireURL(url);
112
- const output = new URL(input);
113
- for (const key of keys)
114
- output.searchParams.delete(key);
115
- return input.href === output.href ? input : output;
116
- }
117
- /** Return a URL without a param (or same URL if no changes were made). */
118
- export const omitURLParam = omitURLParams;
@@ -1,27 +0,0 @@
1
- import type { ImmutableArray } from "../util/array.js";
2
- import { type AbsoluteLink } from "../util/link.js";
3
- import type { StringSchemaOptions } from "./StringSchema.js";
4
- import { StringSchema } from "./StringSchema.js";
5
- /** Allowed options for `LinkSchema` */
6
- export interface LinkSchemaOptions extends Omit<StringSchemaOptions, "input" | "min" | "max" | "multiline"> {
7
- readonly base?: AbsoluteLink | undefined;
8
- readonly schemes?: ImmutableArray<string> | undefined;
9
- readonly hosts?: ImmutableArray<string> | undefined;
10
- }
11
- /**
12
- * Type of `StringSchema` that defines a valid URL link.
13
- * - Checks URL scheme against a whitelist (always), and checks URL domain against a whitelist (optional).
14
- * - URLs are limited to 512 characters, but generally these won't be data: URIs so this is a reasonable limit.
15
- * - Falsy values are converted to `""` empty string.
16
- */
17
- export declare class LinkSchema extends StringSchema {
18
- readonly base: AbsoluteLink | undefined;
19
- readonly schemes: ImmutableArray<string> | undefined;
20
- readonly hosts: ImmutableArray<string> | undefined;
21
- constructor({ one, title, base, schemes, hosts, ...options }: LinkSchemaOptions);
22
- validate(unsafeValue: unknown): AbsoluteLink;
23
- }
24
- /** Valid link, e.g. `https://www.google.com` */
25
- export declare const LINK: LinkSchema;
26
- /** Valid link, e.g. `https://www.google.com`, or `null` */
27
- export declare const NULLABLE_LINK: import("./NullableSchema.js").NullableSchema<`${string}:${string}`>;
package/util/link.d.ts DELETED
@@ -1,71 +0,0 @@
1
- import type { ImmutableArray } from "./array.js";
2
- import type { AnyCaller } from "./function.js";
3
- import type { Nullish } from "./null.js";
4
- import type { Path } from "./path.js";
5
- import { type PossibleURL } from "./url.js";
6
- /**
7
- * URL string with a `scheme:` at the start and a path component, e.g. `https://` or `file://`
8
- * - The `//` in a URI indicates that type of URI has a path heirarchy indicated by the first `/` after the `://`
9
- * - If the URI has no explicit `/path` component it will always be assumed to be `/`
10
- * - Some URIs are non-heirarchical, e.g. `mailto:me@gmail.com`
11
- */
12
- export type AbsoluteLink = `${string}:${string}`;
13
- /**
14
- * Relative link starts with `./` or `../` or `/`
15
- * @example "/a/b/c"
16
- * @example "./d/e/f"
17
- * @example "../g/h/i"
18
- */
19
- export type RelativeLink = Path;
20
- /**
21
- * Either an absolute URL string or a relative URL string.
22
- * @example "http://www.google.com"
23
- * @example "/a/b/c"
24
- * @example "./d/e/f"
25
- * @example "../g/h/i"
26
- */
27
- export type Link = AbsoluteLink | RelativeLink;
28
- /**
29
- * List of allowed schemes for a link.
30
- * @example ["http:", "https:", "mailto:"]
31
- */
32
- export type LinkSchemes = ImmutableArray<string>;
33
- /**
34
- * List of allowed hosts for a link.
35
- * @example ["google.com", "www.google.com"]
36
- */
37
- export type LinkHosts = ImmutableArray<string>;
38
- /**
39
- * Absolute URL is a URL that has an `href` that is a `Link` element and a `pathname` that is an `AbsolutePath` property.
40
- * - e.g. `http://x.com/a/b` is a link URL because `.pathname` will be `/a/b`
41
- * - e.g. `http://x.com` is a link URL because `.pathname` will be `/`
42
- * - e.g. `mailto:me@gmail.com` is _not_ an absolute URL because `.pathname` will be `"me@gmail.com"` which does not start with `/` slash.
43
- */
44
- export type AbsoluteLinkURL = URL & {
45
- href: AbsoluteLink;
46
- };
47
- /**
48
- * Is an unknown value a link URL?
49
- * - A valid link URL is a `URL` instance with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
50
- */
51
- export declare function isLinkURL(value: unknown, schemes?: LinkSchemes, hosts?: LinkHosts): value is AbsoluteLinkURL;
52
- /**
53
- * Convert a possible URL to a link URL, or return `undefined` if conversion fails.
54
- * - A valid link URL is a `URL` instance with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
55
- */
56
- export declare function getLinkURL(value: Nullish<PossibleURL>, base?: AbsoluteLinkURL | AbsoluteLink, schemes?: LinkSchemes, hosts?: LinkHosts): AbsoluteLinkURL | undefined;
57
- /**
58
- * Convert a possible URL to a link URL, or throw `RequiredError` if conversion fails.
59
- * - A valid link URL is a `URL` instance with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
60
- */
61
- export declare function requireLinkURL(value: PossibleURL, base?: AbsoluteLinkURL | AbsoluteLink, schemes?: LinkSchemes, hosts?: LinkHosts, caller?: AnyCaller): AbsoluteLinkURL;
62
- /**
63
- * Convert a possible URL to an link URL string, or return `undefined` if conversion fails.
64
- * - A valid link URL string is an absolute URL string with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
65
- */
66
- export declare function getLink(value: Nullish<PossibleURL>, base?: AbsoluteLinkURL | AbsoluteLink, schemes?: LinkSchemes, hosts?: LinkHosts): AbsoluteLink | undefined;
67
- /**
68
- * Convert a possible URL to an link URL string, or throw `RequiredError` if conversion fails.
69
- * - A valid link URL string is an absolute URL string with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
70
- */
71
- export declare function requireLink(value: PossibleURL, base?: AbsoluteLinkURL | AbsoluteLink, schemes?: LinkSchemes, hosts?: LinkHosts, caller?: AnyCaller): AbsoluteLink;
package/util/link.js DELETED
@@ -1,44 +0,0 @@
1
- import { RequiredError } from "../error/RequiredError.js";
2
- import { getURL, isURL } from "./url.js";
3
- /** Default whitelist for URL schemes. */
4
- const SCHEMES = ["http:", "https:"];
5
- /**
6
- * Is an unknown value a link URL?
7
- * - A valid link URL is a `URL` instance with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
8
- */
9
- export function isLinkURL(value, schemes = SCHEMES, hosts) {
10
- return isURL(value) && schemes.includes(value.protocol) && (!hosts || hosts.includes(value.host));
11
- }
12
- /**
13
- * Convert a possible URL to a link URL, or return `undefined` if conversion fails.
14
- * - A valid link URL is a `URL` instance with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
15
- */
16
- export function getLinkURL(value, base, schemes = SCHEMES, hosts) {
17
- const url = getURL(value, base);
18
- if (isLinkURL(url, schemes, hosts))
19
- return url;
20
- }
21
- /**
22
- * Convert a possible URL to a link URL, or throw `RequiredError` if conversion fails.
23
- * - A valid link URL is a `URL` instance with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
24
- */
25
- export function requireLinkURL(value, base, schemes, hosts, caller = requireLinkURL) {
26
- const url = getLinkURL(value, base, schemes, hosts);
27
- if (!url)
28
- throw new RequiredError("Invalid link", { received: value, base, schemes, hosts, caller });
29
- return url;
30
- }
31
- /**
32
- * Convert a possible URL to an link URL string, or return `undefined` if conversion fails.
33
- * - A valid link URL string is an absolute URL string with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
34
- */
35
- export function getLink(value, base, schemes = SCHEMES, hosts) {
36
- return getLinkURL(value, base, schemes, hosts)?.href;
37
- }
38
- /**
39
- * Convert a possible URL to an link URL string, or throw `RequiredError` if conversion fails.
40
- * - A valid link URL string is an absolute URL string with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
41
- */
42
- export function requireLink(value, base, schemes, hosts, caller = requireLink) {
43
- return requireLinkURL(value, base, schemes, hosts, caller).href;
44
- }
File without changes
File without changes
File without changes