unslash 1.0.1 → 1.0.2
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 +21 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +7 -0
- package/dist/pattern.d.ts +8 -2
- package/dist/pattern.js +1 -1
- package/dist/pattern.js.map +7 -0
- package/dist/slash.d.ts +6 -2
- package/dist/slash.js +2 -95
- package/dist/slash.js.map +7 -0
- package/dist/slashFn.d.ts +9 -0
- package/dist/slashFn.js +2 -0
- package/dist/slashFn.js.map +7 -0
- package/package.json +4 -5
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# `/` unslash
|
|
2
2
|
|
|
3
3
|
Stop wasting your life on slash normalization.<br />
|
|
4
|
+
Works everywhere ("everywhere" means in browsers too).<br />
|
|
4
5
|
Zero dependencies because why would I need any?
|
|
5
6
|
|
|
6
7
|
## Install
|
|
@@ -49,6 +50,25 @@ slash('tlfc', 'http://example.com', 'path', 'to', 'file');
|
|
|
49
50
|
// → 'http://example.com/path/to/file/'
|
|
50
51
|
```
|
|
51
52
|
|
|
53
|
+
You can import shorthand `s` versions (as default or named):
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import s, { s } from 'unslash';
|
|
57
|
+
|
|
58
|
+
s('t', 'path', 'to', 'file');
|
|
59
|
+
// → 'path/to/file/'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
If you need to create a reusable function with a fixed pattern, use `slashFn` or `sfn`:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { slashFn, sfn } from 'unslash';
|
|
66
|
+
const normalizePath = sfn('tlfc');
|
|
67
|
+
|
|
68
|
+
normalizePath('path\\to\\file');
|
|
69
|
+
// → '/path/to/file/'
|
|
70
|
+
```
|
|
71
|
+
|
|
52
72
|
## Pattern Flags
|
|
53
73
|
|
|
54
74
|
- `t` / `!t` — Add/remove **T**railing slash
|
|
@@ -61,6 +81,6 @@ slash('tlfc', 'http://example.com', 'path', 'to', 'file');
|
|
|
61
81
|
Yeah, I know.<br/>
|
|
62
82
|
I don’t give a shit.<br />
|
|
63
83
|
I was too lazy to look for them and made my own.<br />
|
|
64
|
-
|
|
84
|
+
Created with GPT help. Cry about it.
|
|
65
85
|
|
|
66
86
|
_It’d be cool if this package got popular and made me rich._
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export*from"./pattern.js";import{slash as r,s as o}from"./slash.js";import{slashFn as s,sfn as t}from"./slashFn.js";var p=o;export{p as default,o as s,t as sfn,r as slash,s as slashFn};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["export * from './pattern.js';\nimport { slash, s } from './slash.js';\nimport { slashFn, sfn } from './slashFn.js';\n\nexport default s;\nexport { slash, s, slashFn, sfn };\n"],
|
|
5
|
+
"mappings": "AAAA,WAAc,eACd,OAAS,SAAAA,EAAO,KAAAC,MAAS,aACzB,OAAS,WAAAC,EAAS,OAAAC,MAAW,eAE7B,IAAOC,EAAQH",
|
|
6
|
+
"names": ["slash", "s", "slashFn", "sfn", "index_default"]
|
|
7
|
+
}
|
package/dist/pattern.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type SlashBooleanFlag = 't' | 'l' | 'f';
|
|
2
|
+
export type SlashPlainFlag = 'c';
|
|
3
|
+
export type SlashFlag = SlashBooleanFlag | SlashPlainFlag;
|
|
2
4
|
export declare const unslash: unique symbol;
|
|
3
5
|
type link = 'https://github.com/Gwynerva/unslash';
|
|
4
6
|
export type UnknownFlagError<C extends string> = {
|
|
@@ -9,6 +11,10 @@ export type DuplicateFlagError<F extends string> = {
|
|
|
9
11
|
readonly [unslash]: link;
|
|
10
12
|
SlashPatternError: `Flag "${F}" is used more than once or both negated and non-negated`;
|
|
11
13
|
};
|
|
12
|
-
export type
|
|
14
|
+
export type InvalidNegationError<F extends string> = {
|
|
15
|
+
readonly [unslash]: link;
|
|
16
|
+
SlashPatternError: `Flag "${F}" cannot be negated`;
|
|
17
|
+
};
|
|
18
|
+
export type ValidateSlashPattern<S extends string, Pos extends string = never, Neg extends string = never> = S extends `!${infer L}${infer R}` ? L extends SlashFlag ? L extends SlashBooleanFlag ? L extends Pos | Neg ? DuplicateFlagError<L> : ValidateSlashPattern<R, Pos, Neg | L> : InvalidNegationError<L> : UnknownFlagError<`!${L}`> : S extends `${infer L}${infer R}` ? L extends SlashFlag ? L extends Pos | Neg ? DuplicateFlagError<L> : ValidateSlashPattern<R, Pos | L, Neg> : UnknownFlagError<L> : S;
|
|
13
19
|
export type SlashPattern<S extends string> = ValidateSlashPattern<S> extends string ? S : ValidateSlashPattern<S>;
|
|
14
20
|
export {};
|
package/dist/pattern.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
//# sourceMappingURL=pattern.js.map
|
package/dist/slash.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { SlashPattern } from './pattern.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Formats a string based on the given slash pattern.
|
|
4
4
|
* @param pattern
|
|
5
5
|
* A string of letters or their negations (prefixed with "!").
|
|
6
6
|
* Each letter represents a specific formatting rule:
|
|
7
7
|
* - `t` | `!t`: Ensure trailing slash is added | removed.
|
|
8
8
|
* - `l` | `!l`: Ensure leading slash is added | removed.
|
|
9
9
|
* - `f` | `!f`: Force forward | backward slashes.
|
|
10
|
-
* - `c`
|
|
10
|
+
* - `c` Collapse multiple adjacent slashes into a single slash.
|
|
11
11
|
*
|
|
12
12
|
* Example patterns:
|
|
13
13
|
* - `"tlfc"`: Ensure leading and trailing slashes, force forward slashes, collapse multiple slashes.
|
|
@@ -21,3 +21,7 @@ import type { SlashPattern } from './pattern.js';
|
|
|
21
21
|
* Protocols (like `http://`) are preserved and not altered by the formatting.
|
|
22
22
|
*/
|
|
23
23
|
export declare function slash<S extends string>(pattern: SlashPattern<S>, ...parts: string[]): string;
|
|
24
|
+
/**
|
|
25
|
+
* Shortened version of `slash`.
|
|
26
|
+
*/
|
|
27
|
+
export declare const s: typeof slash;
|
package/dist/slash.js
CHANGED
|
@@ -1,95 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @param pattern
|
|
4
|
-
* A string of letters or their negations (prefixed with "!").
|
|
5
|
-
* Each letter represents a specific formatting rule:
|
|
6
|
-
* - `t` | `!t`: Ensure trailing slash is added | removed.
|
|
7
|
-
* - `l` | `!l`: Ensure leading slash is added | removed.
|
|
8
|
-
* - `f` | `!f`: Force forward | backward slashes.
|
|
9
|
-
* - `c` | `!c`: Collapse multiple slashes into a single slash | Does nothing.
|
|
10
|
-
*
|
|
11
|
-
* Example patterns:
|
|
12
|
-
* - `"tlfc"`: Ensure leading and trailing slashes, force forward slashes, collapse multiple slashes.
|
|
13
|
-
* - `"lf"`: Force forward slashes and ensure leading slash (trailing might be present or absent).
|
|
14
|
-
* - `tl!f`: Ensure leading and trailing slashes, force backward slashes.
|
|
15
|
-
* @param parts
|
|
16
|
-
* The string parts to be formatted according to the specified pattern.
|
|
17
|
-
* They will be joined together using forward slashes by default (or backward slashes if `!f` is specified in the pattern).
|
|
18
|
-
* @returns
|
|
19
|
-
* The formatted string with slash-concatenated parts according to the specified slash pattern.
|
|
20
|
-
* Protocols (like `http://`) are preserved and not altered by the formatting.
|
|
21
|
-
*/
|
|
22
|
-
export function slash(pattern, ...parts) {
|
|
23
|
-
const flags = {};
|
|
24
|
-
// @ts-expect-error Pattern is validated at compile-time
|
|
25
|
-
pattern = pattern;
|
|
26
|
-
for (let i = 0; i < pattern.length; i++) {
|
|
27
|
-
const char = pattern[i];
|
|
28
|
-
const negated = char === '!';
|
|
29
|
-
const flag = negated ? pattern[i + 1] : char;
|
|
30
|
-
flags[flag] = !negated;
|
|
31
|
-
if (negated) {
|
|
32
|
-
i++;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
const slashChar = flags['f'] === false ? '\\' : '/';
|
|
36
|
-
// ------------------------------------------------------------
|
|
37
|
-
// Protocol-safe join
|
|
38
|
-
// ------------------------------------------------------------
|
|
39
|
-
let joined = parts.join(slashChar);
|
|
40
|
-
// Matches: scheme: or scheme://
|
|
41
|
-
// Examples: http://, file://, mailto:
|
|
42
|
-
const PROTOCOL_RE = /^([a-zA-Z][a-zA-Z\d+\-.]*:)(\/\/)?/;
|
|
43
|
-
let protocol = '';
|
|
44
|
-
const match = joined.match(PROTOCOL_RE);
|
|
45
|
-
if (match) {
|
|
46
|
-
protocol = match[0];
|
|
47
|
-
joined = joined.slice(protocol.length);
|
|
48
|
-
}
|
|
49
|
-
// ------------------------------------------------------------
|
|
50
|
-
// Force slash type (convert all slashes)
|
|
51
|
-
// ------------------------------------------------------------
|
|
52
|
-
if (flags['f'] === false) {
|
|
53
|
-
// Force backward slashes: convert all / to \
|
|
54
|
-
joined = joined.replace(/\//g, '\\');
|
|
55
|
-
}
|
|
56
|
-
else if (flags['f'] === true) {
|
|
57
|
-
// Force forward slashes: convert all \ to /
|
|
58
|
-
joined = joined.replace(/\\/g, '/');
|
|
59
|
-
}
|
|
60
|
-
// ------------------------------------------------------------
|
|
61
|
-
// Collapse multiple slashes
|
|
62
|
-
// ------------------------------------------------------------
|
|
63
|
-
if (flags['c']) {
|
|
64
|
-
const slashRegex = flags['f'] === false ? /\\+/g : /\/+/g;
|
|
65
|
-
const replacement = flags['f'] === false ? '\\' : '/';
|
|
66
|
-
joined = joined.replace(slashRegex, replacement);
|
|
67
|
-
}
|
|
68
|
-
// ------------------------------------------------------------
|
|
69
|
-
// Leading slash handling
|
|
70
|
-
// ------------------------------------------------------------
|
|
71
|
-
if (flags['l']) {
|
|
72
|
-
if (!joined.startsWith(slashChar)) {
|
|
73
|
-
joined = slashChar + joined;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
while (joined.startsWith('\\') || joined.startsWith('/')) {
|
|
78
|
-
joined = joined.slice(1);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// ------------------------------------------------------------
|
|
82
|
-
// Trailing slash handling
|
|
83
|
-
// ------------------------------------------------------------
|
|
84
|
-
if (flags['t']) {
|
|
85
|
-
if (!joined.endsWith(slashChar)) {
|
|
86
|
-
joined = joined + slashChar;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
while (joined.endsWith('\\') || joined.endsWith('/')) {
|
|
91
|
-
joined = joined.slice(0, -1);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return protocol + joined;
|
|
95
|
-
}
|
|
1
|
+
function g(l,...f){const e={};l=l;for(let t=0;t<l.length;t++){const n=l[t],c=n==="!",h=c?l[t+1]:n;e[h]=!c,c&&t++}const i=e.f===!1?"\\":"/";let s=f.join(i);const r=/^([a-zA-Z][a-zA-Z\d+\-.]*:)(\/\/)?/;let a="";const o=s.match(r);if(o&&(a=o[0],s=s.slice(a.length)),e.f===!1?s=s.replace(/\//g,"\\"):e.f===!0&&(s=s.replace(/\\/g,"/")),e.c){const t=e.f===!1?/\\+/g:/\/+/g,n=e.f===!1?"\\":"/";s=s.replace(t,n)}if(e.l)s.startsWith(i)||(s=i+s);else for(;s.startsWith("\\")||s.startsWith("/");)s=s.slice(1);if(e.t)s.endsWith(i)||(s=s+i);else for(;s.endsWith("\\")||s.endsWith("/");)s=s.slice(0,-1);return a+s}const d=g;export{d as s,g as slash};
|
|
2
|
+
//# sourceMappingURL=slash.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/slash.ts"],
|
|
4
|
+
"sourcesContent": ["import type { SlashPattern } from './pattern.js';\n\n/**\n * Formats a string based on the given slash pattern.\n * @param pattern\n * A string of letters or their negations (prefixed with \"!\").\n * Each letter represents a specific formatting rule:\n * - `t` | `!t`: Ensure trailing slash is added | removed.\n * - `l` | `!l`: Ensure leading slash is added | removed.\n * - `f` | `!f`: Force forward | backward slashes.\n * - `c` Collapse multiple adjacent slashes into a single slash.\n *\n * Example patterns:\n * - `\"tlfc\"`: Ensure leading and trailing slashes, force forward slashes, collapse multiple slashes.\n * - `\"lf\"`: Force forward slashes and ensure leading slash (trailing might be present or absent).\n * - `tl!f`: Ensure leading and trailing slashes, force backward slashes.\n * @param parts\n * The string parts to be formatted according to the specified pattern.\n * They will be joined together using forward slashes by default (or backward slashes if `!f` is specified in the pattern).\n * @returns\n * The formatted string with slash-concatenated parts according to the specified slash pattern.\n * Protocols (like `http://`) are preserved and not altered by the formatting.\n */\nexport function slash<S extends string>(\n pattern: SlashPattern<S>,\n ...parts: string[]\n): string {\n const flags: Record<string, boolean> = {};\n\n // @ts-expect-error Pattern is validated at compile-time\n pattern = pattern as string;\n\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n const negated = char === '!';\n const flag = negated ? pattern[i + 1] : char;\n\n flags[flag] = !negated;\n\n if (negated) {\n i++;\n }\n }\n\n const slashChar = flags['f'] === false ? '\\\\' : '/';\n\n // ------------------------------------------------------------\n // Protocol-safe join\n // ------------------------------------------------------------\n\n let joined = parts.join(slashChar);\n\n // Matches: scheme: or scheme://\n // Examples: http://, file://, mailto:\n const PROTOCOL_RE = /^([a-zA-Z][a-zA-Z\\d+\\-.]*:)(\\/\\/)?/;\n\n let protocol = '';\n const match = joined.match(PROTOCOL_RE);\n\n if (match) {\n protocol = match[0];\n joined = joined.slice(protocol.length);\n }\n\n // ------------------------------------------------------------\n // Force slash type (convert all slashes)\n // ------------------------------------------------------------\n\n if (flags['f'] === false) {\n // Force backward slashes: convert all / to \\\n joined = joined.replace(/\\//g, '\\\\');\n } else if (flags['f'] === true) {\n // Force forward slashes: convert all \\ to /\n joined = joined.replace(/\\\\/g, '/');\n }\n\n // ------------------------------------------------------------\n // Collapse multiple slashes\n // ------------------------------------------------------------\n\n if (flags['c']) {\n const slashRegex = flags['f'] === false ? /\\\\+/g : /\\/+/g;\n const replacement = flags['f'] === false ? '\\\\' : '/';\n joined = joined.replace(slashRegex, replacement);\n }\n\n // ------------------------------------------------------------\n // Leading slash handling\n // ------------------------------------------------------------\n\n if (flags['l']) {\n if (!joined.startsWith(slashChar)) {\n joined = slashChar + joined;\n }\n } else {\n while (joined.startsWith('\\\\') || joined.startsWith('/')) {\n joined = joined.slice(1);\n }\n }\n\n // ------------------------------------------------------------\n // Trailing slash handling\n // ------------------------------------------------------------\n\n if (flags['t']) {\n if (!joined.endsWith(slashChar)) {\n joined = joined + slashChar;\n }\n } else {\n while (joined.endsWith('\\\\') || joined.endsWith('/')) {\n joined = joined.slice(0, -1);\n }\n }\n\n return protocol + joined;\n}\n\n/**\n * Shortened version of `slash`.\n */\nexport const s = slash;\n"],
|
|
5
|
+
"mappings": "AAuBO,SAASA,EACdC,KACGC,EACK,CACR,MAAMC,EAAiC,CAAC,EAGxCF,EAAUA,EAEV,QAASG,EAAI,EAAGA,EAAIH,EAAQ,OAAQG,IAAK,CACvC,MAAMC,EAAOJ,EAAQG,CAAC,EAChBE,EAAUD,IAAS,IACnBE,EAAOD,EAAUL,EAAQG,EAAI,CAAC,EAAIC,EAExCF,EAAMI,CAAI,EAAI,CAACD,EAEXA,GACFF,GAEJ,CAEA,MAAMI,EAAYL,EAAM,IAAS,GAAQ,KAAO,IAMhD,IAAIM,EAASP,EAAM,KAAKM,CAAS,EAIjC,MAAME,EAAc,qCAEpB,IAAIC,EAAW,GACf,MAAMC,EAAQH,EAAO,MAAMC,CAAW,EAuBtC,GArBIE,IACFD,EAAWC,EAAM,CAAC,EAClBH,EAASA,EAAO,MAAME,EAAS,MAAM,GAOnCR,EAAM,IAAS,GAEjBM,EAASA,EAAO,QAAQ,MAAO,IAAI,EAC1BN,EAAM,IAAS,KAExBM,EAASA,EAAO,QAAQ,MAAO,GAAG,GAOhCN,EAAM,EAAM,CACd,MAAMU,EAAaV,EAAM,IAAS,GAAQ,OAAS,OAC7CW,EAAcX,EAAM,IAAS,GAAQ,KAAO,IAClDM,EAASA,EAAO,QAAQI,EAAYC,CAAW,CACjD,CAMA,GAAIX,EAAM,EACHM,EAAO,WAAWD,CAAS,IAC9BC,EAASD,EAAYC,OAGvB,MAAOA,EAAO,WAAW,IAAI,GAAKA,EAAO,WAAW,GAAG,GACrDA,EAASA,EAAO,MAAM,CAAC,EAQ3B,GAAIN,EAAM,EACHM,EAAO,SAASD,CAAS,IAC5BC,EAASA,EAASD,OAGpB,MAAOC,EAAO,SAAS,IAAI,GAAKA,EAAO,SAAS,GAAG,GACjDA,EAASA,EAAO,MAAM,EAAG,EAAE,EAI/B,OAAOE,EAAWF,CACpB,CAKO,MAAMM,EAAIf",
|
|
6
|
+
"names": ["slash", "pattern", "parts", "flags", "i", "char", "negated", "flag", "slashChar", "joined", "PROTOCOL_RE", "protocol", "match", "slashRegex", "replacement", "s"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SlashPattern } from './pattern.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a slash formatter with a fixed pattern for multiple uses.
|
|
4
|
+
* @param pattern
|
|
5
|
+
* See `slash` function for pattern documentation.
|
|
6
|
+
*/
|
|
7
|
+
export declare function slashFn<S extends string>(pattern: SlashPattern<S>): (...parts: string[]) => string;
|
|
8
|
+
/** Shortened version of `slashFn`. */
|
|
9
|
+
export declare const sfn: typeof slashFn;
|
package/dist/slashFn.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/slashFn.ts"],
|
|
4
|
+
"sourcesContent": ["import type { SlashPattern } from './pattern.js';\r\nimport { slash } from './slash.js';\r\n\r\n/**\r\n * Creates a slash formatter with a fixed pattern for multiple uses.\r\n * @param pattern\r\n * See `slash` function for pattern documentation.\r\n */\r\nexport function slashFn<S extends string>(pattern: SlashPattern<S>) {\r\n return (...parts: string[]) => slash(pattern, ...parts);\r\n}\r\n\r\n/** Shortened version of `slashFn`. */\r\nexport const sfn = slashFn;\r\n"],
|
|
5
|
+
"mappings": "AACA,OAAS,SAAAA,MAAa,aAOf,SAASC,EAA0BC,EAA0B,CAClE,MAAO,IAAIC,IAAoBH,EAAME,EAAS,GAAGC,CAAK,CACxD,CAGO,MAAMC,EAAMH",
|
|
6
|
+
"names": ["slash", "slashFn", "pattern", "parts", "sfn"]
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unslash",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "🤬 No more pain with slashes!",
|
|
6
6
|
"keywords": [
|
|
@@ -11,10 +11,8 @@
|
|
|
11
11
|
"url",
|
|
12
12
|
"trailing-slash",
|
|
13
13
|
"leading-slash",
|
|
14
|
-
"router",
|
|
15
14
|
"base-path",
|
|
16
15
|
"cross-platform",
|
|
17
|
-
"windows",
|
|
18
16
|
"utilities"
|
|
19
17
|
],
|
|
20
18
|
"license": "MIT",
|
|
@@ -34,7 +32,7 @@
|
|
|
34
32
|
"dist"
|
|
35
33
|
],
|
|
36
34
|
"scripts": {
|
|
37
|
-
"build": "rm -rf dist && tsc
|
|
35
|
+
"build": "rm -rf dist && tsc -p ./tsconfig.src.json && esbuild src/**/*.ts --outdir=dist --minify --sourcemap --format=esm",
|
|
38
36
|
"prepack": "bun run build",
|
|
39
37
|
"format": "bun prettier --write .",
|
|
40
38
|
"test": "bun vitest run"
|
|
@@ -42,6 +40,7 @@
|
|
|
42
40
|
"devDependencies": {
|
|
43
41
|
"prettier": "^3.8.1",
|
|
44
42
|
"typescript": "^5.9.3",
|
|
45
|
-
"vitest": "^4.0.18"
|
|
43
|
+
"vitest": "^4.0.18",
|
|
44
|
+
"esbuild": "^0.27.2"
|
|
46
45
|
}
|
|
47
46
|
}
|