@lowlighter/toolbox 1.0.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/README.md +14 -0
- package/clone.d.ts +9 -0
- package/clone.js +37 -0
- package/deno.lock +53 -0
- package/env.d.ts +28 -0
- package/env.js +28 -0
- package/evaluate.d.ts +49 -0
- package/evaluate.js +90 -0
- package/events.d.ts +8 -0
- package/events.js +28 -0
- package/filesystem.d.ts +19 -0
- package/filesystem.js +40 -0
- package/fixtures/filesystem/a/b/foo.txt +1 -0
- package/fixtures/filesystem/a/c/bar.txt +1 -0
- package/fixtures/filesystem/a/c/baz.txt +1 -0
- package/fixtures/filesystem/a/d/qux.ts +1 -0
- package/format.d.ts +9 -0
- package/format.js +21 -0
- package/identicon.d.ts +6 -0
- package/identicon.js +32 -0
- package/imgb64.d.ts +1 -0
- package/imgb64.js +15 -0
- package/mod.ts +1 -0
- package/noop.d.ts +1 -0
- package/noop.js +2 -0
- package/package.json +116 -0
- package/permissions.d.ts +1 -0
- package/permissions.js +31 -0
- package/pluralize.d.ts +6 -0
- package/pluralize.js +44 -0
- package/promises.d.ts +1 -0
- package/promises.js +12 -0
- package/resolve.d.ts +5 -0
- package/resolve.js +18 -0
- package/scripts/code_quality.d.ts +0 -0
- package/scripts/code_quality.js +210 -0
- package/scripts/download_lambda_chromium.d.ts +10 -0
- package/scripts/download_lambda_chromium.js +133 -0
- package/scripts/highlight_coverage.d.ts +0 -0
- package/scripts/highlight_coverage.js +62 -0
- package/scripts/publish/_utils.js +95 -0
- package/scripts/publish/npm.d.ts +11 -0
- package/scripts/publish/npm.js +130 -0
- package/scripts/publish/x.d.ts +20 -0
- package/scripts/publish/x.js +303 -0
- package/timezone.d.ts +2 -0
- package/timezone.js +8 -0
package/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# 🧰 Toolbox
|
|
2
|
+
|
|
3
|
+
[](https://jsr.io/@libs/toolbox) [](https://jsr.io/@libs/toolbox)
|
|
4
|
+
|
|
5
|
+
A set of miscellaneous utilities.
|
|
6
|
+
|
|
7
|
+
- [`📚 Documentation`](https://jsr.io/@libs/toolbox/doc)
|
|
8
|
+
|
|
9
|
+
## 📜 License
|
|
10
|
+
|
|
11
|
+
```plaintext
|
|
12
|
+
Copyright (c) Simon Lecoq <@lowlighter>. (MIT License)
|
|
13
|
+
https://github.com/lowlighter/libs/blob/main/LICENSE
|
|
14
|
+
```
|
package/clone.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clones a value deeply.
|
|
3
|
+
*
|
|
4
|
+
* If `structuredCloneable` is set, the clone will be compatible with `structuredClone` algorithm, meaning that:
|
|
5
|
+
* - Proxy are unproxyed to plain objects
|
|
6
|
+
* - Incompatible types are ignored
|
|
7
|
+
*/ export declare function clone<T>(value: T, options?: {
|
|
8
|
+
structuredCloneable?: boolean;
|
|
9
|
+
}): T;
|
package/clone.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clones a value deeply.
|
|
3
|
+
*
|
|
4
|
+
* If `structuredCloneable` is set, the clone will be compatible with `structuredClone` algorithm, meaning that:
|
|
5
|
+
* - Proxy are unproxyed to plain objects
|
|
6
|
+
* - Incompatible types are ignored
|
|
7
|
+
*/ export function clone(value, options) {
|
|
8
|
+
return _clone(value, options, new WeakMap());
|
|
9
|
+
}
|
|
10
|
+
/** {@linkcode clone()} implementation. */ function _clone(value, options, seen) {
|
|
11
|
+
if (Array.isArray(value)) {
|
|
12
|
+
if (seen.has(value)) return seen.get(value);
|
|
13
|
+
const cloned = [];
|
|
14
|
+
seen.set(value, cloned);
|
|
15
|
+
for (const item of value)cloned.push(_clone(item, options, seen));
|
|
16
|
+
return cloned;
|
|
17
|
+
}
|
|
18
|
+
if ([
|
|
19
|
+
Date,
|
|
20
|
+
Error,
|
|
21
|
+
Map,
|
|
22
|
+
Set,
|
|
23
|
+
RegExp
|
|
24
|
+
].some((type)=>value instanceof type)) return structuredClone(value);
|
|
25
|
+
if (typeof value === "object" && value !== null) {
|
|
26
|
+
if (seen.has(value)) return seen.get(value);
|
|
27
|
+
const cloned = {};
|
|
28
|
+
seen.set(value, cloned);
|
|
29
|
+
for (const [k, v] of Object.entries(value)){
|
|
30
|
+
if (options?.structuredCloneable && (typeof v === "symbol" || typeof v === "function")) continue;
|
|
31
|
+
cloned[k] = _clone(v, options, seen);
|
|
32
|
+
}
|
|
33
|
+
return cloned;
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMvdG9vbGJveC9jbG9uZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENsb25lcyBhIHZhbHVlIGRlZXBseS5cbiAqXG4gKiBJZiBgc3RydWN0dXJlZENsb25lYWJsZWAgaXMgc2V0LCB0aGUgY2xvbmUgd2lsbCBiZSBjb21wYXRpYmxlIHdpdGggYHN0cnVjdHVyZWRDbG9uZWAgYWxnb3JpdGhtLCBtZWFuaW5nIHRoYXQ6XG4gKiAtIFByb3h5IGFyZSB1bnByb3h5ZWQgdG8gcGxhaW4gb2JqZWN0c1xuICogLSBJbmNvbXBhdGlibGUgdHlwZXMgYXJlIGlnbm9yZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb25lPFQ+KHZhbHVlOiBULCBvcHRpb25zPzogeyBzdHJ1Y3R1cmVkQ2xvbmVhYmxlPzogYm9vbGVhbiB9KTogVCB7XG4gIHJldHVybiBfY2xvbmUodmFsdWUsIG9wdGlvbnMsIG5ldyBXZWFrTWFwKCkpIGFzIFRcbn1cblxuLyoqIHtAbGlua2NvZGUgY2xvbmUoKX0gaW1wbGVtZW50YXRpb24uICovXG5mdW5jdGlvbiBfY2xvbmUodmFsdWU6IHVua25vd24sIG9wdGlvbnM6IHsgc3RydWN0dXJlZENsb25lYWJsZT86IGJvb2xlYW4gfSB8IHVuZGVmaW5lZCwgc2VlbjogV2Vha01hcDxvYmplY3QsIHVua25vd24+KTogdW5rbm93biB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIGlmIChzZWVuLmhhcyh2YWx1ZSkpXG4gICAgICByZXR1cm4gc2Vlbi5nZXQodmFsdWUpXG4gICAgY29uc3QgY2xvbmVkOiB1bmtub3duW10gPSBbXVxuICAgIHNlZW4uc2V0KHZhbHVlLCBjbG9uZWQpXG4gICAgZm9yIChjb25zdCBpdGVtIG9mIHZhbHVlKVxuICAgICAgY2xvbmVkLnB1c2goX2Nsb25lKGl0ZW0sIG9wdGlvbnMsIHNlZW4pKVxuICAgIHJldHVybiBjbG9uZWRcbiAgfVxuICBpZiAoW0RhdGUsIEVycm9yLCBNYXAsIFNldCwgUmVnRXhwXS5zb21lKCh0eXBlKSA9PiB2YWx1ZSBpbnN0YW5jZW9mIHR5cGUpKVxuICAgIHJldHVybiBzdHJ1Y3R1cmVkQ2xvbmUodmFsdWUpXG4gIGlmICgodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSAmJiAodmFsdWUgIT09IG51bGwpKSB7XG4gICAgaWYgKHNlZW4uaGFzKHZhbHVlKSlcbiAgICAgIHJldHVybiBzZWVuLmdldCh2YWx1ZSlcbiAgICBjb25zdCBjbG9uZWQgPSB7fSBhcyBSZWNvcmQ8UHJvcGVydHlLZXksIHVua25vd24+XG4gICAgc2Vlbi5zZXQodmFsdWUsIGNsb25lZClcbiAgICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSkpIHtcbiAgICAgIGlmICgob3B0aW9ucz8uc3RydWN0dXJlZENsb25lYWJsZSkgJiYgKHR5cGVvZiB2ID09PSBcInN5bWJvbFwiIHx8IHR5cGVvZiB2ID09PSBcImZ1bmN0aW9uXCIpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgY2xvbmVkW2tdID0gX2Nsb25lKHYsIG9wdGlvbnMsIHNlZW4pXG4gICAgfVxuICAgIHJldHVybiBjbG9uZWRcbiAgfVxuICByZXR1cm4gdmFsdWVcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0NBTUMsR0FDRCxPQUFPLFNBQVMsTUFBUyxLQUFRLEVBQUUsT0FBMkM7RUFDNUUsT0FBTyxPQUFPLE9BQU8sU0FBUyxJQUFJO0FBQ3BDO0FBRUEsd0NBQXdDLEdBQ3hDLFNBQVMsT0FBTyxLQUFjLEVBQUUsT0FBc0QsRUFBRSxJQUE4QjtFQUNwSCxJQUFJLE1BQU0sT0FBTyxDQUFDLFFBQVE7SUFDeEIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxRQUNYLE9BQU8sS0FBSyxHQUFHLENBQUM7SUFDbEIsTUFBTSxTQUFvQixFQUFFO0lBQzVCLEtBQUssR0FBRyxDQUFDLE9BQU87SUFDaEIsS0FBSyxNQUFNLFFBQVEsTUFDakIsT0FBTyxJQUFJLENBQUMsT0FBTyxNQUFNLFNBQVM7SUFDcEMsT0FBTztFQUNUO0VBQ0EsSUFBSTtJQUFDO0lBQU07SUFBTztJQUFLO0lBQUs7R0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQVMsaUJBQWlCLE9BQ2xFLE9BQU8sZ0JBQWdCO0VBQ3pCLElBQUksQUFBQyxPQUFPLFVBQVUsWUFBYyxVQUFVLE1BQU87SUFDbkQsSUFBSSxLQUFLLEdBQUcsQ0FBQyxRQUNYLE9BQU8sS0FBSyxHQUFHLENBQUM7SUFDbEIsTUFBTSxTQUFTLENBQUM7SUFDaEIsS0FBSyxHQUFHLENBQUMsT0FBTztJQUNoQixLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsSUFBSSxPQUFPLE9BQU8sQ0FBQyxPQUFRO01BQzFDLElBQUksQUFBQyxTQUFTLHVCQUF3QixDQUFDLE9BQU8sTUFBTSxZQUFZLE9BQU8sTUFBTSxVQUFVLEdBQ3JGO01BQ0YsTUFBTSxDQUFDLEVBQUUsR0FBRyxPQUFPLEdBQUcsU0FBUztJQUNqQztJQUNBLE9BQU87RUFDVDtFQUNBLE9BQU87QUFDVCJ9
|
package/deno.lock
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "5",
|
|
3
|
+
"specifiers": {
|
|
4
|
+
"jsr:@std/cli@^1.0.28": "1.0.31",
|
|
5
|
+
"jsr:@std/fs@^1.0.23": "1.0.24",
|
|
6
|
+
"jsr:@std/internal@^1.0.14": "1.0.14",
|
|
7
|
+
"jsr:@std/path@^1.1.4": "1.1.6",
|
|
8
|
+
"jsr:@std/path@^1.1.5": "1.1.6"
|
|
9
|
+
},
|
|
10
|
+
"jsr": {
|
|
11
|
+
"@std/cli@1.0.31": {
|
|
12
|
+
"integrity": "190bb61f809378267c06be3bcd689fcc540f0cfaa5892171144cae787d02e2fd",
|
|
13
|
+
"dependencies": [
|
|
14
|
+
"jsr:@std/internal"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"@std/fs@1.0.24": {
|
|
18
|
+
"integrity": "f3061b45b81673a2bece689da041df32d174be064c89eb6397fb5718d3fb7877",
|
|
19
|
+
"dependencies": [
|
|
20
|
+
"jsr:@std/internal",
|
|
21
|
+
"jsr:@std/path@^1.1.5"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"@std/internal@1.0.14": {
|
|
25
|
+
"integrity": "291516b3d4c35024d6ffbc0a9df5bf4c64116e05b50012cf846710152d2ffdf7"
|
|
26
|
+
},
|
|
27
|
+
"@std/path@1.1.6": {
|
|
28
|
+
"integrity": "c68485c2a4dfbb5ae3cc74fae4e8c4e5d874cf8a8ed12927917235c758b46cbe",
|
|
29
|
+
"dependencies": [
|
|
30
|
+
"jsr:@std/internal"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"workspace": {
|
|
35
|
+
"dependencies": [
|
|
36
|
+
"jsr:@std/cli@^1.0.28",
|
|
37
|
+
"jsr:@std/encoding@^1.0.10",
|
|
38
|
+
"jsr:@std/fs@^1.0.23",
|
|
39
|
+
"jsr:@std/path@^1.1.4",
|
|
40
|
+
"jsr:@std/streams@^1.0.17",
|
|
41
|
+
"jsr:@std/tar@0.1.10"
|
|
42
|
+
],
|
|
43
|
+
"packageJson": {
|
|
44
|
+
"dependencies": [
|
|
45
|
+
"npm:@jsr/std__cli@^1.0.28",
|
|
46
|
+
"npm:@jsr/std__fs@^1.0.23",
|
|
47
|
+
"npm:@jsr/std__path@^1.1.4",
|
|
48
|
+
"npm:@jsr/std__streams@^1.0.17",
|
|
49
|
+
"npm:@jsr/std__tar@~0.1.10"
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
package/env.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads an environment variable.
|
|
3
|
+
*
|
|
4
|
+
* An empty string is returned if the variable is unreadable.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* env("ENV_VAR", { default: "foo" })
|
|
8
|
+
* ```
|
|
9
|
+
*/ export declare function env(key: string, options?: {
|
|
10
|
+
boolean?: false;
|
|
11
|
+
default?: string;
|
|
12
|
+
}): string;
|
|
13
|
+
/**
|
|
14
|
+
* Reads an environment variable and converts it to a boolean.
|
|
15
|
+
*
|
|
16
|
+
* Any non-empty string is considered truthy, except for:
|
|
17
|
+
* - Values matching falsy definition in {@link https://yaml.org/type/bool.html | YAML 1.1 specification}
|
|
18
|
+
* - Zero-valued strings after a number conversion
|
|
19
|
+
*
|
|
20
|
+
* A falsy value is returned if the variable is unreadable.
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* env("ENV_VAR", { boolean: true, default: "false" })
|
|
24
|
+
* ```
|
|
25
|
+
*/ export declare function env(key: string, options: {
|
|
26
|
+
boolean: true;
|
|
27
|
+
default?: string;
|
|
28
|
+
}): boolean;
|
package/env.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads an environment variable.
|
|
3
|
+
*
|
|
4
|
+
* An empty string is returned if the variable is unreadable.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* env("ENV_VAR", { default: "foo" })
|
|
8
|
+
* ```
|
|
9
|
+
*/ export function env(key, { boolean = false, default: _default = "" } = {}) {
|
|
10
|
+
if (boolean) {
|
|
11
|
+
const value = env(key, {
|
|
12
|
+
boolean: false,
|
|
13
|
+
default: _default
|
|
14
|
+
});
|
|
15
|
+
if (+value === 0) return false;
|
|
16
|
+
return !/^([Nn]o?|NO|[Oo]ff|OFF|[Ff]alse|FALSE)$/.test(value);
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
if (Deno.permissions.querySync({
|
|
20
|
+
name: "env",
|
|
21
|
+
variable: key
|
|
22
|
+
}).state !== "granted") return _default;
|
|
23
|
+
return Deno.env.get(key) || _default;
|
|
24
|
+
} catch {
|
|
25
|
+
return _default;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMvdG9vbGJveC9lbnYudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSZWFkcyBhbiBlbnZpcm9ubWVudCB2YXJpYWJsZS5cbiAqXG4gKiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQgaWYgdGhlIHZhcmlhYmxlIGlzIHVucmVhZGFibGUuXG4gKlxuICogYGBgdHNcbiAqIGVudihcIkVOVl9WQVJcIiwgeyBkZWZhdWx0OiBcImZvb1wiIH0pXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVudihrZXk6IHN0cmluZywgb3B0aW9ucz86IHsgYm9vbGVhbj86IGZhbHNlOyBkZWZhdWx0Pzogc3RyaW5nIH0pOiBzdHJpbmdcbi8qKlxuICogUmVhZHMgYW4gZW52aXJvbm1lbnQgdmFyaWFibGUgYW5kIGNvbnZlcnRzIGl0IHRvIGEgYm9vbGVhbi5cbiAqXG4gKiBBbnkgbm9uLWVtcHR5IHN0cmluZyBpcyBjb25zaWRlcmVkIHRydXRoeSwgZXhjZXB0IGZvcjpcbiAqIC0gVmFsdWVzIG1hdGNoaW5nIGZhbHN5IGRlZmluaXRpb24gaW4ge0BsaW5rIGh0dHBzOi8veWFtbC5vcmcvdHlwZS9ib29sLmh0bWwgfCBZQU1MIDEuMSBzcGVjaWZpY2F0aW9ufVxuICogLSBaZXJvLXZhbHVlZCBzdHJpbmdzIGFmdGVyIGEgbnVtYmVyIGNvbnZlcnNpb25cbiAqXG4gKiBBIGZhbHN5IHZhbHVlIGlzIHJldHVybmVkIGlmIHRoZSB2YXJpYWJsZSBpcyB1bnJlYWRhYmxlLlxuICpcbiAqIGBgYHRzXG4gKiBlbnYoXCJFTlZfVkFSXCIsIHsgYm9vbGVhbjogdHJ1ZSwgZGVmYXVsdDogXCJmYWxzZVwiIH0pXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVudihrZXk6IHN0cmluZywgb3B0aW9uczogeyBib29sZWFuOiB0cnVlOyBkZWZhdWx0Pzogc3RyaW5nIH0pOiBib29sZWFuXG5leHBvcnQgZnVuY3Rpb24gZW52KGtleTogc3RyaW5nLCB7IGJvb2xlYW4gPSBmYWxzZSwgZGVmYXVsdDogX2RlZmF1bHQgPSBcIlwiIH0gPSB7fSkge1xuICBpZiAoYm9vbGVhbikge1xuICAgIGNvbnN0IHZhbHVlID0gZW52KGtleSwgeyBib29sZWFuOiBmYWxzZSwgZGVmYXVsdDogX2RlZmF1bHQgfSlcbiAgICBpZiAoK3ZhbHVlID09PSAwKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgcmV0dXJuICEvXihbTm5dbz98Tk98W09vXWZmfE9GRnxbRmZdYWxzZXxGQUxTRSkkLy50ZXN0KHZhbHVlKVxuICB9XG4gIHRyeSB7XG4gICAgaWYgKERlbm8ucGVybWlzc2lvbnMucXVlcnlTeW5jKHsgbmFtZTogXCJlbnZcIiwgdmFyaWFibGU6IGtleSB9KS5zdGF0ZSAhPT0gXCJncmFudGVkXCIpXG4gICAgICByZXR1cm4gX2RlZmF1bHRcbiAgICByZXR1cm4gRGVuby5lbnYuZ2V0KGtleSkgfHwgX2RlZmF1bHRcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIF9kZWZhdWx0XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Q0FRQyxHQWdCRCxPQUFPLFNBQVMsSUFBSSxHQUFXLEVBQUUsRUFBRSxVQUFVLEtBQUssRUFBRSxTQUFTLFdBQVcsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0VBQy9FLElBQUksU0FBUztJQUNYLE1BQU0sUUFBUSxJQUFJLEtBQUs7TUFBRSxTQUFTO01BQU8sU0FBUztJQUFTO0lBQzNELElBQUksQ0FBQyxVQUFVLEdBQ2IsT0FBTztJQUNULE9BQU8sQ0FBQywwQ0FBMEMsSUFBSSxDQUFDO0VBQ3pEO0VBQ0EsSUFBSTtJQUNGLElBQUksS0FBSyxXQUFXLENBQUMsU0FBUyxDQUFDO01BQUUsTUFBTTtNQUFPLFVBQVU7SUFBSSxHQUFHLEtBQUssS0FBSyxXQUN2RSxPQUFPO0lBQ1QsT0FBTyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUTtFQUM5QixFQUFFLE9BQU07SUFDTixPQUFPO0VBQ1Q7QUFDRiJ9
|
package/evaluate.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Evaluate an expression and return a string. */ export declare function evaluate(expression: string, context: Readonly<Record<PropertyKey, unknown>>, options: EvaluateOptions & {
|
|
2
|
+
sync: true;
|
|
3
|
+
return: typeof EvaluationReturn.String;
|
|
4
|
+
}): string;
|
|
5
|
+
/** Evaluate an expression and return a boolean. */ export declare function evaluate(expression: string, context: Readonly<Record<PropertyKey, unknown>>, options: EvaluateOptions & {
|
|
6
|
+
sync: true;
|
|
7
|
+
return: typeof EvaluationReturn.Boolean;
|
|
8
|
+
}): boolean;
|
|
9
|
+
/** Evaluate an expression against a context. */ export declare function evaluate(expression: string, context?: Readonly<Record<PropertyKey, unknown>>, options?: EvaluateOptions & {
|
|
10
|
+
sync: true;
|
|
11
|
+
}): unknown;
|
|
12
|
+
/** Evaluate an expression and return a string. */ export declare function evaluate(expression: string, context: Readonly<Record<PropertyKey, unknown>>, options: EvaluateOptions & {
|
|
13
|
+
sync?: false;
|
|
14
|
+
return: typeof EvaluationReturn.String;
|
|
15
|
+
}): Promise<string>;
|
|
16
|
+
/** Evaluate an expression and return a boolean. */ export declare function evaluate(expression: string, context: Readonly<Record<PropertyKey, unknown>>, options: EvaluateOptions & {
|
|
17
|
+
sync?: false;
|
|
18
|
+
return: typeof EvaluationReturn.Boolean;
|
|
19
|
+
}): Promise<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* Evaluate an expression against a context.
|
|
22
|
+
*
|
|
23
|
+
* The context is exposed to the expression through a `with` scope, meaning its entries can be referenced directly by name.
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { evaluate } from "./evaluate.ts"
|
|
27
|
+
* console.assert(await evaluate("${a + b}", { a: 1, b: 2 }) === 3)
|
|
28
|
+
* console.assert(await evaluate("foo${a}", { a: "bar" }) === "foobar")
|
|
29
|
+
* ```
|
|
30
|
+
*/ export declare function evaluate(expression: string, context?: Readonly<Record<PropertyKey, unknown>>, options?: EvaluateOptions & {
|
|
31
|
+
sync?: false;
|
|
32
|
+
}): Promise<unknown>;
|
|
33
|
+
/** Syntaxes supported by {@linkcode evaluate()}. */ export declare enum EvaluationSyntax {
|
|
34
|
+
/** Treat the expression as an implicit template literal: expressions wrapped in `${...}` are evaluated, anything else is returned as-is. */ Template,
|
|
35
|
+
/** Treat the expression as a single JavaScript expression. */ Block,
|
|
36
|
+
/** Treat the expression as an asynchronous function body, where `return` statements yield the result. */ Function
|
|
37
|
+
}
|
|
38
|
+
/** Coercions applicable to an {@linkcode evaluate()} result. */ export declare enum EvaluationReturn {
|
|
39
|
+
/** Return the result as-is. */ Unknown,
|
|
40
|
+
/** Coerce the result to a boolean. */ Boolean,
|
|
41
|
+
/** Coerce the result to a string. */ String
|
|
42
|
+
}
|
|
43
|
+
/** Options for {@linkcode evaluate()}. */ export type EvaluateOptions = {
|
|
44
|
+
/** Code evaluated before the expression, useful to declare constants or helper functions. */ preload?: string;
|
|
45
|
+
/** Syntax used to interpret the expression (defaults to {@linkcode EvaluationSyntax.Template}). */ syntax?: EvaluationSyntax;
|
|
46
|
+
/** Coercion applied to the result (defaults to {@linkcode EvaluationReturn.Unknown}). */ return?: EvaluationReturn;
|
|
47
|
+
/** Abort signal (ignored if running in sync mode). */ signal?: AbortSignal;
|
|
48
|
+
/** Whether to evaluate in a synchronous manner. */ sync?: boolean;
|
|
49
|
+
};
|
package/evaluate.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import { AsyncFunction } from "@lowlighter/typing/func";
|
|
3
|
+
/** Reserved identifier used internally by {@linkcode evaluate()} to share state with the evaluated expression. */ const reserved = "__evaluate__";
|
|
4
|
+
export function evaluate(expression, context = {}, { sync = false, preload, syntax = EvaluationSyntax.Template, return: coerce, signal } = {}) {
|
|
5
|
+
// Check whether the expression needs to be executed
|
|
6
|
+
let execute = syntax !== EvaluationSyntax.Template;
|
|
7
|
+
if (syntax === EvaluationSyntax.Template) {
|
|
8
|
+
// Unwrap expressions of the form `${...}`
|
|
9
|
+
if (expression.startsWith("${") && expression.endsWith("}") && coerce !== EvaluationReturn.String) {
|
|
10
|
+
let depth = 1;
|
|
11
|
+
let i = 2;
|
|
12
|
+
for(; i < expression.length && depth > 0; i++)depth += expression[i] === "{" ? 1 : expression[i] === "}" ? -1 : 0;
|
|
13
|
+
if (depth === 0 && i === expression.length) {
|
|
14
|
+
expression = expression.slice(2, -1).trim();
|
|
15
|
+
execute = true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// Quote implicit template literals
|
|
19
|
+
if (!execute && /\$\{[\s\S]*\}/.test(expression)) {
|
|
20
|
+
expression = `\`${expression}\``;
|
|
21
|
+
execute = true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (!execute) return sync ? expression : Promise.resolve(expression);
|
|
25
|
+
// Prevent internal state corruption from namespace collisions
|
|
26
|
+
if (reserved in context) {
|
|
27
|
+
const error = new ReferenceError(`"${reserved}" is a reserved variable name`);
|
|
28
|
+
if (sync) throw error;
|
|
29
|
+
return Promise.reject(error);
|
|
30
|
+
}
|
|
31
|
+
// Evaluate the expression
|
|
32
|
+
if (sync) {
|
|
33
|
+
try {
|
|
34
|
+
if (syntax === EvaluationSyntax.Function) expression = `(()=>{${expression}})()`;
|
|
35
|
+
const fn = new Function(reserved, `${preload};with(${reserved}.context){${reserved}.result=${expression}}return ${reserved}.result`);
|
|
36
|
+
const result = fn({
|
|
37
|
+
context,
|
|
38
|
+
result: undefined
|
|
39
|
+
});
|
|
40
|
+
return coerce === EvaluationReturn.String ? `${result}` : coerce === EvaluationReturn.Boolean ? !!result : result;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
if (error instanceof Error) delete error.stack;
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (syntax === EvaluationSyntax.Function) expression = `await(async()=>{${expression}})()`;
|
|
47
|
+
return (async ()=>{
|
|
48
|
+
const fn = new AsyncFunction(reserved, `${preload};with(${reserved}.context){${reserved}.result=${expression}}return ${reserved}.result`);
|
|
49
|
+
const result = await abortable(fn({
|
|
50
|
+
context,
|
|
51
|
+
result: undefined
|
|
52
|
+
}), signal);
|
|
53
|
+
return coerce === EvaluationReturn.String ? `${result}` : coerce === EvaluationReturn.Boolean ? !!result : result;
|
|
54
|
+
})().catch((error)=>{
|
|
55
|
+
if (error instanceof Error) delete error.stack;
|
|
56
|
+
throw error;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** Race a promise against an abort signal, rejecting with the signal reason upon abortion. */ async function abortable(promise, signal) {
|
|
60
|
+
if (!signal) return promise;
|
|
61
|
+
const { promise: aborted, reject } = Promise.withResolvers();
|
|
62
|
+
const onabort = ()=>reject(signal.reason);
|
|
63
|
+
signal.addEventListener("abort", onabort, {
|
|
64
|
+
once: true
|
|
65
|
+
});
|
|
66
|
+
try {
|
|
67
|
+
signal.throwIfAborted();
|
|
68
|
+
return await Promise.race([
|
|
69
|
+
promise,
|
|
70
|
+
aborted
|
|
71
|
+
]);
|
|
72
|
+
} finally{
|
|
73
|
+
signal.removeEventListener("abort", onabort);
|
|
74
|
+
// Mark a possible late settlement as handled to avoid unhandled rejections after abortion
|
|
75
|
+
promise.catch(()=>{});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Syntaxes supported by {@linkcode evaluate()}. */ export var EvaluationSyntax = /*#__PURE__*/ function(EvaluationSyntax) {
|
|
79
|
+
/** Treat the expression as an implicit template literal: expressions wrapped in `${...}` are evaluated, anything else is returned as-is. */ EvaluationSyntax[EvaluationSyntax["Template"] = 0] = "Template";
|
|
80
|
+
/** Treat the expression as a single JavaScript expression. */ EvaluationSyntax[EvaluationSyntax["Block"] = 1] = "Block";
|
|
81
|
+
/** Treat the expression as an asynchronous function body, where `return` statements yield the result. */ EvaluationSyntax[EvaluationSyntax["Function"] = 2] = "Function";
|
|
82
|
+
return EvaluationSyntax;
|
|
83
|
+
}({});
|
|
84
|
+
/** Coercions applicable to an {@linkcode evaluate()} result. */ export var EvaluationReturn = /*#__PURE__*/ function(EvaluationReturn) {
|
|
85
|
+
/** Return the result as-is. */ EvaluationReturn[EvaluationReturn["Unknown"] = 0] = "Unknown";
|
|
86
|
+
/** Coerce the result to a boolean. */ EvaluationReturn[EvaluationReturn["Boolean"] = 1] = "Boolean";
|
|
87
|
+
/** Coerce the result to a string. */ EvaluationReturn[EvaluationReturn["String"] = 2] = "String";
|
|
88
|
+
return EvaluationReturn;
|
|
89
|
+
}({});
|
|
90
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMvdG9vbGJveC9ldmFsdWF0ZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgeyBBc3luY0Z1bmN0aW9uIH0gZnJvbSBcIkBsaWJzL3R5cGluZy9mdW5jXCJcblxuLyoqIFJlc2VydmVkIGlkZW50aWZpZXIgdXNlZCBpbnRlcm5hbGx5IGJ5IHtAbGlua2NvZGUgZXZhbHVhdGUoKX0gdG8gc2hhcmUgc3RhdGUgd2l0aCB0aGUgZXZhbHVhdGVkIGV4cHJlc3Npb24uICovXG5jb25zdCByZXNlcnZlZCA9IFwiX19ldmFsdWF0ZV9fXCJcblxuLyoqIEV2YWx1YXRlIGFuIGV4cHJlc3Npb24gYW5kIHJldHVybiBhIHN0cmluZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBldmFsdWF0ZShleHByZXNzaW9uOiBzdHJpbmcsIGNvbnRleHQ6IFJlYWRvbmx5PFJlY29yZDxQcm9wZXJ0eUtleSwgdW5rbm93bj4+LCBvcHRpb25zOiBFdmFsdWF0ZU9wdGlvbnMgJiB7IHN5bmM6IHRydWU7IHJldHVybjogdHlwZW9mIEV2YWx1YXRpb25SZXR1cm4uU3RyaW5nIH0pOiBzdHJpbmdcbi8qKiBFdmFsdWF0ZSBhbiBleHByZXNzaW9uIGFuZCByZXR1cm4gYSBib29sZWFuLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV2YWx1YXRlKGV4cHJlc3Npb246IHN0cmluZywgY29udGV4dDogUmVhZG9ubHk8UmVjb3JkPFByb3BlcnR5S2V5LCB1bmtub3duPj4sIG9wdGlvbnM6IEV2YWx1YXRlT3B0aW9ucyAmIHsgc3luYzogdHJ1ZTsgcmV0dXJuOiB0eXBlb2YgRXZhbHVhdGlvblJldHVybi5Cb29sZWFuIH0pOiBib29sZWFuXG4vKiogRXZhbHVhdGUgYW4gZXhwcmVzc2lvbiBhZ2FpbnN0IGEgY29udGV4dC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBldmFsdWF0ZShleHByZXNzaW9uOiBzdHJpbmcsIGNvbnRleHQ/OiBSZWFkb25seTxSZWNvcmQ8UHJvcGVydHlLZXksIHVua25vd24+Piwgb3B0aW9ucz86IEV2YWx1YXRlT3B0aW9ucyAmIHsgc3luYzogdHJ1ZSB9KTogdW5rbm93blxuLyoqIEV2YWx1YXRlIGFuIGV4cHJlc3Npb24gYW5kIHJldHVybiBhIHN0cmluZy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBldmFsdWF0ZShleHByZXNzaW9uOiBzdHJpbmcsIGNvbnRleHQ6IFJlYWRvbmx5PFJlY29yZDxQcm9wZXJ0eUtleSwgdW5rbm93bj4+LCBvcHRpb25zOiBFdmFsdWF0ZU9wdGlvbnMgJiB7IHN5bmM/OiBmYWxzZTsgcmV0dXJuOiB0eXBlb2YgRXZhbHVhdGlvblJldHVybi5TdHJpbmcgfSk6IFByb21pc2U8c3RyaW5nPlxuLyoqIEV2YWx1YXRlIGFuIGV4cHJlc3Npb24gYW5kIHJldHVybiBhIGJvb2xlYW4uICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXZhbHVhdGUoZXhwcmVzc2lvbjogc3RyaW5nLCBjb250ZXh0OiBSZWFkb25seTxSZWNvcmQ8UHJvcGVydHlLZXksIHVua25vd24+Piwgb3B0aW9uczogRXZhbHVhdGVPcHRpb25zICYgeyBzeW5jPzogZmFsc2U7IHJldHVybjogdHlwZW9mIEV2YWx1YXRpb25SZXR1cm4uQm9vbGVhbiB9KTogUHJvbWlzZTxib29sZWFuPlxuLyoqXG4gKiBFdmFsdWF0ZSBhbiBleHByZXNzaW9uIGFnYWluc3QgYSBjb250ZXh0LlxuICpcbiAqIFRoZSBjb250ZXh0IGlzIGV4cG9zZWQgdG8gdGhlIGV4cHJlc3Npb24gdGhyb3VnaCBhIGB3aXRoYCBzY29wZSwgbWVhbmluZyBpdHMgZW50cmllcyBjYW4gYmUgcmVmZXJlbmNlZCBkaXJlY3RseSBieSBuYW1lLlxuICpcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBldmFsdWF0ZSB9IGZyb20gXCIuL2V2YWx1YXRlLnRzXCJcbiAqIGNvbnNvbGUuYXNzZXJ0KGF3YWl0IGV2YWx1YXRlKFwiJHthICsgYn1cIiwgeyBhOiAxLCBiOiAyIH0pID09PSAzKVxuICogY29uc29sZS5hc3NlcnQoYXdhaXQgZXZhbHVhdGUoXCJmb28ke2F9XCIsIHsgYTogXCJiYXJcIiB9KSA9PT0gXCJmb29iYXJcIilcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZXZhbHVhdGUoZXhwcmVzc2lvbjogc3RyaW5nLCBjb250ZXh0PzogUmVhZG9ubHk8UmVjb3JkPFByb3BlcnR5S2V5LCB1bmtub3duPj4sIG9wdGlvbnM/OiBFdmFsdWF0ZU9wdGlvbnMgJiB7IHN5bmM/OiBmYWxzZSB9KTogUHJvbWlzZTx1bmtub3duPlxuZXhwb3J0IGZ1bmN0aW9uIGV2YWx1YXRlKGV4cHJlc3Npb246IHN0cmluZywgY29udGV4dDogUmVhZG9ubHk8UmVjb3JkPFByb3BlcnR5S2V5LCB1bmtub3duPj4gPSB7fSwgeyBzeW5jID0gZmFsc2UsIHByZWxvYWQsIHN5bnRheCA9IEV2YWx1YXRpb25TeW50YXguVGVtcGxhdGUsIHJldHVybjogY29lcmNlLCBzaWduYWwgfTogRXZhbHVhdGVPcHRpb25zID0ge30pIHtcbiAgLy8gQ2hlY2sgd2hldGhlciB0aGUgZXhwcmVzc2lvbiBuZWVkcyB0byBiZSBleGVjdXRlZFxuICBsZXQgZXhlY3V0ZSA9IHN5bnRheCAhPT0gRXZhbHVhdGlvblN5bnRheC5UZW1wbGF0ZVxuICBpZiAoc3ludGF4ID09PSBFdmFsdWF0aW9uU3ludGF4LlRlbXBsYXRlKSB7XG4gICAgLy8gVW53cmFwIGV4cHJlc3Npb25zIG9mIHRoZSBmb3JtIGAkey4uLn1gXG4gICAgaWYgKGV4cHJlc3Npb24uc3RhcnRzV2l0aChcIiR7XCIpICYmIGV4cHJlc3Npb24uZW5kc1dpdGgoXCJ9XCIpICYmIChjb2VyY2UgIT09IEV2YWx1YXRpb25SZXR1cm4uU3RyaW5nKSkge1xuICAgICAgbGV0IGRlcHRoID0gMVxuICAgICAgbGV0IGkgPSAyXG4gICAgICBmb3IgKDsgKGkgPCBleHByZXNzaW9uLmxlbmd0aCkgJiYgKGRlcHRoID4gMCk7IGkrKylcbiAgICAgICAgZGVwdGggKz0gKGV4cHJlc3Npb25baV0gPT09IFwie1wiKSA/IDEgOiAoZXhwcmVzc2lvbltpXSA9PT0gXCJ9XCIpID8gLTEgOiAwXG4gICAgICBpZiAoKGRlcHRoID09PSAwKSAmJiAoaSA9PT0gZXhwcmVzc2lvbi5sZW5ndGgpKSB7XG4gICAgICAgIGV4cHJlc3Npb24gPSBleHByZXNzaW9uLnNsaWNlKDIsIC0xKS50cmltKClcbiAgICAgICAgZXhlY3V0ZSA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gUXVvdGUgaW1wbGljaXQgdGVtcGxhdGUgbGl0ZXJhbHNcbiAgICBpZiAoKCFleGVjdXRlKSAmJiAoL1xcJFxce1tcXHNcXFNdKlxcfS8udGVzdChleHByZXNzaW9uKSkpIHtcbiAgICAgIGV4cHJlc3Npb24gPSBgXFxgJHtleHByZXNzaW9ufVxcYGBcbiAgICAgIGV4ZWN1dGUgPSB0cnVlXG4gICAgfVxuICB9XG4gIGlmICghZXhlY3V0ZSlcbiAgICByZXR1cm4gc3luYyA/IGV4cHJlc3Npb24gOiBQcm9taXNlLnJlc29sdmUoZXhwcmVzc2lvbilcblxuICAvLyBQcmV2ZW50IGludGVybmFsIHN0YXRlIGNvcnJ1cHRpb24gZnJvbSBuYW1lc3BhY2UgY29sbGlzaW9uc1xuICBpZiAocmVzZXJ2ZWQgaW4gY29udGV4dCkge1xuICAgIGNvbnN0IGVycm9yID0gbmV3IFJlZmVyZW5jZUVycm9yKGBcIiR7cmVzZXJ2ZWR9XCIgaXMgYSByZXNlcnZlZCB2YXJpYWJsZSBuYW1lYClcbiAgICBpZiAoc3luYylcbiAgICAgIHRocm93IGVycm9yXG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yKVxuICB9XG5cbiAgLy8gRXZhbHVhdGUgdGhlIGV4cHJlc3Npb25cbiAgaWYgKHN5bmMpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKHN5bnRheCA9PT0gRXZhbHVhdGlvblN5bnRheC5GdW5jdGlvbilcbiAgICAgICAgZXhwcmVzc2lvbiA9IGAoKCk9Pnske2V4cHJlc3Npb259fSkoKWBcbiAgICAgIGNvbnN0IGZuID0gbmV3IEZ1bmN0aW9uKHJlc2VydmVkLCBgJHtwcmVsb2FkfTt3aXRoKCR7cmVzZXJ2ZWR9LmNvbnRleHQpeyR7cmVzZXJ2ZWR9LnJlc3VsdD0ke2V4cHJlc3Npb259fXJldHVybiAke3Jlc2VydmVkfS5yZXN1bHRgKVxuICAgICAgY29uc3QgcmVzdWx0ID0gZm4oeyBjb250ZXh0LCByZXN1bHQ6IHVuZGVmaW5lZCB9KVxuICAgICAgcmV0dXJuIGNvZXJjZSA9PT0gRXZhbHVhdGlvblJldHVybi5TdHJpbmcgPyBgJHtyZXN1bHR9YCA6IGNvZXJjZSA9PT0gRXZhbHVhdGlvblJldHVybi5Cb29sZWFuID8gISFyZXN1bHQgOiByZXN1bHRcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpXG4gICAgICAgIGRlbGV0ZSBlcnJvci5zdGFja1xuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9XG4gIH1cbiAgaWYgKHN5bnRheCA9PT0gRXZhbHVhdGlvblN5bnRheC5GdW5jdGlvbilcbiAgICBleHByZXNzaW9uID0gYGF3YWl0KGFzeW5jKCk9Pnske2V4cHJlc3Npb259fSkoKWBcbiAgcmV0dXJuIChhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZm4gPSBuZXcgQXN5bmNGdW5jdGlvbihyZXNlcnZlZCwgYCR7cHJlbG9hZH07d2l0aCgke3Jlc2VydmVkfS5jb250ZXh0KXske3Jlc2VydmVkfS5yZXN1bHQ9JHtleHByZXNzaW9ufX1yZXR1cm4gJHtyZXNlcnZlZH0ucmVzdWx0YClcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhYm9ydGFibGUoZm4oeyBjb250ZXh0LCByZXN1bHQ6IHVuZGVmaW5lZCB9KSwgc2lnbmFsKVxuICAgIHJldHVybiBjb2VyY2UgPT09IEV2YWx1YXRpb25SZXR1cm4uU3RyaW5nID8gYCR7cmVzdWx0fWAgOiBjb2VyY2UgPT09IEV2YWx1YXRpb25SZXR1cm4uQm9vbGVhbiA/ICEhcmVzdWx0IDogcmVzdWx0XG4gIH0pKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpXG4gICAgICBkZWxldGUgZXJyb3Iuc3RhY2tcbiAgICB0aHJvdyBlcnJvclxuICB9KVxufVxuXG4vKiogUmFjZSBhIHByb21pc2UgYWdhaW5zdCBhbiBhYm9ydCBzaWduYWwsIHJlamVjdGluZyB3aXRoIHRoZSBzaWduYWwgcmVhc29uIHVwb24gYWJvcnRpb24uICovXG5hc3luYyBmdW5jdGlvbiBhYm9ydGFibGU8VD4ocHJvbWlzZTogUHJvbWlzZTxUPiwgc2lnbmFsPzogQWJvcnRTaWduYWwpOiBQcm9taXNlPFQ+IHtcbiAgaWYgKCFzaWduYWwpXG4gICAgcmV0dXJuIHByb21pc2VcbiAgY29uc3QgeyBwcm9taXNlOiBhYm9ydGVkLCByZWplY3QgfSA9IFByb21pc2Uud2l0aFJlc29sdmVyczxuZXZlcj4oKVxuICBjb25zdCBvbmFib3J0ID0gKCkgPT4gcmVqZWN0KHNpZ25hbC5yZWFzb24pXG4gIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgb25hYm9ydCwgeyBvbmNlOiB0cnVlIH0pXG4gIHRyeSB7XG4gICAgc2lnbmFsLnRocm93SWZBYm9ydGVkKClcbiAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5yYWNlKFtwcm9taXNlLCBhYm9ydGVkXSlcbiAgfSBmaW5hbGx5IHtcbiAgICBzaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uYWJvcnQpXG4gICAgLy8gTWFyayBhIHBvc3NpYmxlIGxhdGUgc2V0dGxlbWVudCBhcyBoYW5kbGVkIHRvIGF2b2lkIHVuaGFuZGxlZCByZWplY3Rpb25zIGFmdGVyIGFib3J0aW9uXG4gICAgcHJvbWlzZS5jYXRjaCgoKSA9PiB7fSlcbiAgfVxufVxuXG4vKiogU3ludGF4ZXMgc3VwcG9ydGVkIGJ5IHtAbGlua2NvZGUgZXZhbHVhdGUoKX0uICovXG5leHBvcnQgZW51bSBFdmFsdWF0aW9uU3ludGF4IHtcbiAgLyoqIFRyZWF0IHRoZSBleHByZXNzaW9uIGFzIGFuIGltcGxpY2l0IHRlbXBsYXRlIGxpdGVyYWw6IGV4cHJlc3Npb25zIHdyYXBwZWQgaW4gYCR7Li4ufWAgYXJlIGV2YWx1YXRlZCwgYW55dGhpbmcgZWxzZSBpcyByZXR1cm5lZCBhcy1pcy4gKi9cbiAgVGVtcGxhdGUsXG4gIC8qKiBUcmVhdCB0aGUgZXhwcmVzc2lvbiBhcyBhIHNpbmdsZSBKYXZhU2NyaXB0IGV4cHJlc3Npb24uICovXG4gIEJsb2NrLFxuICAvKiogVHJlYXQgdGhlIGV4cHJlc3Npb24gYXMgYW4gYXN5bmNocm9ub3VzIGZ1bmN0aW9uIGJvZHksIHdoZXJlIGByZXR1cm5gIHN0YXRlbWVudHMgeWllbGQgdGhlIHJlc3VsdC4gKi9cbiAgRnVuY3Rpb24sXG59XG5cbi8qKiBDb2VyY2lvbnMgYXBwbGljYWJsZSB0byBhbiB7QGxpbmtjb2RlIGV2YWx1YXRlKCl9IHJlc3VsdC4gKi9cbmV4cG9ydCBlbnVtIEV2YWx1YXRpb25SZXR1cm4ge1xuICAvKiogUmV0dXJuIHRoZSByZXN1bHQgYXMtaXMuICovXG4gIFVua25vd24sXG4gIC8qKiBDb2VyY2UgdGhlIHJlc3VsdCB0byBhIGJvb2xlYW4uICovXG4gIEJvb2xlYW4sXG4gIC8qKiBDb2VyY2UgdGhlIHJlc3VsdCB0byBhIHN0cmluZy4gKi9cbiAgU3RyaW5nLFxufVxuXG4vKiogT3B0aW9ucyBmb3Ige0BsaW5rY29kZSBldmFsdWF0ZSgpfS4gKi9cbmV4cG9ydCB0eXBlIEV2YWx1YXRlT3B0aW9ucyA9IHtcbiAgLyoqIENvZGUgZXZhbHVhdGVkIGJlZm9yZSB0aGUgZXhwcmVzc2lvbiwgdXNlZnVsIHRvIGRlY2xhcmUgY29uc3RhbnRzIG9yIGhlbHBlciBmdW5jdGlvbnMuICovXG4gIHByZWxvYWQ/OiBzdHJpbmdcbiAgLyoqIFN5bnRheCB1c2VkIHRvIGludGVycHJldCB0aGUgZXhwcmVzc2lvbiAoZGVmYXVsdHMgdG8ge0BsaW5rY29kZSBFdmFsdWF0aW9uU3ludGF4LlRlbXBsYXRlfSkuICovXG4gIHN5bnRheD86IEV2YWx1YXRpb25TeW50YXhcbiAgLyoqIENvZXJjaW9uIGFwcGxpZWQgdG8gdGhlIHJlc3VsdCAoZGVmYXVsdHMgdG8ge0BsaW5rY29kZSBFdmFsdWF0aW9uUmV0dXJuLlVua25vd259KS4gKi9cbiAgcmV0dXJuPzogRXZhbHVhdGlvblJldHVyblxuICAvKiogQWJvcnQgc2lnbmFsIChpZ25vcmVkIGlmIHJ1bm5pbmcgaW4gc3luYyBtb2RlKS4gKi9cbiAgc2lnbmFsPzogQWJvcnRTaWduYWxcbiAgLyoqIFdoZXRoZXIgdG8gZXZhbHVhdGUgaW4gYSBzeW5jaHJvbm91cyBtYW5uZXIuICovXG4gIHN5bmM/OiBib29sZWFuXG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsVUFBVTtBQUNWLFNBQVMsYUFBYSxRQUFRLG9CQUFtQjtBQUVqRCxnSEFBZ0gsR0FDaEgsTUFBTSxXQUFXO0FBd0JqQixPQUFPLFNBQVMsU0FBUyxVQUFrQixFQUFFLFVBQWtELENBQUMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxLQUFLLEVBQUUsT0FBTyxFQUFFLFNBQVMsaUJBQWlCLFFBQVEsRUFBRSxRQUFRLE1BQU0sRUFBRSxNQUFNLEVBQW1CLEdBQUcsQ0FBQyxDQUFDO0VBQzVNLG9EQUFvRDtFQUNwRCxJQUFJLFVBQVUsV0FBVyxpQkFBaUIsUUFBUTtFQUNsRCxJQUFJLFdBQVcsaUJBQWlCLFFBQVEsRUFBRTtJQUN4QywwQ0FBMEM7SUFDMUMsSUFBSSxXQUFXLFVBQVUsQ0FBQyxTQUFTLFdBQVcsUUFBUSxDQUFDLFFBQVMsV0FBVyxpQkFBaUIsTUFBTSxFQUFHO01BQ25HLElBQUksUUFBUTtNQUNaLElBQUksSUFBSTtNQUNSLE1BQU8sQUFBQyxJQUFJLFdBQVcsTUFBTSxJQUFNLFFBQVEsR0FBSSxJQUM3QyxTQUFTLEFBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxNQUFPLElBQUksQUFBQyxVQUFVLENBQUMsRUFBRSxLQUFLLE1BQU8sQ0FBQyxJQUFJO01BQ3hFLElBQUksQUFBQyxVQUFVLEtBQU8sTUFBTSxXQUFXLE1BQU0sRUFBRztRQUM5QyxhQUFhLFdBQVcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUk7UUFDekMsVUFBVTtNQUNaO0lBQ0Y7SUFDQSxtQ0FBbUM7SUFDbkMsSUFBSSxBQUFDLENBQUMsV0FBYSxnQkFBZ0IsSUFBSSxDQUFDLGFBQWM7TUFDcEQsYUFBYSxDQUFDLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQztNQUNoQyxVQUFVO0lBQ1o7RUFDRjtFQUNBLElBQUksQ0FBQyxTQUNILE9BQU8sT0FBTyxhQUFhLFFBQVEsT0FBTyxDQUFDO0VBRTdDLDhEQUE4RDtFQUM5RCxJQUFJLFlBQVksU0FBUztJQUN2QixNQUFNLFFBQVEsSUFBSSxlQUFlLENBQUMsQ0FBQyxFQUFFLFNBQVMsNkJBQTZCLENBQUM7SUFDNUUsSUFBSSxNQUNGLE1BQU07SUFDUixPQUFPLFFBQVEsTUFBTSxDQUFDO0VBQ3hCO0VBRUEsMEJBQTBCO0VBQzFCLElBQUksTUFBTTtJQUNSLElBQUk7TUFDRixJQUFJLFdBQVcsaUJBQWlCLFFBQVEsRUFDdEMsYUFBYSxDQUFDLE1BQU0sRUFBRSxXQUFXLElBQUksQ0FBQztNQUN4QyxNQUFNLEtBQUssSUFBSSxTQUFTLFVBQVUsR0FBRyxRQUFRLE1BQU0sRUFBRSxTQUFTLFVBQVUsRUFBRSxTQUFTLFFBQVEsRUFBRSxXQUFXLFFBQVEsRUFBRSxTQUFTLE9BQU8sQ0FBQztNQUNuSSxNQUFNLFNBQVMsR0FBRztRQUFFO1FBQVMsUUFBUTtNQUFVO01BQy9DLE9BQU8sV0FBVyxpQkFBaUIsTUFBTSxHQUFHLEdBQUcsUUFBUSxHQUFHLFdBQVcsaUJBQWlCLE9BQU8sR0FBRyxDQUFDLENBQUMsU0FBUztJQUM3RyxFQUFFLE9BQU8sT0FBTztNQUNkLElBQUksaUJBQWlCLE9BQ25CLE9BQU8sTUFBTSxLQUFLO01BQ3BCLE1BQU07SUFDUjtFQUNGO0VBQ0EsSUFBSSxXQUFXLGlCQUFpQixRQUFRLEVBQ3RDLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRSxXQUFXLElBQUksQ0FBQztFQUNsRCxPQUFPLENBQUM7SUFDTixNQUFNLEtBQUssSUFBSSxjQUFjLFVBQVUsR0FBRyxRQUFRLE1BQU0sRUFBRSxTQUFTLFVBQVUsRUFBRSxTQUFTLFFBQVEsRUFBRSxXQUFXLFFBQVEsRUFBRSxTQUFTLE9BQU8sQ0FBQztJQUN4SSxNQUFNLFNBQVMsTUFBTSxVQUFVLEdBQUc7TUFBRTtNQUFTLFFBQVE7SUFBVSxJQUFJO0lBQ25FLE9BQU8sV0FBVyxpQkFBaUIsTUFBTSxHQUFHLEdBQUcsUUFBUSxHQUFHLFdBQVcsaUJBQWlCLE9BQU8sR0FBRyxDQUFDLENBQUMsU0FBUztFQUM3RyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUM7SUFDVixJQUFJLGlCQUFpQixPQUNuQixPQUFPLE1BQU0sS0FBSztJQUNwQixNQUFNO0VBQ1I7QUFDRjtBQUVBLDRGQUE0RixHQUM1RixlQUFlLFVBQWEsT0FBbUIsRUFBRSxNQUFvQjtFQUNuRSxJQUFJLENBQUMsUUFDSCxPQUFPO0VBQ1QsTUFBTSxFQUFFLFNBQVMsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLFFBQVEsYUFBYTtFQUMxRCxNQUFNLFVBQVUsSUFBTSxPQUFPLE9BQU8sTUFBTTtFQUMxQyxPQUFPLGdCQUFnQixDQUFDLFNBQVMsU0FBUztJQUFFLE1BQU07RUFBSztFQUN2RCxJQUFJO0lBQ0YsT0FBTyxjQUFjO0lBQ3JCLE9BQU8sTUFBTSxRQUFRLElBQUksQ0FBQztNQUFDO01BQVM7S0FBUTtFQUM5QyxTQUFVO0lBQ1IsT0FBTyxtQkFBbUIsQ0FBQyxTQUFTO0lBQ3BDLDBGQUEwRjtJQUMxRixRQUFRLEtBQUssQ0FBQyxLQUFPO0VBQ3ZCO0FBQ0Y7QUFFQSxrREFBa0QsR0FDbEQsT0FBTyxJQUFBLEFBQUssMENBQUE7RUFDViwwSUFBMEk7RUFFMUksNERBQTREO0VBRTVELHVHQUF1RztTQUw3RjtNQU9YO0FBRUQsOERBQThELEdBQzlELE9BQU8sSUFBQSxBQUFLLDBDQUFBO0VBQ1YsNkJBQTZCO0VBRTdCLG9DQUFvQztFQUVwQyxtQ0FBbUM7U0FMekI7TUFPWCJ9
|
package/events.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** An event emitter with strongly-typed event data. */ export declare class EventEmitter<T = unknown> {
|
|
2
|
+
/** Registers a listener for the specified event. */ on(event: string, listener: Listener<T>, {}?: {
|
|
3
|
+
}): void;
|
|
4
|
+
/** Unregisters all listeners for the specified event. */ off(event: string): void;
|
|
5
|
+
/** Unregisters a listener for the specified event. */ off(event: string, listener: Listener<T>): void;
|
|
6
|
+
/** Emits an event with the specified data. */ emit(event: string, data: T): void;
|
|
7
|
+
}
|
|
8
|
+
/** A listener invoked with the emitted event data. */ export type Listener<T = unknown> = (data: T) => void;
|
package/events.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** An event emitter with strongly-typed event data. */ export class EventEmitter {
|
|
2
|
+
/** Registered listeners mapped to their wrappers. */ #listeners = new Map();
|
|
3
|
+
/** Registers a listener for the specified event. */ on(event, listener, { once = false } = {}) {
|
|
4
|
+
const listeners = this.#listeners.getOrInsert(event, new Map());
|
|
5
|
+
if (!listeners.has(listener)) listeners.set(listener, once ? (data)=>listener(data) : listener);
|
|
6
|
+
}
|
|
7
|
+
off(event, listener) {
|
|
8
|
+
const listeners = this.#listeners.get(event);
|
|
9
|
+
if (!listener) {
|
|
10
|
+
listeners?.clear();
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (listeners?.has(listener)) listeners.delete(listener);
|
|
14
|
+
}
|
|
15
|
+
/** Emits an event with the specified data. */ emit(event, data) {
|
|
16
|
+
const listeners = this.#listeners.get(event);
|
|
17
|
+
if (!listeners) return;
|
|
18
|
+
// Snapshot registered listeners
|
|
19
|
+
for (const [listener, wrapper] of [
|
|
20
|
+
...listeners
|
|
21
|
+
]){
|
|
22
|
+
if (listeners.get(listener) !== wrapper) continue;
|
|
23
|
+
if (wrapper !== listener) listeners.delete(listener);
|
|
24
|
+
wrapper(data);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMvdG9vbGJveC9ldmVudHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIEFuIGV2ZW50IGVtaXR0ZXIgd2l0aCBzdHJvbmdseS10eXBlZCBldmVudCBkYXRhLiAqL1xuZXhwb3J0IGNsYXNzIEV2ZW50RW1pdHRlcjxUID0gdW5rbm93bj4ge1xuICAvKiogUmVnaXN0ZXJlZCBsaXN0ZW5lcnMgbWFwcGVkIHRvIHRoZWlyIHdyYXBwZXJzLiAqL1xuICAjbGlzdGVuZXJzID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxMaXN0ZW5lcjxUPiwgTGlzdGVuZXI8VD4+PigpXG5cbiAgLyoqIFJlZ2lzdGVycyBhIGxpc3RlbmVyIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LiAqL1xuICBvbihldmVudDogc3RyaW5nLCBsaXN0ZW5lcjogTGlzdGVuZXI8VD4sIHsgb25jZSA9IGZhbHNlIH0gPSB7fSk6IHZvaWQge1xuICAgIGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuI2xpc3RlbmVycy5nZXRPckluc2VydChldmVudCwgbmV3IE1hcCgpKVxuICAgIGlmICghbGlzdGVuZXJzLmhhcyhsaXN0ZW5lcikpXG4gICAgICBsaXN0ZW5lcnMuc2V0KGxpc3RlbmVyLCBvbmNlID8gKChkYXRhOiBUKSA9PiBsaXN0ZW5lcihkYXRhKSkgOiBsaXN0ZW5lcilcbiAgfVxuXG4gIC8qKiBVbnJlZ2lzdGVycyBhbGwgbGlzdGVuZXJzIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LiAqL1xuICBvZmYoZXZlbnQ6IHN0cmluZyk6IHZvaWRcbiAgLyoqIFVucmVnaXN0ZXJzIGEgbGlzdGVuZXIgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuICovXG4gIG9mZihldmVudDogc3RyaW5nLCBsaXN0ZW5lcjogTGlzdGVuZXI8VD4pOiB2b2lkXG4gIG9mZihldmVudDogc3RyaW5nLCBsaXN0ZW5lcj86IExpc3RlbmVyPFQ+KSB7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gdGhpcy4jbGlzdGVuZXJzLmdldChldmVudClcbiAgICBpZiAoIWxpc3RlbmVyKSB7XG4gICAgICBsaXN0ZW5lcnM/LmNsZWFyKClcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAobGlzdGVuZXJzPy5oYXMobGlzdGVuZXIpKVxuICAgICAgbGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lcilcbiAgfVxuXG4gIC8qKiBFbWl0cyBhbiBldmVudCB3aXRoIHRoZSBzcGVjaWZpZWQgZGF0YS4gKi9cbiAgZW1pdChldmVudDogc3RyaW5nLCBkYXRhOiBUKTogdm9pZCB7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gdGhpcy4jbGlzdGVuZXJzLmdldChldmVudClcbiAgICBpZiAoIWxpc3RlbmVycylcbiAgICAgIHJldHVyblxuICAgIC8vIFNuYXBzaG90IHJlZ2lzdGVyZWQgbGlzdGVuZXJzXG4gICAgZm9yIChjb25zdCBbbGlzdGVuZXIsIHdyYXBwZXJdIG9mIFsuLi5saXN0ZW5lcnNdKSB7XG4gICAgICBpZiAobGlzdGVuZXJzLmdldChsaXN0ZW5lcikgIT09IHdyYXBwZXIpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICBpZiAod3JhcHBlciAhPT0gbGlzdGVuZXIpXG4gICAgICAgIGxpc3RlbmVycy5kZWxldGUobGlzdGVuZXIpXG4gICAgICB3cmFwcGVyKGRhdGEpXG4gICAgfVxuICB9XG59XG5cbi8qKiBBIGxpc3RlbmVyIGludm9rZWQgd2l0aCB0aGUgZW1pdHRlZCBldmVudCBkYXRhLiAqL1xuZXhwb3J0IHR5cGUgTGlzdGVuZXI8VCA9IHVua25vd24+ID0gKGRhdGE6IFQpID0+IHZvaWRcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxxREFBcUQsR0FDckQsT0FBTyxNQUFNO0VBQ1gsbURBQW1ELEdBQ25ELENBQUEsU0FBVSxHQUFHLElBQUksTUFBNEM7RUFFN0Qsa0RBQWtELEdBQ2xELEdBQUcsS0FBYSxFQUFFLFFBQXFCLEVBQUUsRUFBRSxPQUFPLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFRO0lBQ3BFLE1BQU0sWUFBWSxJQUFJLENBQUMsQ0FBQSxTQUFVLENBQUMsV0FBVyxDQUFDLE9BQU8sSUFBSTtJQUN6RCxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsV0FDakIsVUFBVSxHQUFHLENBQUMsVUFBVSxPQUFRLENBQUMsT0FBWSxTQUFTLFFBQVM7RUFDbkU7RUFNQSxJQUFJLEtBQWEsRUFBRSxRQUFzQixFQUFFO0lBQ3pDLE1BQU0sWUFBWSxJQUFJLENBQUMsQ0FBQSxTQUFVLENBQUMsR0FBRyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxVQUFVO01BQ2IsV0FBVztNQUNYO0lBQ0Y7SUFDQSxJQUFJLFdBQVcsSUFBSSxXQUNqQixVQUFVLE1BQU0sQ0FBQztFQUNyQjtFQUVBLDRDQUE0QyxHQUM1QyxLQUFLLEtBQWEsRUFBRSxJQUFPLEVBQVE7SUFDakMsTUFBTSxZQUFZLElBQUksQ0FBQyxDQUFBLFNBQVUsQ0FBQyxHQUFHLENBQUM7SUFDdEMsSUFBSSxDQUFDLFdBQ0g7SUFDRixnQ0FBZ0M7SUFDaEMsS0FBSyxNQUFNLENBQUMsVUFBVSxRQUFRLElBQUk7U0FBSTtLQUFVLENBQUU7TUFDaEQsSUFBSSxVQUFVLEdBQUcsQ0FBQyxjQUFjLFNBQzlCO01BQ0YsSUFBSSxZQUFZLFVBQ2QsVUFBVSxNQUFNLENBQUM7TUFDbkIsUUFBUTtJQUNWO0VBQ0Y7QUFDRiJ9
|
package/filesystem.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Nullable } from "@lowlighter/typing";
|
|
2
|
+
export type { Nullable };
|
|
3
|
+
/** Gets the current working directory. */ export declare function cwd(): string;
|
|
4
|
+
/** Changes the current working directory. */ export declare function chdir(path: string | URL): string;
|
|
5
|
+
/** Gets the file type of a file path. */ export declare function filetype(path: string): Nullable<"file" | "directory">;
|
|
6
|
+
/** Options for {@linkcode list()}. */ export type ListOptions = {
|
|
7
|
+
/** Root directory to search in. Defaults to the current working directory. */ root?: string;
|
|
8
|
+
/** Whether to return relative paths. */ relative?: boolean;
|
|
9
|
+
/** Whether to include files in the results. */ files?: boolean;
|
|
10
|
+
/** Whether to include directories in the results. */ directories?: boolean;
|
|
11
|
+
/** List of glob patterns to be excluded from the expansion. */ exclude?: string[];
|
|
12
|
+
/** Whether globstar should be case-insensitive. */ caseInsensitive?: boolean;
|
|
13
|
+
/** Whether to follow symbolic links. */ followSymlinks?: boolean;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Lists all entries matching the given glob pattern in the specified root directory.
|
|
17
|
+
*
|
|
18
|
+
* Note that `files` and `directories` both default to `false`, at least one of them must be enabled to get any result.
|
|
19
|
+
*/ export declare function list(glob: string, {}?: ListOptions): Promise<string[]>;
|
package/filesystem.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Imports
|
|
2
|
+
import { expandGlob } from "@std/fs";
|
|
3
|
+
/** Gets the current working directory. */ export function cwd() {
|
|
4
|
+
return Deno.cwd().replaceAll("\\", "/");
|
|
5
|
+
}
|
|
6
|
+
/** Changes the current working directory. */ export function chdir(path) {
|
|
7
|
+
Deno.chdir(path);
|
|
8
|
+
return cwd();
|
|
9
|
+
}
|
|
10
|
+
/** Gets the file type of a file path. */ export function filetype(path) {
|
|
11
|
+
try {
|
|
12
|
+
const lstat = Deno.lstatSync(path);
|
|
13
|
+
if (lstat.isFile) return "file";
|
|
14
|
+
if (lstat.isDirectory) return "directory";
|
|
15
|
+
} catch {
|
|
16
|
+
// Ignore errors
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Lists all entries matching the given glob pattern in the specified root directory.
|
|
22
|
+
*
|
|
23
|
+
* Note that `files` and `directories` both default to `false`, at least one of them must be enabled to get any result.
|
|
24
|
+
*/ export async function list(glob, { root = cwd(), relative = true, files = false, directories = false, exclude, caseInsensitive, followSymlinks } = {}) {
|
|
25
|
+
root = root.replaceAll("\\", "/");
|
|
26
|
+
if (!root.endsWith("/")) root += "/";
|
|
27
|
+
const entries = await Array.fromAsync(expandGlob(glob, {
|
|
28
|
+
root,
|
|
29
|
+
canonicalize: true,
|
|
30
|
+
includeDirs: directories,
|
|
31
|
+
exclude,
|
|
32
|
+
caseInsensitive,
|
|
33
|
+
followSymlinks
|
|
34
|
+
}));
|
|
35
|
+
return entries.filter((entry)=>files && entry.isFile || directories && entry.isDirectory).map(({ path })=>{
|
|
36
|
+
path = path.replaceAll("\\", "/");
|
|
37
|
+
return relative && path.startsWith(root) ? path.slice(root.length) : path;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMvdG9vbGJveC9maWxlc3lzdGVtLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEltcG9ydHNcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUgfSBmcm9tIFwiQGxpYnMvdHlwaW5nXCJcbmltcG9ydCB7IGV4cGFuZEdsb2IgfSBmcm9tIFwiQHN0ZC9mc1wiXG5leHBvcnQgdHlwZSB7IE51bGxhYmxlIH1cblxuLyoqIEdldHMgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuICovXG5leHBvcnQgZnVuY3Rpb24gY3dkKCk6IHN0cmluZyB7XG4gIHJldHVybiBEZW5vLmN3ZCgpLnJlcGxhY2VBbGwoXCJcXFxcXCIsIFwiL1wiKVxufVxuXG4vKiogQ2hhbmdlcyB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGRpcihwYXRoOiBzdHJpbmcgfCBVUkwpOiBzdHJpbmcge1xuICBEZW5vLmNoZGlyKHBhdGgpXG4gIHJldHVybiBjd2QoKVxufVxuXG4vKiogR2V0cyB0aGUgZmlsZSB0eXBlIG9mIGEgZmlsZSBwYXRoLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGV0eXBlKHBhdGg6IHN0cmluZyk6IE51bGxhYmxlPFwiZmlsZVwiIHwgXCJkaXJlY3RvcnlcIj4ge1xuICB0cnkge1xuICAgIGNvbnN0IGxzdGF0ID0gRGVuby5sc3RhdFN5bmMocGF0aClcbiAgICBpZiAobHN0YXQuaXNGaWxlKVxuICAgICAgcmV0dXJuIFwiZmlsZVwiXG4gICAgaWYgKGxzdGF0LmlzRGlyZWN0b3J5KVxuICAgICAgcmV0dXJuIFwiZGlyZWN0b3J5XCJcbiAgfSBjYXRjaCB7XG4gICAgLy8gSWdub3JlIGVycm9yc1xuICB9XG4gIHJldHVybiBudWxsXG59XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmtjb2RlIGxpc3QoKX0uICovXG5leHBvcnQgdHlwZSBMaXN0T3B0aW9ucyA9IHtcbiAgLyoqIFJvb3QgZGlyZWN0b3J5IHRvIHNlYXJjaCBpbi4gRGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuICovXG4gIHJvb3Q/OiBzdHJpbmdcbiAgLyoqIFdoZXRoZXIgdG8gcmV0dXJuIHJlbGF0aXZlIHBhdGhzLiAqL1xuICByZWxhdGl2ZT86IGJvb2xlYW5cbiAgLyoqIFdoZXRoZXIgdG8gaW5jbHVkZSBmaWxlcyBpbiB0aGUgcmVzdWx0cy4gKi9cbiAgZmlsZXM/OiBib29sZWFuXG4gIC8qKiBXaGV0aGVyIHRvIGluY2x1ZGUgZGlyZWN0b3JpZXMgaW4gdGhlIHJlc3VsdHMuICovXG4gIGRpcmVjdG9yaWVzPzogYm9vbGVhblxuICAvKiogTGlzdCBvZiBnbG9iIHBhdHRlcm5zIHRvIGJlIGV4Y2x1ZGVkIGZyb20gdGhlIGV4cGFuc2lvbi4gKi9cbiAgZXhjbHVkZT86IHN0cmluZ1tdXG4gIC8qKiBXaGV0aGVyIGdsb2JzdGFyIHNob3VsZCBiZSBjYXNlLWluc2Vuc2l0aXZlLiAqL1xuICBjYXNlSW5zZW5zaXRpdmU/OiBib29sZWFuXG4gIC8qKiBXaGV0aGVyIHRvIGZvbGxvdyBzeW1ib2xpYyBsaW5rcy4gKi9cbiAgZm9sbG93U3ltbGlua3M/OiBib29sZWFuXG59XG5cbi8qKlxuICogTGlzdHMgYWxsIGVudHJpZXMgbWF0Y2hpbmcgdGhlIGdpdmVuIGdsb2IgcGF0dGVybiBpbiB0aGUgc3BlY2lmaWVkIHJvb3QgZGlyZWN0b3J5LlxuICpcbiAqIE5vdGUgdGhhdCBgZmlsZXNgIGFuZCBgZGlyZWN0b3JpZXNgIGJvdGggZGVmYXVsdCB0byBgZmFsc2VgLCBhdCBsZWFzdCBvbmUgb2YgdGhlbSBtdXN0IGJlIGVuYWJsZWQgdG8gZ2V0IGFueSByZXN1bHQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsaXN0KGdsb2I6IHN0cmluZywgeyByb290ID0gY3dkKCksIHJlbGF0aXZlID0gdHJ1ZSwgZmlsZXMgPSBmYWxzZSwgZGlyZWN0b3JpZXMgPSBmYWxzZSwgZXhjbHVkZSwgY2FzZUluc2Vuc2l0aXZlLCBmb2xsb3dTeW1saW5rcyB9OiBMaXN0T3B0aW9ucyA9IHt9KTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICByb290ID0gcm9vdC5yZXBsYWNlQWxsKFwiXFxcXFwiLCBcIi9cIilcbiAgaWYgKCFyb290LmVuZHNXaXRoKFwiL1wiKSlcbiAgICByb290ICs9IFwiL1wiXG4gIGNvbnN0IGVudHJpZXMgPSBhd2FpdCBBcnJheS5mcm9tQXN5bmMoZXhwYW5kR2xvYihnbG9iLCB7IHJvb3QsIGNhbm9uaWNhbGl6ZTogdHJ1ZSwgaW5jbHVkZURpcnM6IGRpcmVjdG9yaWVzLCBleGNsdWRlLCBjYXNlSW5zZW5zaXRpdmUsIGZvbGxvd1N5bWxpbmtzIH0pKVxuICByZXR1cm4gZW50cmllc1xuICAgIC5maWx0ZXIoKGVudHJ5KSA9PiAoZmlsZXMgJiYgZW50cnkuaXNGaWxlKSB8fCAoZGlyZWN0b3JpZXMgJiYgZW50cnkuaXNEaXJlY3RvcnkpKVxuICAgIC5tYXAoKHsgcGF0aCB9KSA9PiB7XG4gICAgICBwYXRoID0gcGF0aC5yZXBsYWNlQWxsKFwiXFxcXFwiLCBcIi9cIilcbiAgICAgIHJldHVybiAocmVsYXRpdmUgJiYgcGF0aC5zdGFydHNXaXRoKHJvb3QpKSA/IHBhdGguc2xpY2Uocm9vdC5sZW5ndGgpIDogcGF0aFxuICAgIH0pXG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsVUFBVTtBQUVWLFNBQVMsVUFBVSxRQUFRLFVBQVM7QUFHcEMsd0NBQXdDLEdBQ3hDLE9BQU8sU0FBUztFQUNkLE9BQU8sS0FBSyxHQUFHLEdBQUcsVUFBVSxDQUFDLE1BQU07QUFDckM7QUFFQSwyQ0FBMkMsR0FDM0MsT0FBTyxTQUFTLE1BQU0sSUFBa0I7RUFDdEMsS0FBSyxLQUFLLENBQUM7RUFDWCxPQUFPO0FBQ1Q7QUFFQSx1Q0FBdUMsR0FDdkMsT0FBTyxTQUFTLFNBQVMsSUFBWTtFQUNuQyxJQUFJO0lBQ0YsTUFBTSxRQUFRLEtBQUssU0FBUyxDQUFDO0lBQzdCLElBQUksTUFBTSxNQUFNLEVBQ2QsT0FBTztJQUNULElBQUksTUFBTSxXQUFXLEVBQ25CLE9BQU87RUFDWCxFQUFFLE9BQU07RUFDTixnQkFBZ0I7RUFDbEI7RUFDQSxPQUFPO0FBQ1Q7QUFvQkE7Ozs7Q0FJQyxHQUNELE9BQU8sZUFBZSxLQUFLLElBQVksRUFBRSxFQUFFLE9BQU8sS0FBSyxFQUFFLFdBQVcsSUFBSSxFQUFFLFFBQVEsS0FBSyxFQUFFLGNBQWMsS0FBSyxFQUFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFlLEdBQUcsQ0FBQyxDQUFDO0VBQ3hLLE9BQU8sS0FBSyxVQUFVLENBQUMsTUFBTTtFQUM3QixJQUFJLENBQUMsS0FBSyxRQUFRLENBQUMsTUFDakIsUUFBUTtFQUNWLE1BQU0sVUFBVSxNQUFNLE1BQU0sU0FBUyxDQUFDLFdBQVcsTUFBTTtJQUFFO0lBQU0sY0FBYztJQUFNLGFBQWE7SUFBYTtJQUFTO0lBQWlCO0VBQWU7RUFDdEosT0FBTyxRQUNKLE1BQU0sQ0FBQyxDQUFDLFFBQVUsQUFBQyxTQUFTLE1BQU0sTUFBTSxJQUFNLGVBQWUsTUFBTSxXQUFXLEVBQzlFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFO0lBQ1osT0FBTyxLQUFLLFVBQVUsQ0FBQyxNQUFNO0lBQzdCLE9BQU8sQUFBQyxZQUFZLEtBQUssVUFBVSxDQUFDLFFBQVMsS0FBSyxLQUFLLENBQUMsS0FBSyxNQUFNLElBQUk7RUFDekU7QUFDSiJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Lorem ipsum
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Lorem ipsum
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Lorem ipsum
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Lorem ipsum
|
package/format.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Format a country code as a flag emoji. */ export declare function countryFlag(code: string): string;
|
|
2
|
+
/** Normalize string to uppercase and remove diacritics. */ export declare function unfd(string: string): string;
|
|
3
|
+
/** Normalize string to lowercase and remove diacritics. */ export declare function lnfd(string: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* Strip emojis from a string.
|
|
6
|
+
*
|
|
7
|
+
* Keycap emojis are converted back to their base character
|
|
8
|
+
* and flag emojis back to their two-letter country code.
|
|
9
|
+
*/ export declare function stripEmojis(string: string): string;
|
package/format.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Format a country code as a flag emoji. */ export function countryFlag(code) {
|
|
2
|
+
const cc = code.trim().toUpperCase();
|
|
3
|
+
if (!/^[A-Z]{2}$/.test(cc)) return code;
|
|
4
|
+
const A = 0x1f1e6;
|
|
5
|
+
return String.fromCodePoint(A + (cc.charCodeAt(0) - 65), A + (cc.charCodeAt(1) - 65));
|
|
6
|
+
}
|
|
7
|
+
/** Normalize string to uppercase and remove diacritics. */ export function unfd(string) {
|
|
8
|
+
return string.toLocaleUpperCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
9
|
+
}
|
|
10
|
+
/** Normalize string to lowercase and remove diacritics. */ export function lnfd(string) {
|
|
11
|
+
return unfd(string).toLocaleLowerCase();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Strip emojis from a string.
|
|
15
|
+
*
|
|
16
|
+
* Keycap emojis are converted back to their base character
|
|
17
|
+
* and flag emojis back to their two-letter country code.
|
|
18
|
+
*/ export function stripEmojis(string) {
|
|
19
|
+
return string.replace(/([#*0-9])\uFE0F?\u20E3/gu, "$1").replace(/\p{Regional_Indicator}/gu, (char)=>String.fromCharCode(char.codePointAt(0) - 0x1f1e6 + 65)).replace(/\p{Extended_Pictographic}(?:\uFE0F|\p{Emoji_Modifier}|\u200D\p{Extended_Pictographic})*/gu, "");
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMvdG9vbGJveC9mb3JtYXQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIEZvcm1hdCBhIGNvdW50cnkgY29kZSBhcyBhIGZsYWcgZW1vamkuICovXG5leHBvcnQgZnVuY3Rpb24gY291bnRyeUZsYWcoY29kZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgY2MgPSBjb2RlLnRyaW0oKS50b1VwcGVyQ2FzZSgpXG4gIGlmICghL15bQS1aXXsyfSQvLnRlc3QoY2MpKVxuICAgIHJldHVybiBjb2RlXG4gIGNvbnN0IEEgPSAweDFmMWU2XG4gIHJldHVybiBTdHJpbmcuZnJvbUNvZGVQb2ludChBICsgKGNjLmNoYXJDb2RlQXQoMCkgLSA2NSksIEEgKyAoY2MuY2hhckNvZGVBdCgxKSAtIDY1KSlcbn1cblxuLyoqIE5vcm1hbGl6ZSBzdHJpbmcgdG8gdXBwZXJjYXNlIGFuZCByZW1vdmUgZGlhY3JpdGljcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bmZkKHN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0cmluZy50b0xvY2FsZVVwcGVyQ2FzZSgpLm5vcm1hbGl6ZShcIk5GRFwiKS5yZXBsYWNlKC9bXFx1MDMwMC1cXHUwMzZmXS9nLCBcIlwiKVxufVxuXG4vKiogTm9ybWFsaXplIHN0cmluZyB0byBsb3dlcmNhc2UgYW5kIHJlbW92ZSBkaWFjcml0aWNzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxuZmQoc3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdW5mZChzdHJpbmcpLnRvTG9jYWxlTG93ZXJDYXNlKClcbn1cblxuLyoqXG4gKiBTdHJpcCBlbW9qaXMgZnJvbSBhIHN0cmluZy5cbiAqXG4gKiBLZXljYXAgZW1vamlzIGFyZSBjb252ZXJ0ZWQgYmFjayB0byB0aGVpciBiYXNlIGNoYXJhY3RlclxuICogYW5kIGZsYWcgZW1vamlzIGJhY2sgdG8gdGhlaXIgdHdvLWxldHRlciBjb3VudHJ5IGNvZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHJpcEVtb2ppcyhzdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBzdHJpbmdcbiAgICAucmVwbGFjZSgvKFsjKjAtOV0pXFx1RkUwRj9cXHUyMEUzL2d1LCBcIiQxXCIpXG4gICAgLnJlcGxhY2UoL1xccHtSZWdpb25hbF9JbmRpY2F0b3J9L2d1LCAoY2hhcikgPT4gU3RyaW5nLmZyb21DaGFyQ29kZShjaGFyLmNvZGVQb2ludEF0KDApISAtIDB4MWYxZTYgKyA2NSkpXG4gICAgLnJlcGxhY2UoL1xccHtFeHRlbmRlZF9QaWN0b2dyYXBoaWN9KD86XFx1RkUwRnxcXHB7RW1vamlfTW9kaWZpZXJ9fFxcdTIwMERcXHB7RXh0ZW5kZWRfUGljdG9ncmFwaGljfSkqL2d1LCBcIlwiKVxufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDJDQUEyQyxHQUMzQyxPQUFPLFNBQVMsWUFBWSxJQUFZO0VBQ3RDLE1BQU0sS0FBSyxLQUFLLElBQUksR0FBRyxXQUFXO0VBQ2xDLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxLQUNyQixPQUFPO0VBQ1QsTUFBTSxJQUFJO0VBQ1YsT0FBTyxPQUFPLGFBQWEsQ0FBQyxJQUFJLENBQUMsR0FBRyxVQUFVLENBQUMsS0FBSyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsVUFBVSxDQUFDLEtBQUssRUFBRTtBQUNyRjtBQUVBLHlEQUF5RCxHQUN6RCxPQUFPLFNBQVMsS0FBSyxNQUFjO0VBQ2pDLE9BQU8sT0FBTyxpQkFBaUIsR0FBRyxTQUFTLENBQUMsT0FBTyxPQUFPLENBQUMsb0JBQW9CO0FBQ2pGO0FBRUEseURBQXlELEdBQ3pELE9BQU8sU0FBUyxLQUFLLE1BQWM7RUFDakMsT0FBTyxLQUFLLFFBQVEsaUJBQWlCO0FBQ3ZDO0FBRUE7Ozs7O0NBS0MsR0FDRCxPQUFPLFNBQVMsWUFBWSxNQUFjO0VBQ3hDLE9BQU8sT0FDSixPQUFPLENBQUMsNEJBQTRCLE1BQ3BDLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQyxPQUFTLE9BQU8sWUFBWSxDQUFDLEtBQUssV0FBVyxDQUFDLEtBQU0sVUFBVSxLQUNuRyxPQUFPLENBQUMsNkZBQTZGO0FBQzFHIn0=
|
package/identicon.d.ts
ADDED
package/identicon.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A deterministic identicon as an `svg+xml` data URL.
|
|
3
|
+
*
|
|
4
|
+
* A mirror-symmetric pixel grid with a seeded hue to generate a simple recognisable default avatar.
|
|
5
|
+
*/ export function identicon(seed, { size = 5 } = {}) {
|
|
6
|
+
if (!Number.isInteger(size) || size <= 0) throw new RangeError(`Invalid identicon size: ${size}`);
|
|
7
|
+
// FNV-1a 32-bit hash of the seed
|
|
8
|
+
let h = 0x811c9dc5;
|
|
9
|
+
for(let i = 0; i < seed.length; i++){
|
|
10
|
+
h ^= seed.charCodeAt(i);
|
|
11
|
+
h = Math.imul(h, 0x01000193);
|
|
12
|
+
}
|
|
13
|
+
h >>>= 0;
|
|
14
|
+
const hue = h % 360;
|
|
15
|
+
const fg = `hsl(${hue} 58% 62%)`;
|
|
16
|
+
const bg = `hsl(${hue} 26% 18%)`;
|
|
17
|
+
// Seed an LCG from the hash
|
|
18
|
+
let r = h || 1;
|
|
19
|
+
const next = ()=>r = Math.imul(r, 1103515245) + 12345 >>> 0;
|
|
20
|
+
const cells = [];
|
|
21
|
+
for(let y = 0; y < size; y++){
|
|
22
|
+
for(let x = 0; x < Math.ceil(size / 2); x++){
|
|
23
|
+
if (next() & 0x10000) {
|
|
24
|
+
cells.push(`<rect x="${x}" y="${y}" width="1" height="1"/>`);
|
|
25
|
+
if (x < Math.floor(size / 2)) cells.push(`<rect x="${size - 1 - x}" y="${y}" width="1" height="1"/>`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}" ` + `shape-rendering="crispEdges"><rect width="${size}" height="${size}" fill="${bg}"/>` + `<g fill="${fg}">${cells.join("")}</g></svg>`;
|
|
30
|
+
return `data:image/svg+xml;base64,${btoa(svg)}`;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMvdG9vbGJveC9pZGVudGljb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBIGRldGVybWluaXN0aWMgaWRlbnRpY29uIGFzIGFuIGBzdmcreG1sYCBkYXRhIFVSTC5cbiAqXG4gKiBBIG1pcnJvci1zeW1tZXRyaWMgcGl4ZWwgZ3JpZCB3aXRoIGEgc2VlZGVkIGh1ZSB0byBnZW5lcmF0ZSAgYSBzaW1wbGUgcmVjb2duaXNhYmxlIGRlZmF1bHQgYXZhdGFyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpY29uKHNlZWQ6IHN0cmluZywgeyBzaXplID0gNSB9ID0ge30pOiBzdHJpbmcge1xuICBpZiAoKCFOdW1iZXIuaXNJbnRlZ2VyKHNpemUpKSB8fCAoc2l6ZSA8PSAwKSlcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgSW52YWxpZCBpZGVudGljb24gc2l6ZTogJHtzaXplfWApXG4gIC8vIEZOVi0xYSAzMi1iaXQgaGFzaCBvZiB0aGUgc2VlZFxuICBsZXQgaCA9IDB4ODExYzlkYzVcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWVkLmxlbmd0aDsgaSsrKSB7XG4gICAgaCBePSBzZWVkLmNoYXJDb2RlQXQoaSlcbiAgICBoID0gTWF0aC5pbXVsKGgsIDB4MDEwMDAxOTMpXG4gIH1cbiAgaCA+Pj49IDBcbiAgY29uc3QgaHVlID0gaCAlIDM2MFxuICBjb25zdCBmZyA9IGBoc2woJHtodWV9IDU4JSA2MiUpYFxuICBjb25zdCBiZyA9IGBoc2woJHtodWV9IDI2JSAxOCUpYFxuICAvLyBTZWVkIGFuIExDRyBmcm9tIHRoZSBoYXNoXG4gIGxldCByID0gaCB8fCAxXG4gIGNvbnN0IG5leHQgPSAoKSA9PiAociA9IChNYXRoLmltdWwociwgMTEwMzUxNTI0NSkgKyAxMjM0NSkgPj4+IDApXG4gIGNvbnN0IGNlbGxzOiBzdHJpbmdbXSA9IFtdXG4gIGZvciAobGV0IHkgPSAwOyB5IDwgc2l6ZTsgeSsrKSB7XG4gICAgZm9yIChsZXQgeCA9IDA7IHggPCBNYXRoLmNlaWwoc2l6ZSAvIDIpOyB4KyspIHtcbiAgICAgIGlmIChuZXh0KCkgJiAweDEwMDAwKSB7XG4gICAgICAgIGNlbGxzLnB1c2goYDxyZWN0IHg9XCIke3h9XCIgeT1cIiR7eX1cIiB3aWR0aD1cIjFcIiBoZWlnaHQ9XCIxXCIvPmApXG4gICAgICAgIGlmICh4IDwgTWF0aC5mbG9vcihzaXplIC8gMikpXG4gICAgICAgICAgY2VsbHMucHVzaChgPHJlY3QgeD1cIiR7c2l6ZSAtIDEgLSB4fVwiIHk9XCIke3l9XCIgd2lkdGg9XCIxXCIgaGVpZ2h0PVwiMVwiLz5gKVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCBzdmcgPSBgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAke3NpemV9ICR7c2l6ZX1cIiBgICtcbiAgICBgc2hhcGUtcmVuZGVyaW5nPVwiY3Jpc3BFZGdlc1wiPjxyZWN0IHdpZHRoPVwiJHtzaXplfVwiIGhlaWdodD1cIiR7c2l6ZX1cIiBmaWxsPVwiJHtiZ31cIi8+YCArXG4gICAgYDxnIGZpbGw9XCIke2ZnfVwiPiR7Y2VsbHMuam9pbihcIlwiKX08L2c+PC9zdmc+YFxuICByZXR1cm4gYGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsJHtidG9hKHN2Zyl9YFxufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0NBSUMsR0FDRCxPQUFPLFNBQVMsVUFBVSxJQUFZLEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztFQUN2RCxJQUFJLEFBQUMsQ0FBQyxPQUFPLFNBQVMsQ0FBQyxTQUFXLFFBQVEsR0FDeEMsTUFBTSxJQUFJLFdBQVcsQ0FBQyx3QkFBd0IsRUFBRSxNQUFNO0VBQ3hELGlDQUFpQztFQUNqQyxJQUFJLElBQUk7RUFDUixJQUFLLElBQUksSUFBSSxHQUFHLElBQUksS0FBSyxNQUFNLEVBQUUsSUFBSztJQUNwQyxLQUFLLEtBQUssVUFBVSxDQUFDO0lBQ3JCLElBQUksS0FBSyxJQUFJLENBQUMsR0FBRztFQUNuQjtFQUNBLE9BQU87RUFDUCxNQUFNLE1BQU0sSUFBSTtFQUNoQixNQUFNLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxTQUFTLENBQUM7RUFDaEMsTUFBTSxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksU0FBUyxDQUFDO0VBQ2hDLDRCQUE0QjtFQUM1QixJQUFJLElBQUksS0FBSztFQUNiLE1BQU0sT0FBTyxJQUFPLElBQUksQUFBQyxLQUFLLElBQUksQ0FBQyxHQUFHLGNBQWMsVUFBVztFQUMvRCxNQUFNLFFBQWtCLEVBQUU7RUFDMUIsSUFBSyxJQUFJLElBQUksR0FBRyxJQUFJLE1BQU0sSUFBSztJQUM3QixJQUFLLElBQUksSUFBSSxHQUFHLElBQUksS0FBSyxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUs7TUFDNUMsSUFBSSxTQUFTLFNBQVM7UUFDcEIsTUFBTSxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxLQUFLLEVBQUUsRUFBRSx3QkFBd0IsQ0FBQztRQUMzRCxJQUFJLElBQUksS0FBSyxLQUFLLENBQUMsT0FBTyxJQUN4QixNQUFNLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxPQUFPLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSx3QkFBd0IsQ0FBQztNQUMxRTtJQUNGO0VBQ0Y7RUFDQSxNQUFNLE1BQU0sQ0FBQyxxREFBcUQsRUFBRSxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxHQUNsRixDQUFDLDBDQUEwQyxFQUFFLEtBQUssVUFBVSxFQUFFLEtBQUssUUFBUSxFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQ3BGLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRSxFQUFFLE1BQU0sSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDO0VBQy9DLE9BQU8sQ0FBQywwQkFBMEIsRUFBRSxLQUFLLE1BQU07QUFDakQifQ==
|
package/imgb64.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/** Download a remote PNG and return it as a base64 data URL. */ export declare function imgb64(url: string): Promise<string>;
|
package/imgb64.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { encodeBase64 } from "@std/encoding/base64";
|
|
2
|
+
/** Transparent 1x1 PNG data URL. */ const fallback = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==";
|
|
3
|
+
/** Download a remote PNG and return it as a base64 data URL. */ export async function imgb64(url) {
|
|
4
|
+
try {
|
|
5
|
+
const response = await fetch(url);
|
|
6
|
+
if (!response.ok) {
|
|
7
|
+
await response.body?.cancel();
|
|
8
|
+
return fallback;
|
|
9
|
+
}
|
|
10
|
+
return `data:image/png;base64,${encodeBase64(await response.arrayBuffer())}`;
|
|
11
|
+
} catch {
|
|
12
|
+
return fallback;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMvdG9vbGJveC9pbWdiNjQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZW5jb2RlQmFzZTY0IH0gZnJvbSBcIkBzdGQvZW5jb2RpbmcvYmFzZTY0XCJcblxuLyoqIFRyYW5zcGFyZW50IDF4MSBQTkcgZGF0YSBVUkwuICovXG5jb25zdCBmYWxsYmFjayA9IFwiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBRUFBQUFCQ0FBQUFBQTZmcHRWQUFBQUNrbEVRVlFJMTJOZ0FBQUFBZ0FCNGlHOE13QUFBQUJKUlU1RXJrSmdnZz09XCJcblxuLyoqIERvd25sb2FkIGEgcmVtb3RlIFBORyBhbmQgcmV0dXJuIGl0IGFzIGEgYmFzZTY0IGRhdGEgVVJMLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGltZ2I2NCh1cmw6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgYXdhaXQgcmVzcG9uc2UuYm9keT8uY2FuY2VsKClcbiAgICAgIHJldHVybiBmYWxsYmFja1xuICAgIH1cbiAgICByZXR1cm4gYGRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCwke2VuY29kZUJhc2U2NChhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpKX1gXG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxsYmFja1xuICB9XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsU0FBUyxZQUFZLFFBQVEsdUJBQXNCO0FBRW5ELGtDQUFrQyxHQUNsQyxNQUFNLFdBQVc7QUFFakIsOERBQThELEdBQzlELE9BQU8sZUFBZSxPQUFPLEdBQVc7RUFDdEMsSUFBSTtJQUNGLE1BQU0sV0FBVyxNQUFNLE1BQU07SUFDN0IsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFO01BQ2hCLE1BQU0sU0FBUyxJQUFJLEVBQUU7TUFDckIsT0FBTztJQUNUO0lBQ0EsT0FBTyxDQUFDLHNCQUFzQixFQUFFLGFBQWEsTUFBTSxTQUFTLFdBQVcsS0FBSztFQUM5RSxFQUFFLE9BQU07SUFDTixPQUFPO0VBQ1Q7QUFDRiJ9
|
package/mod.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// No default exports
|
package/noop.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/** No operation. */ export declare function noop(): void;
|
package/noop.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/** No operation. */ export function noop() {}
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMvdG9vbGJveC9ub29wLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBObyBvcGVyYXRpb24uICovXG5leHBvcnQgZnVuY3Rpb24gbm9vcCgpOiB2b2lkIHt9XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsa0JBQWtCLEdBQ2xCLE9BQU8sU0FBUyxRQUFjIn0=
|