tiny-essentials 1.2.0 → 1.2.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/TinyBasicsEs.js +51 -14
- package/dist/TinyBasicsEs.min.js +1 -1
- package/dist/TinyCertCrypto.js +26497 -71362
- package/dist/TinyCertCrypto.min.js +1 -1
- package/dist/TinyCertCrypto.min.js.LICENSE.txt +0 -2
- package/dist/TinyCrypto.js +93 -70
- package/dist/TinyCrypto.min.js +1 -1
- package/dist/TinyEssentials.js +232 -136
- package/dist/TinyEssentials.min.js +1 -1
- package/dist/TinyLevelUp.js +9 -9
- package/dist/legacy/crypto/decrypt.cjs +1 -0
- package/dist/legacy/crypto/decrypt.mjs +1 -0
- package/dist/legacy/crypto/default.cjs +2 -0
- package/dist/legacy/crypto/default.mjs +1 -0
- package/dist/legacy/crypto/encrypt.cjs +2 -1
- package/dist/legacy/crypto/encrypt.mjs +1 -0
- package/dist/legacy/crypto/index.cjs +1 -1
- package/dist/legacy/crypto/index.mjs +1 -0
- package/dist/legacy/firebase/cookieSession.cjs +2 -0
- package/dist/legacy/firebase/cookieSession.mjs +1 -0
- package/dist/legacy/firebase/database/index.cjs +3 -0
- package/dist/legacy/firebase/database/index.mjs +1 -0
- package/dist/legacy/firebase/database/presence.cjs +3 -0
- package/dist/legacy/firebase/database/presence.mjs +1 -0
- package/dist/legacy/firebase/database/saveAsync.cjs +2 -0
- package/dist/legacy/firebase/database/saveAsync.mjs +1 -0
- package/dist/legacy/firebase/databaseEscape.cjs +3 -0
- package/dist/legacy/firebase/databaseEscape.mjs +1 -0
- package/dist/legacy/firebase/databaseLogger.cjs +3 -0
- package/dist/legacy/firebase/databaseLogger.mjs +1 -0
- package/dist/legacy/firebase/discord/api/addGuildMember.cjs +3 -0
- package/dist/legacy/firebase/discord/api/addGuildMember.mjs +1 -0
- package/dist/legacy/firebase/discord/api/getGuildWidget.cjs +3 -0
- package/dist/legacy/firebase/discord/api/getGuildWidget.mjs +1 -0
- package/dist/legacy/firebase/discord/api/getToken.cjs +3 -0
- package/dist/legacy/firebase/discord/api/getToken.mjs +1 -0
- package/dist/legacy/firebase/discord/api/getUser.cjs +3 -0
- package/dist/legacy/firebase/discord/api/getUser.mjs +1 -0
- package/dist/legacy/firebase/discord/api/getUserConnections.cjs +3 -0
- package/dist/legacy/firebase/discord/api/getUserConnections.mjs +1 -0
- package/dist/legacy/firebase/discord/api/getUserGuilds.cjs +3 -0
- package/dist/legacy/firebase/discord/api/getUserGuilds.mjs +1 -0
- package/dist/legacy/firebase/discord/api/index.cjs +3 -0
- package/dist/legacy/firebase/discord/api/index.mjs +1 -0
- package/dist/legacy/firebase/discord/api/refreshToken.cjs +3 -0
- package/dist/legacy/firebase/discord/api/refreshToken.mjs +1 -0
- package/dist/legacy/firebase/discord/api/revokeToken.cjs +3 -0
- package/dist/legacy/firebase/discord/api/revokeToken.mjs +1 -0
- package/dist/legacy/firebase/discord/config.cjs +2 -0
- package/dist/legacy/firebase/discord/config.mjs +1 -0
- package/dist/legacy/firebase/discord/firebase_redirect/index.cjs +3 -0
- package/dist/legacy/firebase/discord/firebase_redirect/index.mjs +1 -0
- package/dist/legacy/firebase/discord/firebase_redirect/login.cjs +2 -0
- package/dist/legacy/firebase/discord/firebase_redirect/login.mjs +1 -0
- package/dist/legacy/firebase/discord/firebase_redirect/logout.cjs +2 -0
- package/dist/legacy/firebase/discord/firebase_redirect/logout.mjs +1 -0
- package/dist/legacy/firebase/discord/get/authURLGenerator.cjs +3 -0
- package/dist/legacy/firebase/discord/get/authURLGenerator.mjs +1 -0
- package/dist/legacy/firebase/discord/get/cookie-session.cjs +3 -0
- package/dist/legacy/firebase/discord/get/cookie-session.mjs +1 -0
- package/dist/legacy/firebase/discord/get/credentials.cjs +2 -0
- package/dist/legacy/firebase/discord/get/credentials.mjs +1 -0
- package/dist/legacy/firebase/discord/get/errorValidator.cjs +3 -0
- package/dist/legacy/firebase/discord/get/errorValidator.mjs +1 -0
- package/dist/legacy/firebase/discord/get/index.cjs +3 -0
- package/dist/legacy/firebase/discord/get/index.mjs +1 -0
- package/dist/legacy/firebase/discord/get/randomAvatar.cjs +3 -0
- package/dist/legacy/firebase/discord/get/randomAvatar.mjs +1 -0
- package/dist/legacy/firebase/discord/http/index.cjs +3 -0
- package/dist/legacy/firebase/discord/http/index.mjs +1 -0
- package/dist/legacy/firebase/discord/http/login.cjs +3 -0
- package/dist/legacy/firebase/discord/http/login.mjs +1 -0
- package/dist/legacy/firebase/discord/http/logout.cjs +3 -0
- package/dist/legacy/firebase/discord/http/logout.mjs +1 -0
- package/dist/legacy/firebase/discord/http/redirect.cjs +3 -0
- package/dist/legacy/firebase/discord/http/redirect.mjs +1 -0
- package/dist/legacy/firebase/discord/http/refreshToken.cjs +3 -0
- package/dist/legacy/firebase/discord/http/refreshToken.mjs +1 -0
- package/dist/legacy/firebase/discord/index.cjs +3 -0
- package/dist/legacy/firebase/discord/index.mjs +1 -0
- package/dist/legacy/firebase/discord/template/cookie-session.cjs +3 -0
- package/dist/legacy/firebase/discord/template/cookie-session.mjs +1 -0
- package/dist/legacy/firebase/domainRedirect.cjs +2 -0
- package/dist/legacy/firebase/domainRedirect.mjs +1 -0
- package/dist/legacy/firebase/escape.cjs +2 -0
- package/dist/legacy/firebase/escape.mjs +1 -0
- package/dist/legacy/firebase/getDBAsync.cjs +2 -0
- package/dist/legacy/firebase/getDBAsync.mjs +1 -0
- package/dist/legacy/firebase/getDBData.cjs +3 -0
- package/dist/legacy/firebase/getDBData.mjs +1 -0
- package/dist/legacy/firebase/getDBValue.cjs +2 -0
- package/dist/legacy/firebase/getDBValue.mjs +1 -0
- package/dist/legacy/firebase/index.cjs +3 -0
- package/dist/legacy/firebase/index.mjs +1 -0
- package/dist/legacy/firebase/isEmulator.cjs +2 -0
- package/dist/legacy/firebase/isEmulator.mjs +1 -0
- package/dist/legacy/firebase/logger.cjs +3 -0
- package/dist/legacy/firebase/logger.mjs +1 -0
- package/dist/legacy/firebase/mySQL.cjs +3 -0
- package/dist/legacy/firebase/mySQL.mjs +1 -0
- package/dist/legacy/firebase/mysqlConnector/create.cjs +2 -0
- package/dist/legacy/firebase/mysqlConnector/create.mjs +1 -0
- package/dist/legacy/firebase/mysqlConnector/index.cjs +3 -0
- package/dist/legacy/firebase/mysqlConnector/index.mjs +1 -0
- package/dist/legacy/firebase/mysqlConnector/nextPrev.cjs +2 -0
- package/dist/legacy/firebase/mysqlConnector/nextPrev.mjs +1 -0
- package/dist/legacy/firebase/mysqlConnector/pagination.cjs +2 -0
- package/dist/legacy/firebase/mysqlConnector/pagination.mjs +1 -0
- package/dist/legacy/firebase/mysqlConnector/sameUser.cjs +3 -0
- package/dist/legacy/firebase/mysqlConnector/sameUser.mjs +1 -0
- package/dist/legacy/firebase/transactionDBAsync.cjs +2 -0
- package/dist/legacy/firebase/transactionDBAsync.mjs +1 -0
- package/dist/legacy/get/countObj.cjs +3 -0
- package/dist/legacy/get/countObj.mjs +1 -0
- package/dist/legacy/get/decimalColor.cjs +3 -0
- package/dist/legacy/get/decimalColor.mjs +1 -0
- package/dist/legacy/get/objType.cjs +2 -0
- package/dist/legacy/get/objType.mjs +1 -0
- package/dist/legacy/get/pagination.cjs +3 -0
- package/dist/legacy/get/pagination.mjs +1 -0
- package/dist/legacy/get/queryUrlByName.cjs +2 -0
- package/dist/legacy/get/queryUrlByName.mjs +1 -0
- package/dist/legacy/get/queryUrlJSON.cjs +2 -0
- package/dist/legacy/get/queryUrlJSON.mjs +1 -0
- package/dist/legacy/get/super_string_filter.cjs +3 -0
- package/dist/legacy/get/super_string_filter.mjs +1 -0
- package/dist/legacy/get/versionCheck.cjs +2 -1
- package/dist/legacy/get/versionCheck.mjs +1 -0
- package/dist/legacy/http/HTTP-1.0.cjs +2 -0
- package/dist/legacy/http/HTTP-1.0.mjs +1 -0
- package/dist/legacy/http/auth.cjs +2 -0
- package/dist/legacy/http/auth.mjs +1 -0
- package/dist/legacy/http/check_domain.cjs +2 -0
- package/dist/legacy/http/check_domain.mjs +1 -0
- package/dist/legacy/http/csrfTokenAnalyze.cjs +2 -0
- package/dist/legacy/http/csrfTokenAnalyze.mjs +1 -0
- package/dist/legacy/http/domainValidator.cjs +3 -0
- package/dist/legacy/http/domainValidator.mjs +1 -0
- package/dist/legacy/http/errorsCallback.cjs +2 -0
- package/dist/legacy/http/errorsCallback.mjs +1 -0
- package/dist/legacy/http/fetch/json.cjs +3 -0
- package/dist/legacy/http/fetch/json.mjs +1 -0
- package/dist/legacy/http/fetch/text.cjs +3 -0
- package/dist/legacy/http/fetch/text.mjs +1 -0
- package/dist/legacy/http/fileCache.cjs +3 -0
- package/dist/legacy/http/fileCache.mjs +1 -0
- package/dist/legacy/http/getDomainURL.cjs +3 -0
- package/dist/legacy/http/getDomainURL.mjs +1 -0
- package/dist/legacy/http/userIP.cjs +3 -0
- package/dist/legacy/http/userIP.mjs +1 -0
- package/dist/legacy/index.cjs +3 -0
- package/dist/legacy/index.mjs +1 -0
- package/dist/legacy/libs/arraySortPositions.cjs +2 -0
- package/dist/legacy/libs/arraySortPositions.mjs +1 -0
- package/dist/legacy/libs/capitalize.cjs +2 -0
- package/dist/legacy/libs/capitalize.mjs +1 -0
- package/dist/legacy/libs/convertBytes.cjs +2 -0
- package/dist/legacy/libs/convertBytes.mjs +1 -0
- package/dist/legacy/libs/custom_module_loader.cjs +3 -0
- package/dist/legacy/libs/custom_module_loader.mjs +1 -0
- package/dist/legacy/libs/dice.cjs +2 -0
- package/dist/legacy/libs/dice.mjs +1 -0
- package/dist/legacy/libs/markdown.cjs +2 -0
- package/dist/legacy/libs/markdown.mjs +1 -0
- package/dist/legacy/libs/percentage.cjs +2 -0
- package/dist/legacy/libs/percentage.mjs +1 -0
- package/dist/legacy/libs/regex/getLetter.cjs +2 -0
- package/dist/legacy/libs/regex/getLetter.mjs +1 -0
- package/dist/legacy/libs/replaceAsync.cjs +3 -0
- package/dist/legacy/libs/replaceAsync.mjs +3 -0
- package/dist/legacy/libs/rule3.cjs +2 -0
- package/dist/legacy/libs/rule3.mjs +1 -0
- package/dist/legacy/libs/userLevel.cjs +9 -9
- package/dist/legacy/libs/userLevel.d.mts +39 -16
- package/dist/legacy/libs/userLevel.mjs +9 -9
- package/dist/legacy/momentjs/getAge.cjs +3 -0
- package/dist/legacy/momentjs/getAge.mjs +1 -0
- package/dist/legacy/momentjs/index.cjs +1 -1
- package/dist/legacy/momentjs/index.mjs +1 -0
- package/dist/legacy/momentjs/timeDuration.cjs +3 -0
- package/dist/legacy/momentjs/timeDuration.mjs +1 -0
- package/dist/legacy/socket.io/antiFlood/index.cjs +1 -1
- package/dist/legacy/socket.io/antiFlood/index.mjs +1 -0
- package/dist/legacy/socket.io/antiFlood/install.cjs +3 -0
- package/dist/legacy/socket.io/antiFlood/install.mjs +1 -0
- package/dist/legacy/socket.io/antiFlood/verify.cjs +3 -0
- package/dist/legacy/socket.io/antiFlood/verify.mjs +1 -0
- package/dist/legacy/socket.io/cookie-session.cjs +2 -0
- package/dist/legacy/socket.io/cookie-session.mjs +1 -0
- package/dist/legacy/socket.io/discord.cjs +3 -0
- package/dist/legacy/socket.io/discord.mjs +1 -0
- package/dist/legacy/socket.io/index.cjs +3 -0
- package/dist/legacy/socket.io/index.mjs +1 -0
- package/dist/v1/basics/clock.cjs +43 -13
- package/dist/v1/basics/clock.mjs +31 -13
- package/dist/v1/basics/objFilter.cjs +4 -0
- package/dist/v1/basics/objFilter.mjs +3 -0
- package/dist/v1/basics/simpleMath.cjs +1 -1
- package/dist/v1/basics/simpleMath.mjs +1 -1
- package/dist/v1/libs/TinyCertCrypto.cjs +104 -45
- package/dist/v1/libs/TinyCertCrypto.d.mts +18 -16
- package/dist/v1/libs/TinyCertCrypto.mjs +68 -37
- package/dist/v1/libs/TinyCrypto.cjs +70 -33
- package/dist/v1/libs/TinyCrypto.d.mts +64 -26
- package/dist/v1/libs/TinyCrypto.mjs +54 -38
- package/package.json +1 -1
- package/webpack.config.mjs +0 -69
package/dist/v1/basics/clock.mjs
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
export function getTimeDuration(timeData = new Date(), durationType = 'asSeconds', now = null) {
|
|
10
10
|
if (timeData instanceof Date) {
|
|
11
11
|
const currentTime = now instanceof Date ? now : new Date();
|
|
12
|
-
|
|
12
|
+
/** @type {number} */
|
|
13
|
+
const diffMs = timeData.getTime() - currentTime.getTime();
|
|
13
14
|
switch (durationType) {
|
|
14
15
|
case 'asMilliseconds':
|
|
15
16
|
return diffMs;
|
|
@@ -48,6 +49,17 @@ export function formatCustomTimer(totalSeconds, level = 'seconds', format = '{ti
|
|
|
48
49
|
minutes: index >= 1,
|
|
49
50
|
seconds: index >= 0,
|
|
50
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* @type {{
|
|
54
|
+
* years: number|NaN,
|
|
55
|
+
* months: number|NaN,
|
|
56
|
+
* days: number|NaN,
|
|
57
|
+
* hours: number|NaN,
|
|
58
|
+
* minutes: number|NaN,
|
|
59
|
+
* seconds: number|NaN,
|
|
60
|
+
* total: number|NaN
|
|
61
|
+
* }}
|
|
62
|
+
*/
|
|
51
63
|
const parts = {
|
|
52
64
|
years: include.years ? 0 : NaN,
|
|
53
65
|
months: include.months ? 0 : NaN,
|
|
@@ -64,29 +76,26 @@ export function formatCustomTimer(totalSeconds, level = 'seconds', format = '{ti
|
|
|
64
76
|
const workingDate = new Date(baseDate);
|
|
65
77
|
// Years
|
|
66
78
|
if (include.years) {
|
|
67
|
-
while (new Date(workingDate.getFullYear() + 1, workingDate.getMonth(), workingDate.getDate()) <=
|
|
68
|
-
targetDate) {
|
|
79
|
+
while (new Date(workingDate.getFullYear() + 1, workingDate.getMonth(), workingDate.getDate()).getTime() <= targetDate.getTime()) {
|
|
69
80
|
workingDate.setFullYear(workingDate.getFullYear() + 1);
|
|
70
81
|
parts.years++;
|
|
71
82
|
}
|
|
72
83
|
}
|
|
73
84
|
// Months
|
|
74
85
|
if (include.months) {
|
|
75
|
-
while (new Date(workingDate.getFullYear(), workingDate.getMonth() + 1, workingDate.getDate()) <=
|
|
76
|
-
targetDate) {
|
|
86
|
+
while (new Date(workingDate.getFullYear(), workingDate.getMonth() + 1, workingDate.getDate()).getTime() <= targetDate.getTime()) {
|
|
77
87
|
workingDate.setMonth(workingDate.getMonth() + 1);
|
|
78
88
|
parts.months++;
|
|
79
89
|
}
|
|
80
90
|
}
|
|
81
91
|
// Days
|
|
82
92
|
if (include.days) {
|
|
83
|
-
while (new Date(workingDate.getFullYear(), workingDate.getMonth(), workingDate.getDate() + 1) <=
|
|
84
|
-
targetDate) {
|
|
93
|
+
while (new Date(workingDate.getFullYear(), workingDate.getMonth(), workingDate.getDate() + 1).getTime() <= targetDate.getTime()) {
|
|
85
94
|
workingDate.setDate(workingDate.getDate() + 1);
|
|
86
95
|
parts.days++;
|
|
87
96
|
}
|
|
88
97
|
}
|
|
89
|
-
remaining = Math.floor((targetDate - workingDate) / 1000);
|
|
98
|
+
remaining = Math.floor((targetDate.getTime() - workingDate.getTime()) / 1000);
|
|
90
99
|
}
|
|
91
100
|
if (include.hours) {
|
|
92
101
|
parts.hours = Math.floor(remaining / 3600);
|
|
@@ -109,7 +118,16 @@ export function formatCustomTimer(totalSeconds, level = 'seconds', format = '{ti
|
|
|
109
118
|
years: include.years ? parts.years + (parts.months || 0) / 12 + (parts.days || 0) / 365 : NaN,
|
|
110
119
|
};
|
|
111
120
|
parts.total = +(totalMap[level] || 0).toFixed(2).replace(/\.00$/, '');
|
|
112
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Pads a number to ensure it is at least two digits long, using leading zeros if necessary.
|
|
123
|
+
*
|
|
124
|
+
* @param {number|string} n - The number or string to pad.
|
|
125
|
+
* @returns {string} The padded string.
|
|
126
|
+
*/
|
|
127
|
+
const pad = (n) => {
|
|
128
|
+
const num = typeof n === 'string' ? parseInt(n) : n;
|
|
129
|
+
return Number.isNaN(num) ? 'NaN' : String(num).padStart(2, '0');
|
|
130
|
+
};
|
|
113
131
|
const timeString = [
|
|
114
132
|
include.hours ? pad(parts.hours) : null,
|
|
115
133
|
include.minutes ? pad(parts.minutes) : null,
|
|
@@ -118,14 +136,14 @@ export function formatCustomTimer(totalSeconds, level = 'seconds', format = '{ti
|
|
|
118
136
|
.filter((v) => v !== null)
|
|
119
137
|
.join(':');
|
|
120
138
|
return format
|
|
121
|
-
.replace(/\{years\}/g, parts.years)
|
|
122
|
-
.replace(/\{months\}/g, parts.months)
|
|
123
|
-
.replace(/\{days\}/g, parts.days)
|
|
139
|
+
.replace(/\{years\}/g, String(parts.years))
|
|
140
|
+
.replace(/\{months\}/g, String(parts.months))
|
|
141
|
+
.replace(/\{days\}/g, String(parts.days))
|
|
124
142
|
.replace(/\{hours\}/g, pad(parts.hours))
|
|
125
143
|
.replace(/\{minutes\}/g, pad(parts.minutes))
|
|
126
144
|
.replace(/\{seconds\}/g, pad(parts.seconds))
|
|
127
145
|
.replace(/\{time\}/g, timeString)
|
|
128
|
-
.replace(/\{total\}/g, parts.total)
|
|
146
|
+
.replace(/\{total\}/g, String(parts.total))
|
|
129
147
|
.trim();
|
|
130
148
|
}
|
|
131
149
|
/**
|
|
@@ -74,6 +74,9 @@ const typeValidator = {
|
|
|
74
74
|
/** Checks if the value is a Buffer. */
|
|
75
75
|
buffer: (val) => typeof buffer.Buffer !== 'undefined' && buffer.Buffer.isBuffer(val),
|
|
76
76
|
|
|
77
|
+
/** Checks if the value is a File. */
|
|
78
|
+
file: (val) => typeof File !== 'undefined' && val instanceof File,
|
|
79
|
+
|
|
77
80
|
/** Checks if the value is a Html Element. */
|
|
78
81
|
htmlelement: (val) => typeof HTMLElement !== 'undefined' && val instanceof HTMLElement,
|
|
79
82
|
|
|
@@ -93,6 +96,7 @@ const typeValidator = {
|
|
|
93
96
|
'function',
|
|
94
97
|
'array',
|
|
95
98
|
'buffer',
|
|
99
|
+
'file',
|
|
96
100
|
'date',
|
|
97
101
|
'regexp',
|
|
98
102
|
'map',
|
|
@@ -53,6 +53,8 @@ const typeValidator = {
|
|
|
53
53
|
promise: (val) => val instanceof Promise,
|
|
54
54
|
/** Checks if the value is a Buffer. */
|
|
55
55
|
buffer: (val) => typeof Buffer !== 'undefined' && Buffer.isBuffer(val),
|
|
56
|
+
/** Checks if the value is a File. */
|
|
57
|
+
file: (val) => typeof File !== 'undefined' && val instanceof File,
|
|
56
58
|
/** Checks if the value is a Html Element. */
|
|
57
59
|
htmlelement: (val) => typeof HTMLElement !== 'undefined' && val instanceof HTMLElement,
|
|
58
60
|
/** Checks if the value is a non-null plain object or instance of a class. */
|
|
@@ -70,6 +72,7 @@ const typeValidator = {
|
|
|
70
72
|
'function',
|
|
71
73
|
'array',
|
|
72
74
|
'buffer',
|
|
75
|
+
'file',
|
|
73
76
|
'date',
|
|
74
77
|
'regexp',
|
|
75
78
|
'map',
|
|
@@ -62,7 +62,7 @@ function getSimplePerc(price, percentage) {
|
|
|
62
62
|
function getAge(timeData = 0, now = null) {
|
|
63
63
|
if (typeof timeData !== 'undefined' && timeData !== null && timeData !== 0) {
|
|
64
64
|
const birthDate = new Date(timeData);
|
|
65
|
-
if (isNaN(birthDate)) return null;
|
|
65
|
+
if (Number.isNaN(birthDate.getTime())) return null;
|
|
66
66
|
|
|
67
67
|
const currentDate = now instanceof Date ? now : new Date();
|
|
68
68
|
|
|
@@ -58,7 +58,7 @@ export function getSimplePerc(price, percentage) {
|
|
|
58
58
|
export function getAge(timeData = 0, now = null) {
|
|
59
59
|
if (typeof timeData !== 'undefined' && timeData !== null && timeData !== 0) {
|
|
60
60
|
const birthDate = new Date(timeData);
|
|
61
|
-
if (isNaN(birthDate))
|
|
61
|
+
if (Number.isNaN(birthDate.getTime()))
|
|
62
62
|
return null;
|
|
63
63
|
const currentDate = now instanceof Date ? now : new Date();
|
|
64
64
|
let age = currentDate.getFullYear() - birthDate.getFullYear();
|
|
@@ -1,9 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var fs = require('fs');
|
|
4
|
-
var crypto = require('crypto');
|
|
5
4
|
var buffer = require('buffer');
|
|
6
5
|
|
|
6
|
+
function _interopNamespaceDefault(e) {
|
|
7
|
+
var n = Object.create(null);
|
|
8
|
+
if (e) {
|
|
9
|
+
Object.keys(e).forEach(function (k) {
|
|
10
|
+
if (k !== 'default') {
|
|
11
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
12
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return e[k]; }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
n.default = e;
|
|
20
|
+
return Object.freeze(n);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
|
24
|
+
|
|
7
25
|
/**
|
|
8
26
|
* Determines if the environment is a browser.
|
|
9
27
|
*
|
|
@@ -33,7 +51,6 @@ class TinyCertCrypto {
|
|
|
33
51
|
* It supports multi-line content.
|
|
34
52
|
*
|
|
35
53
|
* @type {RegExp}
|
|
36
|
-
* @private
|
|
37
54
|
*/
|
|
38
55
|
#certRegex = /-----BEGIN CERTIFICATE-----([\s\S]+?)-----END CERTIFICATE-----/;
|
|
39
56
|
|
|
@@ -46,7 +63,6 @@ class TinyCertCrypto {
|
|
|
46
63
|
* It captures the key type (PUBLIC|PRIVATE) and the base64 content.
|
|
47
64
|
*
|
|
48
65
|
* @type {RegExp}
|
|
49
|
-
* @private
|
|
50
66
|
*/
|
|
51
67
|
#keyRegex =
|
|
52
68
|
/-----BEGIN\s+(?:RSA\s+)?(PUBLIC|PRIVATE)\s+KEY-----([\s\S]+?)-----END\s+(?:RSA\s+)?\1\s+KEY-----/;
|
|
@@ -114,10 +130,10 @@ class TinyCertCrypto {
|
|
|
114
130
|
* This method is private and should not be called directly from outside.
|
|
115
131
|
*
|
|
116
132
|
* @returns {Promise<Object>} The loaded `node-forge` module.
|
|
117
|
-
* @private
|
|
118
133
|
*/
|
|
119
134
|
async #fetchNodeForge() {
|
|
120
135
|
if (!this.forge) {
|
|
136
|
+
// @ts-ignore
|
|
121
137
|
const forge = await import(/* webpackMode: "eager" */ 'node-forge');
|
|
122
138
|
this.forge = forge.default;
|
|
123
139
|
}
|
|
@@ -139,7 +155,6 @@ class TinyCertCrypto {
|
|
|
139
155
|
* Assumes the module has already been loaded.
|
|
140
156
|
*
|
|
141
157
|
* @returns {Object} The `node-forge` module.
|
|
142
|
-
* @private
|
|
143
158
|
*/
|
|
144
159
|
#getNodeForge() {
|
|
145
160
|
return this.forge;
|
|
@@ -162,13 +177,12 @@ class TinyCertCrypto {
|
|
|
162
177
|
* or `'unknown'` if the format is not recognized.
|
|
163
178
|
*
|
|
164
179
|
* @param {string} pemString - The PEM string to inspect.
|
|
165
|
-
* @returns {
|
|
166
|
-
* @private
|
|
180
|
+
* @returns {string} The detected PEM type.
|
|
167
181
|
*/
|
|
168
182
|
#detectPemType(pemString) {
|
|
169
183
|
if (this.#certRegex.test(pemString)) return 'certificate';
|
|
170
184
|
const keyMatch = this.#keyRegex.exec(pemString);
|
|
171
|
-
if (keyMatch) return keyMatch[1].toLowerCase() + '_key'; // "public_key" or "private_key"
|
|
185
|
+
if (keyMatch && typeof keyMatch[1] === 'string') return keyMatch[1].toLowerCase() + '_key'; // "public_key" or "private_key"
|
|
172
186
|
return 'unknown';
|
|
173
187
|
}
|
|
174
188
|
|
|
@@ -178,13 +192,9 @@ class TinyCertCrypto {
|
|
|
178
192
|
* This method can only be used in Node.js environments. It throws an error if a certificate
|
|
179
193
|
* or key is already loaded into the instance.
|
|
180
194
|
*
|
|
181
|
-
* @param {Object} subjectFields - An object representing the subject fields of the certificate (e.g., CN, O, C).
|
|
195
|
+
* @param {Object<string, string>} subjectFields - An object representing the subject fields of the certificate (e.g., CN, O, C).
|
|
182
196
|
* @param {Object} [options={}] - Optional configuration for key and certificate generation.
|
|
183
197
|
* @param {number} [options.modulusLength=2048] - Length of the RSA key in bits.
|
|
184
|
-
* @param {Object} [options.publicKeyEncoding={ type: 'spki', format: 'pem' }] - Options for public key encoding.
|
|
185
|
-
* @param {Object} [options.privateKeyEncoding={ type: 'pkcs8', format: 'pem' }] - Options for private key encoding.
|
|
186
|
-
* @param {string} [options.publicKeyType] - Overrides `publicKeyEncoding.type` if provided.
|
|
187
|
-
* @param {string} [options.privateKeyType] - Overrides `privateKeyEncoding.type` if provided.
|
|
188
198
|
* @param {number} [options.validityInYears=1] - Number of years the certificate will be valid.
|
|
189
199
|
* @param {number} [options.randomBytesLength=16] - Number of random bytes to use for serial number generation.
|
|
190
200
|
*
|
|
@@ -197,34 +207,26 @@ class TinyCertCrypto {
|
|
|
197
207
|
throw new Error('A certificate is already loaded into the instance.');
|
|
198
208
|
|
|
199
209
|
// Prepare cert
|
|
210
|
+
/** @type {any} */
|
|
200
211
|
const { pki } = await this.#fetchNodeForge();
|
|
201
|
-
const {
|
|
202
|
-
modulusLength = 2048,
|
|
203
|
-
publicKeyEncoding = { type: 'spki', format: 'pem' },
|
|
204
|
-
privateKeyEncoding = { type: 'pkcs8', format: 'pem' },
|
|
205
|
-
validityInYears = 1,
|
|
206
|
-
randomBytesLength = 16,
|
|
207
|
-
} = options;
|
|
208
212
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
/**
|
|
214
|
+
* @property {number} [modulusLength=2048] - The length of the RSA modulus (in bits). Default is 2048.
|
|
215
|
+
* @property {number} [validityInYears=1] - The validity period of the key pair in years. Default is 1 year.
|
|
216
|
+
* @property {number} [randomBytesLength=16] - The length of random bytes used in key generation. Default is 16 bytes.
|
|
217
|
+
*/
|
|
218
|
+
const { modulusLength = 2048, validityInYears = 1, randomBytesLength = 16 } = options;
|
|
215
219
|
|
|
216
220
|
// Generate keys
|
|
217
|
-
const { publicKey, privateKey } =
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
privateKeyEncoding: { ...privateKeyEncoding, type: privateKeyType },
|
|
221
|
-
});
|
|
221
|
+
const { publicKey, privateKey } = pki.rsa.generateKeyPair(modulusLength);
|
|
222
|
+
const encodedPublicKey = pki.publicKeyToPem(publicKey);
|
|
223
|
+
const encodedPrivateKey = pki.privateKeyToPem(privateKey);
|
|
222
224
|
|
|
223
225
|
// Get pem files
|
|
224
226
|
const { cert, publicPem, privatePem } = this.#generateCertificate(
|
|
225
227
|
subjectFields,
|
|
226
|
-
|
|
227
|
-
|
|
228
|
+
encodedPublicKey,
|
|
229
|
+
encodedPrivateKey,
|
|
228
230
|
validityInYears,
|
|
229
231
|
randomBytesLength,
|
|
230
232
|
);
|
|
@@ -236,26 +238,33 @@ class TinyCertCrypto {
|
|
|
236
238
|
this.publicCertPath = 'MEMORY';
|
|
237
239
|
this.privateKeyPath = 'MEMORY';
|
|
238
240
|
this.source = 'memory';
|
|
239
|
-
this.publicCertBuffer =
|
|
240
|
-
this.privateKeyBuffer =
|
|
241
|
+
this.publicCertBuffer = buffer.Buffer.from(encodedPublicKey);
|
|
242
|
+
this.privateKeyBuffer = buffer.Buffer.from(encodedPrivateKey);
|
|
241
243
|
|
|
242
244
|
this.#loadX509Certificate(cert);
|
|
243
|
-
return { publicKey, privateKey, cert };
|
|
245
|
+
return { publicKey: encodedPublicKey, privateKey: encodedPrivateKey, cert };
|
|
244
246
|
}
|
|
245
247
|
|
|
248
|
+
/**
|
|
249
|
+
* @typedef {Object} CertificateDetails
|
|
250
|
+
* @property {string} cert - The certificate in PEM format.
|
|
251
|
+
* @property {string} publicPem - The public key in PEM format.
|
|
252
|
+
* @property {string} privatePem - The private key in PEM format.
|
|
253
|
+
*/
|
|
254
|
+
|
|
246
255
|
/**
|
|
247
256
|
* Generates a self-signed X.509 certificate using the given public and private RSA keys.
|
|
248
257
|
*
|
|
249
258
|
* This method creates a certificate, assigns the subject and issuer fields,
|
|
250
259
|
* sets the validity period, and signs it with the private key.
|
|
251
260
|
*
|
|
252
|
-
* @param {Object} subject - An object representing the subject/issuer fields (e.g., { CN: 'example.com' }).
|
|
261
|
+
* @param {Object<string, string>} subject - An object representing the subject/issuer fields (e.g., { CN: 'example.com' }).
|
|
253
262
|
* @param {string} publicKey - The public key in PEM format.
|
|
254
263
|
* @param {string} privateKey - The private key in PEM format.
|
|
255
264
|
* @param {number} validityInYears - Number of years the certificate will remain valid.
|
|
256
265
|
* @param {number} randomBytesLength - Number of random bytes used to generate the serial number.
|
|
257
266
|
*
|
|
258
|
-
* @returns {
|
|
267
|
+
* @returns {CertificateDetails} An object containing:
|
|
259
268
|
* - {string} cert: The generated certificate in PEM format.
|
|
260
269
|
* - {Object} publicPem: The parsed public key object (from node-forge).
|
|
261
270
|
* - {Object} privatePem: The parsed private key object (from node-forge).
|
|
@@ -267,7 +276,9 @@ class TinyCertCrypto {
|
|
|
267
276
|
const privatePem = pki.privateKeyFromPem(privateKey);
|
|
268
277
|
|
|
269
278
|
cert.publicKey = publicPem;
|
|
270
|
-
cert.serialNumber = buffer.Buffer.from(
|
|
279
|
+
cert.serialNumber = buffer.Buffer.from(this.forge.random.getBytesSync(randomBytesLength)).toString(
|
|
280
|
+
'hex',
|
|
281
|
+
);
|
|
271
282
|
cert.validity.notBefore = new Date();
|
|
272
283
|
cert.validity.notAfter = new Date();
|
|
273
284
|
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + validityInYears);
|
|
@@ -308,8 +319,21 @@ class TinyCertCrypto {
|
|
|
308
319
|
|
|
309
320
|
// Load public key
|
|
310
321
|
this.metadata = {};
|
|
322
|
+
/** @type {any} */
|
|
311
323
|
const { pki } = await this.#fetchNodeForge();
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Loads the public key from a PEM-encoded certificate or public key.
|
|
327
|
+
*
|
|
328
|
+
* @param {string|null} publicPem - The PEM-encoded public key or certificate.
|
|
329
|
+
* @throws {Error} If the PEM string is not recognized or if the key cannot be parsed.
|
|
330
|
+
*/
|
|
312
331
|
const loadPublicKey = (publicPem) => {
|
|
332
|
+
if (typeof publicPem !== 'string')
|
|
333
|
+
throw new Error(
|
|
334
|
+
'Expected publicPem to be a string containing a PEM-encoded key or certificate.',
|
|
335
|
+
);
|
|
336
|
+
|
|
313
337
|
// File type
|
|
314
338
|
const fileType = this.#detectPemType(publicPem);
|
|
315
339
|
|
|
@@ -325,12 +349,29 @@ class TinyCertCrypto {
|
|
|
325
349
|
else throw new Error('Public key is required to initialize');
|
|
326
350
|
};
|
|
327
351
|
|
|
352
|
+
/**
|
|
353
|
+
* Loads the private key from a PEM-encoded private key.
|
|
354
|
+
*
|
|
355
|
+
* @param {string|null} privatePem - The PEM-encoded private key.
|
|
356
|
+
* @throws {Error} If the PEM string is not recognized or if the key cannot be parsed.
|
|
357
|
+
*/
|
|
328
358
|
const loadPrivateKey = (privatePem) => {
|
|
359
|
+
if (typeof privatePem !== 'string')
|
|
360
|
+
throw new Error('Expected privatePem to be a string containing a PEM-encoded private key.');
|
|
329
361
|
const fileType = this.#detectPemType(privatePem);
|
|
330
362
|
if (fileType === 'private_key') this.privateKey = pki.privateKeyFromPem(privatePem);
|
|
331
363
|
else throw new Error('Private key is required to initialize');
|
|
332
364
|
};
|
|
333
365
|
|
|
366
|
+
if (typeof this.publicCertPath !== 'string')
|
|
367
|
+
throw new TypeError(
|
|
368
|
+
`Expected 'publicCertPath' to be a string, but got ${typeof this.publicCertPath}`,
|
|
369
|
+
);
|
|
370
|
+
if (typeof this.privateKeyPath !== 'string')
|
|
371
|
+
throw new TypeError(
|
|
372
|
+
`Expected 'privateKeyPath' to be a string, but got ${typeof this.privateKeyPath}`,
|
|
373
|
+
);
|
|
374
|
+
|
|
334
375
|
// Nodejs
|
|
335
376
|
if (!isBrowser) {
|
|
336
377
|
const usedPublicBuffer = !!this.publicCertBuffer;
|
|
@@ -340,8 +381,10 @@ class TinyCertCrypto {
|
|
|
340
381
|
const publicPem = usedPublicBuffer
|
|
341
382
|
? typeof this.publicCertBuffer === 'string'
|
|
342
383
|
? this.publicCertBuffer
|
|
343
|
-
: this.publicCertBuffer
|
|
344
|
-
|
|
384
|
+
: buffer.Buffer.isBuffer(this.publicCertBuffer)
|
|
385
|
+
? this.publicCertBuffer.toString('utf-8')
|
|
386
|
+
: null
|
|
387
|
+
: fs__namespace.readFileSync(this.publicCertPath, 'utf-8');
|
|
345
388
|
loadPublicKey(publicPem);
|
|
346
389
|
|
|
347
390
|
// Private Key
|
|
@@ -349,8 +392,10 @@ class TinyCertCrypto {
|
|
|
349
392
|
const privatePem = usedPrivateBuffer
|
|
350
393
|
? typeof this.privateKeyBuffer === 'string'
|
|
351
394
|
? this.privateKeyBuffer
|
|
352
|
-
: this.privateKeyBuffer
|
|
353
|
-
|
|
395
|
+
: buffer.Buffer.isBuffer(this.privateKeyBuffer)
|
|
396
|
+
? this.privateKeyBuffer.toString('utf-8')
|
|
397
|
+
: null
|
|
398
|
+
: fs__namespace.readFileSync(this.privateKeyPath, 'utf-8');
|
|
354
399
|
|
|
355
400
|
loadPrivateKey(privatePem);
|
|
356
401
|
}
|
|
@@ -391,7 +436,6 @@ class TinyCertCrypto {
|
|
|
391
436
|
* This method supports both PEM strings and already-parsed Forge certificate objects.
|
|
392
437
|
* The parsed certificate is saved to `this.publicCert` and its metadata is extracted to `this.metadata`.
|
|
393
438
|
*
|
|
394
|
-
* @private
|
|
395
439
|
* @param {string|object} certPem - A PEM-encoded certificate string or a `forge.pki.Certificate` object.
|
|
396
440
|
* @throws {Error} If the certificate cannot be parsed or processed.
|
|
397
441
|
*/
|
|
@@ -401,8 +445,21 @@ class TinyCertCrypto {
|
|
|
401
445
|
const cert = typeof certPem === 'string' ? pki.certificateFromPem(certPem) : certPem;
|
|
402
446
|
this.publicCert = cert;
|
|
403
447
|
|
|
448
|
+
/**
|
|
449
|
+
* @typedef {Object} Attribute
|
|
450
|
+
* @property {string} name - The name of the attribute.
|
|
451
|
+
* @property {string} shortName - The short name of the attribute.
|
|
452
|
+
* @property {string} value - The value of the attribute.
|
|
453
|
+
*/
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* @param {Array<Attribute>} attributes - The list of attributes, each containing `name`, `shortName`, and `value`.
|
|
457
|
+
* @returns {{names: { [key: string]: string }, shortNames: { [key: string]: string }, raw: string}} The processed data containing the organized attributes.
|
|
458
|
+
*/
|
|
404
459
|
const insertData = (attributes) => {
|
|
460
|
+
/** @type {{[key: string]: string}} */
|
|
405
461
|
const names = {};
|
|
462
|
+
/** @type {{[key: string]: string}} */
|
|
406
463
|
const shortNames = {};
|
|
407
464
|
const raw = attributes.map((attr) => `${attr.shortName}=${attr.value}`).join(',');
|
|
408
465
|
for (const item of attributes) {
|
|
@@ -420,7 +477,9 @@ class TinyCertCrypto {
|
|
|
420
477
|
validTo: cert.validity.notAfter,
|
|
421
478
|
};
|
|
422
479
|
} catch (err) {
|
|
423
|
-
throw new Error(
|
|
480
|
+
throw new Error(
|
|
481
|
+
`Failed to parse X.509 certificate in browser: ${err instanceof Error && typeof err.message === 'string' ? err.message : 'Unknown error'}`,
|
|
482
|
+
);
|
|
424
483
|
}
|
|
425
484
|
}
|
|
426
485
|
|
|
@@ -52,14 +52,22 @@ declare class TinyCertCrypto {
|
|
|
52
52
|
validTo?: undefined;
|
|
53
53
|
} | {
|
|
54
54
|
subject: {
|
|
55
|
-
names: {
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
names: {
|
|
56
|
+
[key: string]: string;
|
|
57
|
+
};
|
|
58
|
+
shortNames: {
|
|
59
|
+
[key: string]: string;
|
|
60
|
+
};
|
|
61
|
+
raw: string;
|
|
58
62
|
};
|
|
59
63
|
issuer: {
|
|
60
|
-
names: {
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
names: {
|
|
65
|
+
[key: string]: string;
|
|
66
|
+
};
|
|
67
|
+
shortNames: {
|
|
68
|
+
[key: string]: string;
|
|
69
|
+
};
|
|
70
|
+
raw: string;
|
|
63
71
|
};
|
|
64
72
|
serialNumber: any;
|
|
65
73
|
validFrom: any;
|
|
@@ -85,25 +93,19 @@ declare class TinyCertCrypto {
|
|
|
85
93
|
* This method can only be used in Node.js environments. It throws an error if a certificate
|
|
86
94
|
* or key is already loaded into the instance.
|
|
87
95
|
*
|
|
88
|
-
* @param {Object} subjectFields - An object representing the subject fields of the certificate (e.g., CN, O, C).
|
|
96
|
+
* @param {Object<string, string>} subjectFields - An object representing the subject fields of the certificate (e.g., CN, O, C).
|
|
89
97
|
* @param {Object} [options={}] - Optional configuration for key and certificate generation.
|
|
90
98
|
* @param {number} [options.modulusLength=2048] - Length of the RSA key in bits.
|
|
91
|
-
* @param {Object} [options.publicKeyEncoding={ type: 'spki', format: 'pem' }] - Options for public key encoding.
|
|
92
|
-
* @param {Object} [options.privateKeyEncoding={ type: 'pkcs8', format: 'pem' }] - Options for private key encoding.
|
|
93
|
-
* @param {string} [options.publicKeyType] - Overrides `publicKeyEncoding.type` if provided.
|
|
94
|
-
* @param {string} [options.privateKeyType] - Overrides `privateKeyEncoding.type` if provided.
|
|
95
99
|
* @param {number} [options.validityInYears=1] - Number of years the certificate will be valid.
|
|
96
100
|
* @param {number} [options.randomBytesLength=16] - Number of random bytes to use for serial number generation.
|
|
97
101
|
*
|
|
98
102
|
* @returns {Promise<{publicKey: string, privateKey: string, cert: string}>} The generated keys and certificate in PEM format.
|
|
99
103
|
* @throws {Error} If running in a browser or if a cert/key is already loaded.
|
|
100
104
|
*/
|
|
101
|
-
generateX509Cert(subjectFields:
|
|
105
|
+
generateX509Cert(subjectFields: {
|
|
106
|
+
[x: string]: string;
|
|
107
|
+
}, options?: {
|
|
102
108
|
modulusLength?: number | undefined;
|
|
103
|
-
publicKeyEncoding?: Object | undefined;
|
|
104
|
-
privateKeyEncoding?: Object | undefined;
|
|
105
|
-
publicKeyType?: string | undefined;
|
|
106
|
-
privateKeyType?: string | undefined;
|
|
107
109
|
validityInYears?: number | undefined;
|
|
108
110
|
randomBytesLength?: number | undefined;
|
|
109
111
|
}): Promise<{
|