@regardio/js 0.6.0 → 0.7.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/dist/assert/index.d.mts +45 -0
- package/dist/assert/index.mjs +57 -0
- package/dist/encoding/index.d.mts +14 -0
- package/dist/encoding/index.mjs +25 -0
- package/dist/http/index.d.mts +53 -0
- package/dist/http/index.mjs +122 -0
- package/dist/intl/index.d.mts +92 -0
- package/dist/intl/index.mjs +124 -0
- package/dist/text/index.d.mts +48 -0
- package/dist/text/index.mjs +223 -0
- package/dist/time/index.d.mts +22 -0
- package/dist/time/index.mjs +154 -0
- package/package.json +21 -21
- package/dist/assert/index.d.ts +0 -43
- package/dist/assert/index.js +0 -22
- package/dist/encoding/index.d.ts +0 -13
- package/dist/encoding/index.js +0 -18
- package/dist/http/index.d.ts +0 -49
- package/dist/http/index.js +0 -126
- package/dist/intl/index.d.ts +0 -91
- package/dist/intl/index.js +0 -139
- package/dist/text/index.d.ts +0 -46
- package/dist/text/index.js +0 -109
- package/dist/time/index.d.ts +0 -48
- package/dist/time/index.js +0 -157
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
//#region src/text/bytes.ts
|
|
2
|
+
function formatBytes(bytes, decimals = 2) {
|
|
3
|
+
if (!+bytes) return "0 Bytes";
|
|
4
|
+
/** Converts on base 10
|
|
5
|
+
* In binary - change k to 1024
|
|
6
|
+
*/
|
|
7
|
+
const k = 1e3;
|
|
8
|
+
const dm = decimals < 0 ? 0 : decimals;
|
|
9
|
+
const sizes = [
|
|
10
|
+
"Bytes",
|
|
11
|
+
"KB",
|
|
12
|
+
"MB",
|
|
13
|
+
"GB",
|
|
14
|
+
"TB",
|
|
15
|
+
"PB",
|
|
16
|
+
"EB",
|
|
17
|
+
"ZB",
|
|
18
|
+
"YB"
|
|
19
|
+
];
|
|
20
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
21
|
+
return `${Number.parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/text/text.ts
|
|
26
|
+
/**
|
|
27
|
+
* Locale-specific typographic quote styles
|
|
28
|
+
* Using Unicode escape sequences to avoid encoding issues
|
|
29
|
+
* @see https://en.wikipedia.org/wiki/Quotation_mark#Summary_table
|
|
30
|
+
*/
|
|
31
|
+
const quoteStyles = {
|
|
32
|
+
cs: {
|
|
33
|
+
close: "”",
|
|
34
|
+
closeSingle: "’",
|
|
35
|
+
open: "„",
|
|
36
|
+
openSingle: "‚"
|
|
37
|
+
},
|
|
38
|
+
da: {
|
|
39
|
+
close: "«",
|
|
40
|
+
closeSingle: "›",
|
|
41
|
+
open: "»",
|
|
42
|
+
openSingle: "‹"
|
|
43
|
+
},
|
|
44
|
+
de: {
|
|
45
|
+
close: "”",
|
|
46
|
+
closeSingle: "’",
|
|
47
|
+
open: "„",
|
|
48
|
+
openSingle: "‚"
|
|
49
|
+
},
|
|
50
|
+
"de-ch": {
|
|
51
|
+
close: "»",
|
|
52
|
+
closeSingle: "›",
|
|
53
|
+
open: "«",
|
|
54
|
+
openSingle: "‹"
|
|
55
|
+
},
|
|
56
|
+
en: {
|
|
57
|
+
close: "”",
|
|
58
|
+
closeSingle: "’",
|
|
59
|
+
open: "“",
|
|
60
|
+
openSingle: "‘"
|
|
61
|
+
},
|
|
62
|
+
es: {
|
|
63
|
+
close: "»",
|
|
64
|
+
closeSingle: "”",
|
|
65
|
+
open: "«",
|
|
66
|
+
openSingle: "“"
|
|
67
|
+
},
|
|
68
|
+
fi: {
|
|
69
|
+
close: "”",
|
|
70
|
+
closeSingle: "’",
|
|
71
|
+
open: "”",
|
|
72
|
+
openSingle: "’"
|
|
73
|
+
},
|
|
74
|
+
fr: {
|
|
75
|
+
close: " »",
|
|
76
|
+
closeSingle: " ›",
|
|
77
|
+
open: "« ",
|
|
78
|
+
openSingle: "‹ "
|
|
79
|
+
},
|
|
80
|
+
hu: {
|
|
81
|
+
close: "”",
|
|
82
|
+
closeSingle: "’",
|
|
83
|
+
open: "„",
|
|
84
|
+
openSingle: "‚"
|
|
85
|
+
},
|
|
86
|
+
it: {
|
|
87
|
+
close: "»",
|
|
88
|
+
closeSingle: "”",
|
|
89
|
+
open: "«",
|
|
90
|
+
openSingle: "“"
|
|
91
|
+
},
|
|
92
|
+
ja: {
|
|
93
|
+
close: "」",
|
|
94
|
+
closeSingle: "』",
|
|
95
|
+
open: "「",
|
|
96
|
+
openSingle: "『"
|
|
97
|
+
},
|
|
98
|
+
nl: {
|
|
99
|
+
close: "’",
|
|
100
|
+
closeSingle: "’",
|
|
101
|
+
open: "‘",
|
|
102
|
+
openSingle: "‘"
|
|
103
|
+
},
|
|
104
|
+
no: {
|
|
105
|
+
close: "«",
|
|
106
|
+
closeSingle: "›",
|
|
107
|
+
open: "»",
|
|
108
|
+
openSingle: "‹"
|
|
109
|
+
},
|
|
110
|
+
pl: {
|
|
111
|
+
close: "”",
|
|
112
|
+
closeSingle: "’",
|
|
113
|
+
open: "„",
|
|
114
|
+
openSingle: "‚"
|
|
115
|
+
},
|
|
116
|
+
pt: {
|
|
117
|
+
close: "»",
|
|
118
|
+
closeSingle: "”",
|
|
119
|
+
open: "«",
|
|
120
|
+
openSingle: "“"
|
|
121
|
+
},
|
|
122
|
+
ru: {
|
|
123
|
+
close: "»",
|
|
124
|
+
closeSingle: "’",
|
|
125
|
+
open: "«",
|
|
126
|
+
openSingle: "‚"
|
|
127
|
+
},
|
|
128
|
+
sv: {
|
|
129
|
+
close: "”",
|
|
130
|
+
closeSingle: "’",
|
|
131
|
+
open: "”",
|
|
132
|
+
openSingle: "’"
|
|
133
|
+
},
|
|
134
|
+
zh: {
|
|
135
|
+
close: "」",
|
|
136
|
+
closeSingle: "』",
|
|
137
|
+
open: "「",
|
|
138
|
+
openSingle: "『"
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Get the quote style for a given locale.
|
|
143
|
+
* Falls back to base language if region-specific style not found,
|
|
144
|
+
* then to English style as default.
|
|
145
|
+
*/
|
|
146
|
+
function getQuoteStyle(locale) {
|
|
147
|
+
const normalized = locale.toLowerCase();
|
|
148
|
+
const exactMatch = quoteStyles[normalized];
|
|
149
|
+
if (exactMatch) return exactMatch;
|
|
150
|
+
const baseLanguage = normalized.split("-")[0];
|
|
151
|
+
if (baseLanguage) {
|
|
152
|
+
const baseMatch = quoteStyles[baseLanguage];
|
|
153
|
+
if (baseMatch) return baseMatch;
|
|
154
|
+
}
|
|
155
|
+
return quoteStyles.en;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Replace straight quotes with typographically correct quotes for the given locale.
|
|
159
|
+
*
|
|
160
|
+
* @param text - The text containing straight quotes
|
|
161
|
+
* @param locale - The locale to use for quote style (e.g., 'en', 'de', 'fr')
|
|
162
|
+
* @returns Text with typographic quotes
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* typographicQuotes('"Hello"', 'en') // → '"Hello"'
|
|
166
|
+
* typographicQuotes('"Hello"', 'de') // → '„Hello"'
|
|
167
|
+
* typographicQuotes('"Hello"', 'fr') // → '« Hello »'
|
|
168
|
+
*/
|
|
169
|
+
function typographicQuotes(text, locale) {
|
|
170
|
+
const style = getQuoteStyle(locale);
|
|
171
|
+
let result = text.replace(/"([^"]*)"/g, `${style.open}$1${style.close}`);
|
|
172
|
+
result = result.replace(/'([^']*)'/g, `${style.openSingle}$1${style.closeSingle}`);
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
function toBoolean(value) {
|
|
176
|
+
if (typeof value === "boolean") return value;
|
|
177
|
+
return value === "true" || value === "1";
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Replace ­ HTML entity with Unicode soft hyphen
|
|
181
|
+
*/
|
|
182
|
+
function replaceShyInString(input) {
|
|
183
|
+
return input.replace(/­/g, "");
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Split text into sentences
|
|
187
|
+
*/
|
|
188
|
+
function splitIntoSentences(text) {
|
|
189
|
+
return text.split(/(?<=[.!?])\s+/);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Split text into words
|
|
193
|
+
*/
|
|
194
|
+
function splitIntoWords(text) {
|
|
195
|
+
return text.split(/\s+/);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Truncate text to a maximum length
|
|
199
|
+
*/
|
|
200
|
+
function truncateText(text, maxLength, suffix = "...") {
|
|
201
|
+
if (text.length <= maxLength) return text;
|
|
202
|
+
return text.slice(0, maxLength - suffix.length) + suffix;
|
|
203
|
+
}
|
|
204
|
+
const authorRegex = /^(.*?)\s*(?:<([^>]+)>)?\s*(?:\(([^)]+)\))?$/;
|
|
205
|
+
/**
|
|
206
|
+
* Parse an author string in the format "Name <email> (url)"
|
|
207
|
+
*/
|
|
208
|
+
function parseAuthorString(input) {
|
|
209
|
+
const match = input.match(authorRegex);
|
|
210
|
+
if (match) {
|
|
211
|
+
const [, name, email, url] = match;
|
|
212
|
+
const result = {};
|
|
213
|
+
if (email) result.email = email;
|
|
214
|
+
const trimmedName = name?.trim();
|
|
215
|
+
if (trimmedName) result.name = trimmedName;
|
|
216
|
+
if (url) result.url = url;
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
return {};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
//#endregion
|
|
223
|
+
export { formatBytes, parseAuthorString, replaceShyInString, splitIntoSentences, splitIntoWords, toBoolean, truncateText, typographicQuotes };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/time/delay.d.ts
|
|
2
|
+
/** Delays using a promise
|
|
3
|
+
* @param ms Milisecods of delay
|
|
4
|
+
* @return Promise
|
|
5
|
+
*/
|
|
6
|
+
declare function delay(ms: number): Promise<void>;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/time/measure.d.ts
|
|
9
|
+
declare function measure<Result>(key: string, callback: () => Result | Promise<Result>): Promise<Result>;
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/time/time.d.ts
|
|
12
|
+
declare function timeAgo(input: Date | string): string;
|
|
13
|
+
declare const oneWeekFromNow: () => Date;
|
|
14
|
+
declare const oneDayFromNow: () => Date;
|
|
15
|
+
declare const oneMinuteFromNow: () => Date;
|
|
16
|
+
declare function friendlyDuration(minutes: number | null, locale: string, short?: boolean): {
|
|
17
|
+
key: string;
|
|
18
|
+
vars: Record<string, string | number>;
|
|
19
|
+
} | null;
|
|
20
|
+
declare const dateTimeInUnix: (date: number) => number;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { dateTimeInUnix, delay, friendlyDuration, measure, oneDayFromNow, oneMinuteFromNow, oneWeekFromNow, timeAgo };
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
//#region src/time/delay.ts
|
|
2
|
+
/** Delays using a promise
|
|
3
|
+
* @param ms Milisecods of delay
|
|
4
|
+
* @return Promise
|
|
5
|
+
*/
|
|
6
|
+
function delay(ms) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
return setTimeout(resolve, ms);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/time/measure.ts
|
|
14
|
+
async function measure(key, callback) {
|
|
15
|
+
const start = Date.now();
|
|
16
|
+
try {
|
|
17
|
+
let result = callback();
|
|
18
|
+
if (result instanceof Promise) result = await result;
|
|
19
|
+
return result;
|
|
20
|
+
} finally {
|
|
21
|
+
const end = Date.now();
|
|
22
|
+
console.log(`${key} took ${end - start}ms`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/time/time.ts
|
|
28
|
+
function timeAgo(input) {
|
|
29
|
+
const date = new Date(input);
|
|
30
|
+
const formatter = new Intl.RelativeTimeFormat("en");
|
|
31
|
+
const ranges = {
|
|
32
|
+
days: 3600 * 24,
|
|
33
|
+
hours: 3600,
|
|
34
|
+
minutes: 60,
|
|
35
|
+
months: 3600 * 24 * 30,
|
|
36
|
+
seconds: 1,
|
|
37
|
+
weeks: 3600 * 24 * 7,
|
|
38
|
+
years: 3600 * 24 * 365
|
|
39
|
+
};
|
|
40
|
+
const secondsElapsed = (date.getTime() - Date.now()) / 1e3;
|
|
41
|
+
for (const key of Object.keys(ranges)) if (ranges[key] < Math.abs(secondsElapsed)) {
|
|
42
|
+
const delta = secondsElapsed / ranges[key];
|
|
43
|
+
return formatter.format(Math.round(delta), key);
|
|
44
|
+
}
|
|
45
|
+
return "Just now";
|
|
46
|
+
}
|
|
47
|
+
const oneWeekFromNow = () => {
|
|
48
|
+
const now = /* @__PURE__ */ new Date();
|
|
49
|
+
return new Date(now.getTime() + 10080 * 60 * 1e3);
|
|
50
|
+
};
|
|
51
|
+
const oneDayFromNow = () => {
|
|
52
|
+
const now = /* @__PURE__ */ new Date();
|
|
53
|
+
return new Date(now.getTime() + 1440 * 60 * 1e3);
|
|
54
|
+
};
|
|
55
|
+
const oneMinuteFromNow = () => {
|
|
56
|
+
const now = /* @__PURE__ */ new Date();
|
|
57
|
+
return new Date(now.getTime() + 60 * 1e3);
|
|
58
|
+
};
|
|
59
|
+
function friendlyDuration(minutes, locale, short = false) {
|
|
60
|
+
const numberFormatter = new Intl.NumberFormat(locale);
|
|
61
|
+
if (!minutes) return null;
|
|
62
|
+
if (short) {
|
|
63
|
+
if (minutes > 120) {
|
|
64
|
+
const hours = Math.floor(minutes / 60);
|
|
65
|
+
const remainingMinutes = minutes % 60;
|
|
66
|
+
if (remainingMinutes > 0) return {
|
|
67
|
+
key: "common:duration.hoursAndMinutesShort",
|
|
68
|
+
vars: {
|
|
69
|
+
hours: numberFormatter.format(hours),
|
|
70
|
+
minutes: numberFormatter.format(remainingMinutes)
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
key: "common:duration.hoursShort",
|
|
75
|
+
vars: { hours: numberFormatter.format(hours) }
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
key: "common:duration.minutesShort",
|
|
80
|
+
vars: { minutes: numberFormatter.format(minutes) }
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (minutes >= 525600) {
|
|
84
|
+
const years = Math.floor(minutes / 525600);
|
|
85
|
+
return {
|
|
86
|
+
key: "common:duration.years",
|
|
87
|
+
vars: {
|
|
88
|
+
count: years,
|
|
89
|
+
value: numberFormatter.format(years)
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (minutes >= 43200) {
|
|
94
|
+
const months = Math.floor(minutes / 43200);
|
|
95
|
+
return {
|
|
96
|
+
key: "common:duration.months",
|
|
97
|
+
vars: {
|
|
98
|
+
count: months,
|
|
99
|
+
value: numberFormatter.format(months)
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (minutes >= 10080) {
|
|
104
|
+
const weeks = Math.floor(minutes / 10080);
|
|
105
|
+
return {
|
|
106
|
+
key: "common:duration.weeks",
|
|
107
|
+
vars: {
|
|
108
|
+
count: weeks,
|
|
109
|
+
value: numberFormatter.format(weeks)
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (minutes >= 1440) {
|
|
114
|
+
const days = Math.floor(minutes / 1440);
|
|
115
|
+
return {
|
|
116
|
+
key: "common:duration.days",
|
|
117
|
+
vars: {
|
|
118
|
+
count: days,
|
|
119
|
+
value: numberFormatter.format(days)
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (minutes >= 240) {
|
|
124
|
+
const hours = Math.floor(minutes / 60);
|
|
125
|
+
const remainingMinutes = minutes % 60;
|
|
126
|
+
if (remainingMinutes > 0) return {
|
|
127
|
+
key: "common:duration.hoursAndMinutes",
|
|
128
|
+
vars: {
|
|
129
|
+
hours: numberFormatter.format(hours),
|
|
130
|
+
minutes: numberFormatter.format(remainingMinutes)
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
return {
|
|
134
|
+
key: "common:duration.hours",
|
|
135
|
+
vars: {
|
|
136
|
+
count: hours,
|
|
137
|
+
value: numberFormatter.format(hours)
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
key: "common:duration.minutes",
|
|
143
|
+
vars: {
|
|
144
|
+
count: minutes,
|
|
145
|
+
value: numberFormatter.format(minutes)
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const dateTimeInUnix = (date) => {
|
|
150
|
+
return Math.floor(date / 1e3);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
//#endregion
|
|
154
|
+
export { dateTimeInUnix, delay, friendlyDuration, measure, oneDayFromNow, oneMinuteFromNow, oneWeekFromNow, timeAgo };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://www.schemastore.org/package.json",
|
|
3
3
|
"name": "@regardio/js",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.1",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Regardio JavaScript utilities",
|
|
7
7
|
"keywords": [
|
|
@@ -28,37 +28,37 @@
|
|
|
28
28
|
"type": "module",
|
|
29
29
|
"exports": {
|
|
30
30
|
"./assert": {
|
|
31
|
-
"types": "./dist/assert/index.d.
|
|
32
|
-
"import": "./dist/assert/index.
|
|
31
|
+
"types": "./dist/assert/index.d.mts",
|
|
32
|
+
"import": "./dist/assert/index.mjs"
|
|
33
33
|
},
|
|
34
34
|
"./encoding": {
|
|
35
|
-
"types": "./dist/encoding/index.d.
|
|
36
|
-
"import": "./dist/encoding/index.
|
|
35
|
+
"types": "./dist/encoding/index.d.mts",
|
|
36
|
+
"import": "./dist/encoding/index.mjs"
|
|
37
37
|
},
|
|
38
38
|
"./http": {
|
|
39
|
-
"types": "./dist/http/index.d.
|
|
40
|
-
"import": "./dist/http/index.
|
|
39
|
+
"types": "./dist/http/index.d.mts",
|
|
40
|
+
"import": "./dist/http/index.mjs"
|
|
41
41
|
},
|
|
42
42
|
"./intl": {
|
|
43
|
-
"types": "./dist/intl/index.d.
|
|
44
|
-
"import": "./dist/intl/index.
|
|
43
|
+
"types": "./dist/intl/index.d.mts",
|
|
44
|
+
"import": "./dist/intl/index.mjs"
|
|
45
45
|
},
|
|
46
46
|
"./text": {
|
|
47
|
-
"types": "./dist/text/index.d.
|
|
48
|
-
"import": "./dist/text/index.
|
|
47
|
+
"types": "./dist/text/index.d.mts",
|
|
48
|
+
"import": "./dist/text/index.mjs"
|
|
49
49
|
},
|
|
50
50
|
"./time": {
|
|
51
|
-
"types": "./dist/time/index.d.
|
|
52
|
-
"import": "./dist/time/index.
|
|
51
|
+
"types": "./dist/time/index.d.mts",
|
|
52
|
+
"import": "./dist/time/index.mjs"
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"files": [
|
|
56
56
|
"dist"
|
|
57
57
|
],
|
|
58
58
|
"scripts": {
|
|
59
|
-
"build": "
|
|
59
|
+
"build": "tsdown && pnpm fix",
|
|
60
60
|
"clean": "exec-clean .turbo dist",
|
|
61
|
-
"dev": "
|
|
61
|
+
"dev": "tsdown --watch",
|
|
62
62
|
"fix": "exec-p fix:*",
|
|
63
63
|
"fix:biome": "lint-biome check --write --unsafe .",
|
|
64
64
|
"fix:md": "lint-md --fix",
|
|
@@ -80,13 +80,13 @@
|
|
|
80
80
|
"react-router": "7.12.0"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"@regardio/dev": "1.
|
|
83
|
+
"@regardio/dev": "1.12.1",
|
|
84
84
|
"@total-typescript/ts-reset": "0.6.1",
|
|
85
|
-
"@types/node": "25.0.
|
|
86
|
-
"@vitest/coverage-v8": "4.0.
|
|
87
|
-
"@vitest/ui": "4.0.
|
|
88
|
-
"
|
|
89
|
-
"vitest": "4.0.
|
|
85
|
+
"@types/node": "25.0.8",
|
|
86
|
+
"@vitest/coverage-v8": "4.0.17",
|
|
87
|
+
"@vitest/ui": "4.0.17",
|
|
88
|
+
"tsdown": "0.20.0-beta.3",
|
|
89
|
+
"vitest": "4.0.17"
|
|
90
90
|
},
|
|
91
91
|
"publishConfig": {
|
|
92
92
|
"access": "public"
|
package/dist/assert/index.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provide a condition and if that condition is falsey, this throws an error
|
|
3
|
-
* with the given message.
|
|
4
|
-
*
|
|
5
|
-
* inspired by invariant from 'tiny-invariant' except will still include the
|
|
6
|
-
* message in production.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* invariant(typeof value === 'string', `value must be a string`)
|
|
10
|
-
*
|
|
11
|
-
* @param condition The condition to check
|
|
12
|
-
* @param message The message to throw (or a callback to generate the message)
|
|
13
|
-
*
|
|
14
|
-
* @throws {Error} if condition is falsey
|
|
15
|
-
*/
|
|
16
|
-
declare function invariant(condition: unknown, message: string | (() => string)): asserts condition;
|
|
17
|
-
/**
|
|
18
|
-
* Provide a condition and if that condition is falsey, this throws a 400
|
|
19
|
-
* Response with the given message.
|
|
20
|
-
*
|
|
21
|
-
* inspired by invariant from 'tiny-invariant'
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* invariantResponse(typeof value === 'string', `value must be a string`)
|
|
25
|
-
*
|
|
26
|
-
* @param condition The condition to check
|
|
27
|
-
* @param message The message to throw (or a callback to generate the message)
|
|
28
|
-
* @param responseInit Additional response init options if a response is thrown
|
|
29
|
-
*
|
|
30
|
-
* @throws {Response} if condition is falsey
|
|
31
|
-
*/
|
|
32
|
-
declare function invariantResponse(condition: unknown, message: string | (() => string), responseInit?: ResponseInit): asserts condition;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Check if a mime type matches the set given in accept
|
|
36
|
-
*
|
|
37
|
-
* @param type the mime type to test, ex image/png
|
|
38
|
-
* @param accept the mime types to accept, ex audio/*,video/*,image/png
|
|
39
|
-
* @returns true if the mime is accepted, false otherwise
|
|
40
|
-
*/
|
|
41
|
-
declare function verifyAccept(type: string, accept: string): boolean;
|
|
42
|
-
|
|
43
|
-
export { invariant, invariantResponse, verifyAccept };
|
package/dist/assert/index.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// src/assert/invariant.ts
|
|
2
|
-
function invariant(condition, message) {
|
|
3
|
-
if (!condition) {
|
|
4
|
-
throw new Error(typeof message === "function" ? message() : message);
|
|
5
|
-
}
|
|
6
|
-
}
|
|
7
|
-
function invariantResponse(condition, message, responseInit) {
|
|
8
|
-
if (!condition) {
|
|
9
|
-
throw new Response(typeof message === "function" ? message() : message, {
|
|
10
|
-
status: 400,
|
|
11
|
-
...responseInit
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// src/assert/verify-file-accept.ts
|
|
17
|
-
function verifyAccept(type, accept) {
|
|
18
|
-
const allowed = accept.split(",").map((x) => x.trim());
|
|
19
|
-
return allowed.includes(type) || allowed.includes(`${type.split("/")[0]}/*`);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export { invariant, invariantResponse, verifyAccept };
|
package/dist/encoding/index.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Converts a base64 string to a Uint8Array
|
|
3
|
-
* @param base64String The base64 string to convert
|
|
4
|
-
* @returns A Uint8Array containing the decoded data
|
|
5
|
-
*/
|
|
6
|
-
declare const urlBase64ToUint8Array: (base64String: string) => Uint8Array;
|
|
7
|
-
/**
|
|
8
|
-
* Generate a cryptographically secure random base64 string.
|
|
9
|
-
* @returns A base64-encoded random string (16 bytes of entropy)
|
|
10
|
-
*/
|
|
11
|
-
declare function generateRandomBase64(): string;
|
|
12
|
-
|
|
13
|
-
export { generateRandomBase64, urlBase64ToUint8Array };
|
package/dist/encoding/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// src/encoding/base64.ts
|
|
2
|
-
var urlBase64ToUint8Array = (base64String) => {
|
|
3
|
-
const padding = "=".repeat((4 - base64String.length % 4) % 4);
|
|
4
|
-
const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
|
|
5
|
-
const rawData = window.atob(base64);
|
|
6
|
-
const outputArray = new Uint8Array(rawData.length);
|
|
7
|
-
for (let i = 0; i < rawData.length; ++i) {
|
|
8
|
-
outputArray[i] = rawData.charCodeAt(i);
|
|
9
|
-
}
|
|
10
|
-
return outputArray;
|
|
11
|
-
};
|
|
12
|
-
function generateRandomBase64() {
|
|
13
|
-
const array = new Uint8Array(16);
|
|
14
|
-
crypto.getRandomValues(array);
|
|
15
|
-
return btoa(String.fromCharCode(...array));
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export { generateRandomBase64, urlBase64ToUint8Array };
|
package/dist/http/index.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Helper function to set cookies in a more controlled way
|
|
3
|
-
* @param name - The name of the cookie
|
|
4
|
-
* @param value - The value to set
|
|
5
|
-
* @param options - Cookie options
|
|
6
|
-
*/
|
|
7
|
-
declare function setCookieValue(name: string, value: string, options?: {
|
|
8
|
-
expires?: Date;
|
|
9
|
-
path?: string;
|
|
10
|
-
sameSite?: string;
|
|
11
|
-
secure?: boolean;
|
|
12
|
-
domain?: string;
|
|
13
|
-
}): void;
|
|
14
|
-
/**
|
|
15
|
-
* Get a cookie value by name
|
|
16
|
-
* @param name - The name of the cookie to get
|
|
17
|
-
* @returns The cookie value or null if not found
|
|
18
|
-
*/
|
|
19
|
-
declare function getCookieValue(name: string): string | null;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Helper utility used to extract the domain from the request even if it's
|
|
23
|
-
* behind a proxy. This is useful for sitemaps and other things.
|
|
24
|
-
* @param request Request object
|
|
25
|
-
* @returns Current domain
|
|
26
|
-
*/
|
|
27
|
-
declare const createDomain: (request: Request) => string;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @name isRouteActive
|
|
31
|
-
* @description A function to check if a route is active. This is used to
|
|
32
|
-
* @param end
|
|
33
|
-
* @param path
|
|
34
|
-
* @param currentPath
|
|
35
|
-
*/
|
|
36
|
-
declare function isRouteActive(path: string, currentPath: string, end?: boolean | ((path: string) => boolean) | undefined): boolean;
|
|
37
|
-
/**
|
|
38
|
-
* @name checkIfRouteIsActive
|
|
39
|
-
* @description A function to check if a route is active. This is used to
|
|
40
|
-
* highlight the active link in the navigation.
|
|
41
|
-
* @param targetLink - The link to check against
|
|
42
|
-
* @param currentRoute - the current route
|
|
43
|
-
* @param depth - how far down should segments be matched?
|
|
44
|
-
*/
|
|
45
|
-
declare function checkIfRouteIsActive(targetLink: string, currentRoute: string, depth?: number): boolean;
|
|
46
|
-
|
|
47
|
-
declare function getCleanUrl(request: Request): string;
|
|
48
|
-
|
|
49
|
-
export { checkIfRouteIsActive, createDomain, getCleanUrl, getCookieValue, isRouteActive, setCookieValue };
|