@regardio/js 0.3.0 → 0.4.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/async/delay.d.ts +7 -2
- package/dist/async/delay.js +7 -4
- package/dist/browser/base64.d.ts +8 -2
- package/dist/browser/base64.js +12 -9
- package/dist/format/bytes.d.ts +3 -2
- package/dist/format/bytes.js +12 -9
- package/dist/format/measure.d.ts +3 -2
- package/dist/format/measure.js +14 -12
- package/dist/http/cookie.d.ts +15 -3
- package/dist/http/cookie.js +44 -43
- package/dist/http/domain.d.ts +9 -2
- package/dist/http/domain.js +15 -12
- package/dist/http/request-helpers.d.ts +3 -2
- package/dist/http/request-helpers.js +9 -6
- package/dist/intl/language-detector.d.ts +64 -6
- package/dist/intl/language-detector.js +128 -123
- package/dist/time/time.d.ts +8 -7
- package/dist/time/time.js +121 -118
- package/dist/validation/invariant.d.ts +34 -3
- package/dist/validation/invariant.js +14 -11
- package/dist/validation/verify-file-accept.d.ts +10 -2
- package/dist/validation/verify-file-accept.js +6 -3
- package/package.json +4 -3
- package/dist/async/delay.d.ts.map +0 -1
- package/dist/async/delay.test.d.ts +0 -2
- package/dist/async/delay.test.d.ts.map +0 -1
- package/dist/async/delay.test.js +0 -35
- package/dist/browser/base64.d.ts.map +0 -1
- package/dist/format/bytes.d.ts.map +0 -1
- package/dist/format/bytes.test.d.ts +0 -2
- package/dist/format/bytes.test.d.ts.map +0 -1
- package/dist/format/bytes.test.js +0 -49
- package/dist/format/measure.d.ts.map +0 -1
- package/dist/format/measure.test.d.ts +0 -2
- package/dist/format/measure.test.d.ts.map +0 -1
- package/dist/format/measure.test.js +0 -50
- package/dist/http/cookie.d.ts.map +0 -1
- package/dist/http/domain.d.ts.map +0 -1
- package/dist/http/domain.test.d.ts +0 -2
- package/dist/http/domain.test.d.ts.map +0 -1
- package/dist/http/domain.test.js +0 -29
- package/dist/http/request-helpers.d.ts.map +0 -1
- package/dist/http/request-helpers.test.d.ts +0 -2
- package/dist/http/request-helpers.test.d.ts.map +0 -1
- package/dist/http/request-helpers.test.js +0 -37
- package/dist/intl/language-detector.d.ts.map +0 -1
- package/dist/intl/language-detector.test.d.ts +0 -2
- package/dist/intl/language-detector.test.d.ts.map +0 -1
- package/dist/intl/language-detector.test.js +0 -186
- package/dist/time/time.d.ts.map +0 -1
- package/dist/time/time.test.d.ts +0 -2
- package/dist/time/time.test.d.ts.map +0 -1
- package/dist/time/time.test.js +0 -202
- package/dist/validation/invariant.d.ts.map +0 -1
- package/dist/validation/invariant.test.d.ts +0 -2
- package/dist/validation/invariant.test.d.ts.map +0 -1
- package/dist/validation/invariant.test.js +0 -110
- package/dist/validation/verify-file-accept.d.ts.map +0 -1
- package/dist/validation/verify-file-accept.test.d.ts +0 -2
- package/dist/validation/verify-file-accept.test.d.ts.map +0 -1
- package/dist/validation/verify-file-accept.test.js +0 -71
|
@@ -1,134 +1,139 @@
|
|
|
1
1
|
import { parseAcceptLanguage } from 'intl-parse-accept-language';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
|
|
3
|
+
// src/intl/language-detector.ts
|
|
4
|
+
var LanguageDetectorLingui = class {
|
|
5
|
+
detector;
|
|
6
|
+
options;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.options = options;
|
|
9
|
+
this.detector = new LanguageDetector(this.options.detection);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Detect the current locale by following the order defined in the
|
|
13
|
+
* `detection.order` option.
|
|
14
|
+
* By default the order is
|
|
15
|
+
* - urlPath (first segment like /de/ or /en/)
|
|
16
|
+
* - cookie
|
|
17
|
+
* - session
|
|
18
|
+
* - searchParams
|
|
19
|
+
* - header
|
|
20
|
+
* And finally the fallback language.
|
|
21
|
+
*/
|
|
22
|
+
async getLocale(request) {
|
|
23
|
+
return await this.detector.detect(request);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var LanguageDetector = class {
|
|
27
|
+
options;
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.options = options;
|
|
30
|
+
this.isSessionOnly(this.options);
|
|
31
|
+
this.isCookieOnly(this.options);
|
|
32
|
+
}
|
|
33
|
+
async detect(request) {
|
|
34
|
+
const order = this.options.order ?? ["urlPath", "cookie", "session", "searchParams", "header"];
|
|
35
|
+
for (const method of order) {
|
|
36
|
+
let locale = null;
|
|
37
|
+
if (method === "urlPath") {
|
|
38
|
+
locale = this.fromUrlPath(request);
|
|
39
|
+
}
|
|
40
|
+
if (method === "searchParams") {
|
|
41
|
+
locale = this.fromSearchParams(request);
|
|
42
|
+
}
|
|
43
|
+
if (method === "cookie") {
|
|
44
|
+
locale = await this.fromCookie(request);
|
|
45
|
+
}
|
|
46
|
+
if (method === "session") {
|
|
47
|
+
locale = await this.fromSessionStorage(request);
|
|
48
|
+
}
|
|
49
|
+
if (method === "header") {
|
|
50
|
+
locale = this.fromHeader(request);
|
|
51
|
+
}
|
|
52
|
+
if (locale) return locale;
|
|
8
53
|
}
|
|
9
|
-
|
|
10
|
-
|
|
54
|
+
return this.options.fallbackLanguage;
|
|
55
|
+
}
|
|
56
|
+
isSessionOnly(options) {
|
|
57
|
+
if (options.order?.length === 1 && options.order[0] === "session" && !options.sessionStorage) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
"You need a sessionStorage if you want to only get the locale from the session"
|
|
60
|
+
);
|
|
11
61
|
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
options
|
|
15
|
-
|
|
16
|
-
this.options = options;
|
|
17
|
-
this.isSessionOnly(this.options);
|
|
18
|
-
this.isCookieOnly(this.options);
|
|
19
|
-
}
|
|
20
|
-
async detect(request) {
|
|
21
|
-
const order = this.options.order ?? ['urlPath', 'cookie', 'session', 'searchParams', 'header'];
|
|
22
|
-
for (const method of order) {
|
|
23
|
-
let locale = null;
|
|
24
|
-
if (method === 'urlPath') {
|
|
25
|
-
locale = this.fromUrlPath(request);
|
|
26
|
-
}
|
|
27
|
-
if (method === 'searchParams') {
|
|
28
|
-
locale = this.fromSearchParams(request);
|
|
29
|
-
}
|
|
30
|
-
if (method === 'cookie') {
|
|
31
|
-
locale = await this.fromCookie(request);
|
|
32
|
-
}
|
|
33
|
-
if (method === 'session') {
|
|
34
|
-
locale = await this.fromSessionStorage(request);
|
|
35
|
-
}
|
|
36
|
-
if (method === 'header') {
|
|
37
|
-
locale = this.fromHeader(request);
|
|
38
|
-
}
|
|
39
|
-
if (locale)
|
|
40
|
-
return locale;
|
|
41
|
-
}
|
|
42
|
-
return this.options.fallbackLanguage;
|
|
43
|
-
}
|
|
44
|
-
isSessionOnly(options) {
|
|
45
|
-
if (options.order?.length === 1 && options.order[0] === 'session' && !options.sessionStorage) {
|
|
46
|
-
throw new Error('You need a sessionStorage if you want to only get the locale from the session');
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
isCookieOnly(options) {
|
|
50
|
-
if (options.order?.length === 1 && options.order[0] === 'cookie' && !options.cookie) {
|
|
51
|
-
throw new Error('You need a cookie if you want to only get the locale from the cookie');
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
fromUrlPath(request) {
|
|
55
|
-
const url = new URL(request.url);
|
|
56
|
-
const pathSegments = url.pathname.split('/').filter(Boolean);
|
|
57
|
-
if (pathSegments.length > 0) {
|
|
58
|
-
const firstSegment = pathSegments[0];
|
|
59
|
-
if (firstSegment) {
|
|
60
|
-
return this.fromSupported(firstSegment);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
fromSearchParams(request) {
|
|
66
|
-
const url = new URL(request.url);
|
|
67
|
-
if (!url.searchParams.has(this.options.searchParamKey ?? 'lng')) {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
return this.fromSupported(url.searchParams.get(this.options.searchParamKey ?? 'lng'));
|
|
62
|
+
}
|
|
63
|
+
isCookieOnly(options) {
|
|
64
|
+
if (options.order?.length === 1 && options.order[0] === "cookie" && !options.cookie) {
|
|
65
|
+
throw new Error("You need a cookie if you want to only get the locale from the cookie");
|
|
71
66
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
catch (_error) {
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
67
|
+
}
|
|
68
|
+
fromUrlPath(request) {
|
|
69
|
+
const url = new URL(request.url);
|
|
70
|
+
const pathSegments = url.pathname.split("/").filter(Boolean);
|
|
71
|
+
if (pathSegments.length > 0) {
|
|
72
|
+
const firstSegment = pathSegments[0];
|
|
73
|
+
if (firstSegment) {
|
|
74
|
+
return this.fromSupported(firstSegment);
|
|
75
|
+
}
|
|
85
76
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return null;
|
|
93
|
-
return this.fromSupported(lng);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
fromSearchParams(request) {
|
|
80
|
+
const url = new URL(request.url);
|
|
81
|
+
if (!url.searchParams.has(this.options.searchParamKey ?? "lng")) {
|
|
82
|
+
return null;
|
|
94
83
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
84
|
+
return this.fromSupported(url.searchParams.get(this.options.searchParamKey ?? "lng"));
|
|
85
|
+
}
|
|
86
|
+
async fromCookie(request) {
|
|
87
|
+
if (!this.options.cookie) return null;
|
|
88
|
+
const cookie = this.options.cookie;
|
|
89
|
+
try {
|
|
90
|
+
const lng = await cookie.parse(request.headers.get("Cookie"));
|
|
91
|
+
if (typeof lng !== "string" || !lng) return null;
|
|
92
|
+
return this.fromSupported(lng);
|
|
93
|
+
} catch (_error) {
|
|
94
|
+
return null;
|
|
102
95
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
96
|
+
}
|
|
97
|
+
async fromSessionStorage(request) {
|
|
98
|
+
if (!this.options.sessionStorage) return null;
|
|
99
|
+
const session = await this.options.sessionStorage.getSession(request.headers.get("Cookie"));
|
|
100
|
+
const lng = session.get(this.options.sessionKey ?? "lng");
|
|
101
|
+
if (!lng) return null;
|
|
102
|
+
return this.fromSupported(lng);
|
|
103
|
+
}
|
|
104
|
+
fromHeader(request) {
|
|
105
|
+
const locales = getClientLocales(request);
|
|
106
|
+
if (!locales) return null;
|
|
107
|
+
if (Array.isArray(locales)) return this.fromSupported(locales.join(","));
|
|
108
|
+
return this.fromSupported(locales);
|
|
109
|
+
}
|
|
110
|
+
fromSupported(language) {
|
|
111
|
+
if (!language) return this.options.fallbackLanguage;
|
|
112
|
+
const languageStr = Array.isArray(language) ? language.join(",") : language;
|
|
113
|
+
const parsed = parseAcceptLanguage(languageStr, {
|
|
114
|
+
ignoreWildcard: true,
|
|
115
|
+
validate: (locale) => this.options.supportedLanguages.includes(locale) ? locale : null
|
|
122
116
|
});
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
117
|
+
return parsed[0] || this.options.fallbackLanguage;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
function getClientLocales(requestOrHeaders) {
|
|
121
|
+
const headers = getHeaders(requestOrHeaders);
|
|
122
|
+
const acceptLanguage = headers.get("Accept-Language");
|
|
123
|
+
if (!acceptLanguage) return void 0;
|
|
124
|
+
const locales = parseAcceptLanguage(acceptLanguage, {
|
|
125
|
+
ignoreWildcard: true,
|
|
126
|
+
validate: Intl.DateTimeFormat.supportedLocalesOf
|
|
127
|
+
});
|
|
128
|
+
if (locales.length === 0) return void 0;
|
|
129
|
+
if (locales.length === 1) return locales[0];
|
|
130
|
+
return locales;
|
|
128
131
|
}
|
|
129
132
|
function getHeaders(requestOrHeaders) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
if (requestOrHeaders instanceof Request) {
|
|
134
|
+
return requestOrHeaders.headers;
|
|
135
|
+
}
|
|
136
|
+
return requestOrHeaders;
|
|
134
137
|
}
|
|
138
|
+
|
|
139
|
+
export { LanguageDetector, LanguageDetectorLingui };
|
package/dist/time/time.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
declare function timeAgo(input: Date | string): string;
|
|
2
|
+
declare const oneWeekFromNow: () => Date;
|
|
3
|
+
declare const oneDayFromNow: () => Date;
|
|
4
|
+
declare const oneMinuteFromNow: () => Date;
|
|
5
|
+
declare function friendlyDuration(minutes: number | null, locale: string, short?: boolean): {
|
|
6
6
|
key: string;
|
|
7
7
|
vars: {
|
|
8
8
|
hours: string;
|
|
@@ -35,5 +35,6 @@ export declare function friendlyDuration(minutes: number | null, locale: string,
|
|
|
35
35
|
minutes?: undefined;
|
|
36
36
|
};
|
|
37
37
|
} | null;
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
declare const dateTimeInUnix: (date: number) => number;
|
|
39
|
+
|
|
40
|
+
export { dateTimeInUnix, friendlyDuration, oneDayFromNow, oneMinuteFromNow, oneWeekFromNow, timeAgo };
|
package/dist/time/time.js
CHANGED
|
@@ -1,132 +1,135 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
// src/time/time.ts
|
|
2
|
+
function timeAgo(input) {
|
|
3
|
+
const date = new Date(input);
|
|
4
|
+
const formatter = new Intl.RelativeTimeFormat("en");
|
|
5
|
+
const ranges = {
|
|
6
|
+
days: 3600 * 24,
|
|
7
|
+
hours: 3600,
|
|
8
|
+
minutes: 60,
|
|
9
|
+
months: 3600 * 24 * 30,
|
|
10
|
+
seconds: 1,
|
|
11
|
+
weeks: 3600 * 24 * 7,
|
|
12
|
+
years: 3600 * 24 * 365
|
|
13
|
+
};
|
|
14
|
+
const secondsElapsed = (date.getTime() - Date.now()) / 1e3;
|
|
15
|
+
for (const key of Object.keys(ranges)) {
|
|
16
|
+
if (ranges[key] < Math.abs(secondsElapsed)) {
|
|
17
|
+
const delta = secondsElapsed / ranges[key];
|
|
18
|
+
return formatter.format(Math.round(delta), key);
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
}
|
|
21
|
+
return "Just now";
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
var oneWeekFromNow = () => {
|
|
24
|
+
const now = /* @__PURE__ */ new Date();
|
|
25
|
+
return new Date(now.getTime() + 7 * 24 * 60 * 60 * 1e3);
|
|
25
26
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
var oneDayFromNow = () => {
|
|
28
|
+
const now = /* @__PURE__ */ new Date();
|
|
29
|
+
return new Date(now.getTime() + 1 * 24 * 60 * 60 * 1e3);
|
|
29
30
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
var oneMinuteFromNow = () => {
|
|
32
|
+
const now = /* @__PURE__ */ new Date();
|
|
33
|
+
return new Date(now.getTime() + 1 * 60 * 1e3);
|
|
33
34
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
key: 'common:duration.hoursAndMinutesShort',
|
|
46
|
-
vars: {
|
|
47
|
-
hours: numberFormatter.format(hours),
|
|
48
|
-
minutes: numberFormatter.format(remainingMinutes),
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
return {
|
|
53
|
-
key: 'common:duration.hoursShort',
|
|
54
|
-
vars: { hours: numberFormatter.format(hours) },
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
return {
|
|
58
|
-
key: 'common:duration.minutesShort',
|
|
59
|
-
vars: { minutes: numberFormatter.format(minutes) },
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
if (minutes >= 525600) {
|
|
63
|
-
const years = Math.floor(minutes / 525600);
|
|
64
|
-
return {
|
|
65
|
-
key: 'common:duration.years',
|
|
66
|
-
vars: {
|
|
67
|
-
count: years,
|
|
68
|
-
value: numberFormatter.format(years),
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
if (minutes >= 43200) {
|
|
73
|
-
const months = Math.floor(minutes / 43200);
|
|
74
|
-
return {
|
|
75
|
-
key: 'common:duration.months',
|
|
76
|
-
vars: {
|
|
77
|
-
count: months,
|
|
78
|
-
value: numberFormatter.format(months),
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
if (minutes >= 10080) {
|
|
83
|
-
const weeks = Math.floor(minutes / 10080);
|
|
84
|
-
return {
|
|
85
|
-
key: 'common:duration.weeks',
|
|
86
|
-
vars: {
|
|
87
|
-
count: weeks,
|
|
88
|
-
value: numberFormatter.format(weeks),
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
if (minutes >= 1440) {
|
|
93
|
-
const days = Math.floor(minutes / 1440);
|
|
35
|
+
function friendlyDuration(minutes, locale, short = false) {
|
|
36
|
+
const numberFormatter = new Intl.NumberFormat(locale);
|
|
37
|
+
if (!minutes) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (short) {
|
|
41
|
+
if (minutes > 120) {
|
|
42
|
+
const hours = Math.floor(minutes / 60);
|
|
43
|
+
const remainingMinutes = minutes % 60;
|
|
44
|
+
if (remainingMinutes > 0) {
|
|
94
45
|
return {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
46
|
+
key: "common:duration.hoursAndMinutesShort",
|
|
47
|
+
vars: {
|
|
48
|
+
hours: numberFormatter.format(hours),
|
|
49
|
+
minutes: numberFormatter.format(remainingMinutes)
|
|
50
|
+
}
|
|
100
51
|
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
key: "common:duration.hoursShort",
|
|
55
|
+
vars: { hours: numberFormatter.format(hours) }
|
|
56
|
+
};
|
|
101
57
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
58
|
+
return {
|
|
59
|
+
key: "common:duration.minutesShort",
|
|
60
|
+
vars: { minutes: numberFormatter.format(minutes) }
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (minutes >= 525600) {
|
|
64
|
+
const years = Math.floor(minutes / 525600);
|
|
65
|
+
return {
|
|
66
|
+
key: "common:duration.years",
|
|
67
|
+
vars: {
|
|
68
|
+
count: years,
|
|
69
|
+
value: numberFormatter.format(years)
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (minutes >= 43200) {
|
|
74
|
+
const months = Math.floor(minutes / 43200);
|
|
75
|
+
return {
|
|
76
|
+
key: "common:duration.months",
|
|
77
|
+
vars: {
|
|
78
|
+
count: months,
|
|
79
|
+
value: numberFormatter.format(months)
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (minutes >= 10080) {
|
|
84
|
+
const weeks = Math.floor(minutes / 10080);
|
|
85
|
+
return {
|
|
86
|
+
key: "common:duration.weeks",
|
|
87
|
+
vars: {
|
|
88
|
+
count: weeks,
|
|
89
|
+
value: numberFormatter.format(weeks)
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (minutes >= 1440) {
|
|
94
|
+
const days = Math.floor(minutes / 1440);
|
|
95
|
+
return {
|
|
96
|
+
key: "common:duration.days",
|
|
97
|
+
vars: {
|
|
98
|
+
count: days,
|
|
99
|
+
value: numberFormatter.format(days)
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (minutes >= 240) {
|
|
104
|
+
const hours = Math.floor(minutes / 60);
|
|
105
|
+
const remainingMinutes = minutes % 60;
|
|
106
|
+
if (remainingMinutes > 0) {
|
|
107
|
+
return {
|
|
108
|
+
key: "common:duration.hoursAndMinutes",
|
|
109
|
+
vars: {
|
|
110
|
+
hours: numberFormatter.format(hours),
|
|
111
|
+
minutes: numberFormatter.format(remainingMinutes)
|
|
113
112
|
}
|
|
114
|
-
|
|
115
|
-
key: 'common:duration.hours',
|
|
116
|
-
vars: {
|
|
117
|
-
count: hours,
|
|
118
|
-
value: numberFormatter.format(hours),
|
|
119
|
-
},
|
|
120
|
-
};
|
|
113
|
+
};
|
|
121
114
|
}
|
|
122
115
|
return {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
116
|
+
key: "common:duration.hours",
|
|
117
|
+
vars: {
|
|
118
|
+
count: hours,
|
|
119
|
+
value: numberFormatter.format(hours)
|
|
120
|
+
}
|
|
128
121
|
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
key: "common:duration.minutes",
|
|
125
|
+
vars: {
|
|
126
|
+
count: minutes,
|
|
127
|
+
value: numberFormatter.format(minutes)
|
|
128
|
+
}
|
|
129
|
+
};
|
|
129
130
|
}
|
|
130
|
-
|
|
131
|
-
|
|
131
|
+
var dateTimeInUnix = (date) => {
|
|
132
|
+
return Math.floor(date / 1e3);
|
|
132
133
|
};
|
|
134
|
+
|
|
135
|
+
export { dateTimeInUnix, friendlyDuration, oneDayFromNow, oneMinuteFromNow, oneWeekFromNow, timeAgo };
|
|
@@ -1,3 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
+
export { invariant, invariantResponse };
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// src/validation/invariant.ts
|
|
2
|
+
function invariant(condition, message) {
|
|
3
|
+
if (!condition) {
|
|
4
|
+
throw new Error(typeof message === "function" ? message() : message);
|
|
5
|
+
}
|
|
5
6
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
+
}
|
|
13
14
|
}
|
|
15
|
+
|
|
16
|
+
export { invariant, invariantResponse };
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Check if a mime type matches the set given in accept
|
|
3
|
+
*
|
|
4
|
+
* @param type the mime type to test, ex image/png
|
|
5
|
+
* @param accept the mime types to accept, ex audio/*,video/*,image/png
|
|
6
|
+
* @returns true if the mime is accepted, false otherwise
|
|
7
|
+
*/
|
|
8
|
+
declare function verifyAccept(type: string, accept: string): boolean;
|
|
9
|
+
|
|
10
|
+
export { verifyAccept };
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/validation/verify-file-accept.ts
|
|
2
|
+
function verifyAccept(type, accept) {
|
|
3
|
+
const allowed = accept.split(",").map((x) => x.trim());
|
|
4
|
+
return allowed.includes(type) || allowed.includes(`${type.split("/")[0]}/*`);
|
|
4
5
|
}
|
|
6
|
+
|
|
7
|
+
export { verifyAccept };
|
package/package.json
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"@regardio/dev": "1.9.4",
|
|
14
14
|
"@total-typescript/ts-reset": "0.6.1",
|
|
15
15
|
"@types/node": "25.0.3",
|
|
16
|
+
"tsup": "8.5.1",
|
|
16
17
|
"vitest": "4.0.16"
|
|
17
18
|
},
|
|
18
19
|
"exports": {
|
|
@@ -84,9 +85,9 @@
|
|
|
84
85
|
"url": "https://github.com/regardio/js"
|
|
85
86
|
},
|
|
86
87
|
"scripts": {
|
|
87
|
-
"build": "
|
|
88
|
+
"build": "tsup",
|
|
88
89
|
"clean": "exec-clean .turbo dist",
|
|
89
|
-
"dev": "
|
|
90
|
+
"dev": "tsup --watch",
|
|
90
91
|
"fix": "exec-p fix:*",
|
|
91
92
|
"fix:biome": "lint-biome check --write --unsafe .",
|
|
92
93
|
"fix:md": "lint-md --fix",
|
|
@@ -104,5 +105,5 @@
|
|
|
104
105
|
},
|
|
105
106
|
"sideEffects": false,
|
|
106
107
|
"type": "module",
|
|
107
|
-
"version": "0.
|
|
108
|
+
"version": "0.4.1"
|
|
108
109
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"delay.d.ts","sourceRoot":"","sources":["../../src/async/delay.ts"],"names":[],"mappings":"AAIA,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,oBAI/B"}
|