tiny-essentials 1.1.1 → 1.2.0

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.
Files changed (42) hide show
  1. package/README.md +3 -1
  2. package/dist/TinyBasicsEs.js +2784 -0
  3. package/dist/TinyBasicsEs.min.js +2 -0
  4. package/dist/TinyBasicsEs.min.js.LICENSE.txt +8 -0
  5. package/dist/TinyCertCrypto.js +76229 -0
  6. package/dist/TinyCertCrypto.min.js +2 -0
  7. package/dist/TinyCertCrypto.min.js.LICENSE.txt +10 -0
  8. package/dist/TinyCrypto.js +48115 -0
  9. package/dist/TinyCrypto.min.js +2 -0
  10. package/dist/TinyCrypto.min.js.LICENSE.txt +10 -0
  11. package/dist/TinyEssentials.js +77599 -0
  12. package/dist/TinyEssentials.min.js +2 -1
  13. package/dist/TinyEssentials.min.js.LICENSE.txt +10 -0
  14. package/dist/TinyLevelUp.js +173 -0
  15. package/dist/TinyLevelUp.min.js +1 -0
  16. package/dist/v1/basics/index.cjs +27 -0
  17. package/dist/v1/basics/index.d.mts +17 -0
  18. package/dist/v1/basics/index.mjs +7 -0
  19. package/dist/v1/basics/objFilter.cjs +3 -1
  20. package/dist/v1/basics/objFilter.mjs +1 -0
  21. package/dist/v1/build/TinyCertCrypto.cjs +7 -0
  22. package/dist/v1/build/TinyCertCrypto.d.mts +2 -0
  23. package/dist/v1/build/TinyCertCrypto.mjs +2 -0
  24. package/dist/v1/build/TinyCrypto.cjs +7 -0
  25. package/dist/v1/build/TinyCrypto.d.mts +2 -0
  26. package/dist/v1/build/TinyCrypto.mjs +2 -0
  27. package/dist/v1/build/TinyLevelUp.cjs +7 -0
  28. package/dist/v1/build/TinyLevelUp.d.mts +2 -0
  29. package/dist/v1/build/TinyLevelUp.mjs +2 -0
  30. package/dist/v1/index.cjs +2 -0
  31. package/dist/v1/index.d.mts +2 -1
  32. package/dist/v1/index.mjs +2 -1
  33. package/dist/v1/libs/TinyCertCrypto.cjs +514 -0
  34. package/dist/v1/libs/TinyCertCrypto.d.mts +191 -0
  35. package/dist/v1/libs/TinyCertCrypto.mjs +450 -0
  36. package/dist/v1/libs/TinyCrypto.cjs +21 -12
  37. package/dist/v1/libs/TinyCrypto.d.mts +1 -0
  38. package/dist/v1/libs/TinyCrypto.mjs +10 -1
  39. package/docs/README.md +2 -0
  40. package/docs/libs/TinyCertCrypto.md +202 -0
  41. package/package.json +11 -6
  42. package/webpack.config.mjs +69 -0
@@ -2,9 +2,18 @@
2
2
 
3
3
  var crypto = require('crypto');
4
4
  var fs = require('fs');
5
+ var buffer = require('buffer');
5
6
  var objFilter = require('../basics/objFilter.cjs');
6
7
 
7
- // Detecta se estamos no browser
8
+ /**
9
+ * Determines if the environment is a browser.
10
+ *
11
+ * This constant checks if the code is running in a browser environment by verifying if
12
+ * the `window` object and the `window.document` object are available. It will return `true`
13
+ * if the environment is a browser, and `false` otherwise (e.g., in a Node.js environment).
14
+ *
15
+ * @constant {boolean}
16
+ */
8
17
  const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
9
18
 
10
19
  /**
@@ -99,7 +108,7 @@ class TinyCrypto {
99
108
  });
100
109
 
101
110
  let encrypted = cipher.update(plainText, this.inputEncoding);
102
- encrypted = Buffer.concat([encrypted, cipher.final()]);
111
+ encrypted = buffer.Buffer.concat([encrypted, cipher.final()]);
103
112
  const authTag = cipher.getAuthTag();
104
113
 
105
114
  return {
@@ -134,9 +143,9 @@ class TinyCrypto {
134
143
  * console.log(decrypted); // Outputs: 'Hello, world!'
135
144
  */
136
145
  decrypt({ iv, encrypted, authTag }, expectedType = null) {
137
- const ivBuffer = Buffer.from(iv, this.outputEncoding);
138
- const encryptedBuffer = Buffer.from(encrypted, this.outputEncoding);
139
- const authTagBuffer = Buffer.from(authTag, this.outputEncoding);
146
+ const ivBuffer = buffer.Buffer.from(iv, this.outputEncoding);
147
+ const encryptedBuffer = buffer.Buffer.from(encrypted, this.outputEncoding);
148
+ const authTagBuffer = buffer.Buffer.from(authTag, this.outputEncoding);
140
149
 
141
150
  const decipher = crypto.createDecipheriv(this.algorithm, this.key, ivBuffer, {
142
151
  authTagLength: this.authTagLength,
@@ -174,9 +183,9 @@ class TinyCrypto {
174
183
  * console.log(dataType); // Outputs: 'string'
175
184
  */
176
185
  getTypeFromEncrypted({ iv, encrypted, authTag }) {
177
- const ivBuffer = Buffer.from(iv, this.outputEncoding);
178
- const encryptedBuffer = Buffer.from(encrypted, this.outputEncoding);
179
- const authTagBuffer = Buffer.from(authTag, this.outputEncoding);
186
+ const ivBuffer = buffer.Buffer.from(iv, this.outputEncoding);
187
+ const encryptedBuffer = buffer.Buffer.from(encrypted, this.outputEncoding);
188
+ const authTagBuffer = buffer.Buffer.from(authTag, this.outputEncoding);
180
189
 
181
190
  const decipher = crypto.createDecipheriv(this.algorithm, this.key, ivBuffer, {
182
191
  authTagLength: this.authTagLength,
@@ -322,7 +331,7 @@ class TinyCrypto {
322
331
  const reader = new FileReader();
323
332
  reader.onload = () => {
324
333
  const hexKey = reader.result.trim();
325
- const keyBuffer = Buffer.from(hexKey, 'hex');
334
+ const keyBuffer = buffer.Buffer.from(hexKey, 'hex');
326
335
  this.key = keyBuffer;
327
336
  resolve(keyBuffer);
328
337
  };
@@ -331,7 +340,7 @@ class TinyCrypto {
331
340
  });
332
341
  } else {
333
342
  const hexKey = fs.readFileSync(file, 'utf8');
334
- const keyBuffer = Buffer.from(hexKey, 'hex');
343
+ const keyBuffer = buffer.Buffer.from(hexKey, 'hex');
335
344
  this.key = keyBuffer;
336
345
  return keyBuffer;
337
346
  }
@@ -409,7 +418,7 @@ class TinyCrypto {
409
418
  else if (typeof config.authTagLength !== 'undefined')
410
419
  throw new Error('Invalid or missing "authTagLength" property. Expected a number.');
411
420
 
412
- if (typeof config.key === 'string') this.key = Buffer.from(config.key, 'hex');
421
+ if (typeof config.key === 'string') this.key = buffer.Buffer.from(config.key, 'hex');
413
422
  else if (typeof config.key !== 'undefined')
414
423
  throw new Error('Invalid or missing "key" property. Expected a hexadecimal string.');
415
424
  }
@@ -532,7 +541,7 @@ class TinyCrypto {
532
541
  array: (value) => value,
533
542
  object: (value) => value,
534
543
  string: (value) => String(value),
535
- buffer: (value) => Buffer.from(value, 'base64'),
544
+ buffer: (value) => buffer.Buffer.from(value, 'base64'),
536
545
  };
537
546
 
538
547
  /**
@@ -265,3 +265,4 @@ declare class TinyCrypto {
265
265
  }): void;
266
266
  #private;
267
267
  }
268
+ import { Buffer } from 'buffer';
@@ -1,7 +1,16 @@
1
1
  import crypto from 'crypto';
2
2
  import fs from 'fs';
3
+ import { Buffer } from 'buffer';
3
4
  import { objType } from '../../v1/basics/objFilter.mjs';
4
- // Detecta se estamos no browser
5
+ /**
6
+ * Determines if the environment is a browser.
7
+ *
8
+ * This constant checks if the code is running in a browser environment by verifying if
9
+ * the `window` object and the `window.document` object are available. It will return `true`
10
+ * if the environment is a browser, and `false` otherwise (e.g., in a Node.js environment).
11
+ *
12
+ * @constant {boolean}
13
+ */
5
14
  const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
6
15
  /**
7
16
  * TinyCrypto is a utility class that provides methods for secure key generation,
package/docs/README.md CHANGED
@@ -14,6 +14,8 @@ This folder contains external libraries and utility modules that are designed to
14
14
 
15
15
  - 🔐 **[TinyCrypto.md](./libs/TinyCrypto.md)** — A flexible and browser-compatible AES-256-GCM encryption utility with support for complex JavaScript types like `Date`, `RegExp`, `Buffer`, and even DOM elements (in the browser).
16
16
 
17
+ - 📄 **[TinyCertCrypto.md](./libs/TinyCertCrypto.md)** — A lightweight tool for managing RSA key pairs and X.509 certificates with support for generation, PEM parsing, encryption/decryption of JSON, and certificate metadata extraction. Works in both Node.js and browser environments (with limitations in browser).
18
+
17
19
  ---
18
20
 
19
21
  ### 2. **`basics/`**
@@ -0,0 +1,202 @@
1
+ # ✨ Tiny Cert Crypto
2
+
3
+ A lightweight 🔐 utility for managing, generating, and handling **X.509 certificates** and **RSA key pairs**.
4
+ Built with flexibility in mind — runs seamlessly in both **Node.js** and **browser** environments! 🌍
5
+
6
+ ---
7
+
8
+ ## 📦 Features
9
+
10
+ - 🛠️ RSA key pair generation (**Node.js only**)
11
+ - 🧾 Self-signed X.509 certificate creation
12
+ - 🧬 Support for PEM-based 🔑 public/private keys and certificates
13
+ - 🧊 JSON encryption & decryption using Base64 encoding
14
+ - 🕵️ Metadata extraction from certificates (issuer, subject, validity, etc.)
15
+ - 📁 Flexible key loading: from memory, local files (Node.js), or URLs (browser)
16
+
17
+ ---
18
+
19
+ ## 🚀 Getting Started
20
+
21
+ ### 📚 Constructor
22
+
23
+ ```js
24
+ const instance = new TinyCertCrypto({
25
+ publicCertPath: 'cert.pem', // Path to public cert (Node.js)
26
+ privateKeyPath: 'key.pem', // Path to private key (Node.js)
27
+ publicCertBuffer: null, // String or Buffer in memory (Node.js/browser)
28
+ privateKeyBuffer: null, // String or Buffer in memory (Node.js/browser)
29
+ cryptoType: 'RSA-OAEP', // Encryption algorithm (default: 'RSA-OAEP')
30
+ });
31
+ ```
32
+
33
+ > 🔍 In **browser environments**, at least `publicCertPath` or `publicCertBuffer` must be provided.
34
+
35
+ ---
36
+
37
+ ## 🧪 Core Methods
38
+
39
+ ### 🔧 `async init()`
40
+ Initializes the certificate and key system from files, memory buffers, or URLs.
41
+
42
+ - Loads the public certificate/key.
43
+ - Optionally loads the private key.
44
+ - Detects whether you’re running in Node.js or the browser and adjusts behavior accordingly.
45
+
46
+ ---
47
+
48
+ ### 📑 `extractCertMetadata()`
49
+ Returns parsed metadata from the loaded certificate.
50
+
51
+ ```js
52
+ {
53
+ subject: { names: {}, shortNames: {}, raw: "CN=example.com,O=MyOrg" },
54
+ issuer: { names: {}, shortNames: {}, raw: "CN=example.com,O=MyOrg" },
55
+ serialNumber: '...',
56
+ validFrom: Date,
57
+ validTo: Date
58
+ }
59
+ ```
60
+
61
+ ---
62
+
63
+ ### 🛡️ `encryptJson(jsonObject)`
64
+ Encrypts a JavaScript object using the loaded **public key**, returning a **Base64-encoded string**.
65
+
66
+ ```js
67
+ const encrypted = instance.encryptJson({ hello: "world" });
68
+ ```
69
+
70
+ ---
71
+
72
+ ### 🔓 `decryptToJson(base64String)`
73
+ Decrypts a Base64 string using the **private key**, returning the original JSON object.
74
+
75
+ ```js
76
+ const json = instance.decryptToJson(encrypted);
77
+ ```
78
+
79
+ ---
80
+
81
+ ### 🔍 `hasKeys()`
82
+ Returns `true` if both `publicKey` and `privateKey` are loaded.
83
+
84
+ ---
85
+
86
+ ### 📜 `hasCert()`
87
+ Returns `true` if a certificate (`publicCert`) is loaded.
88
+
89
+ ---
90
+
91
+ ### ♻️ `reset()`
92
+ Resets the internal state, clearing:
93
+ - `publicKey`
94
+ - `privateKey`
95
+ - `publicCert`
96
+ - `metadata`
97
+ - `source`
98
+
99
+ ---
100
+
101
+ ### 📦 `fetchNodeForge()` & `getNodeForge()`
102
+ Handles lazy-loading and reuse of the `node-forge` module.
103
+
104
+ Use if you want to access Forge directly without importing it yourself:
105
+
106
+ ```js
107
+ const forge = await instance.fetchNodeForge();
108
+ ```
109
+
110
+ ---
111
+
112
+ ## 🧠 Internals & Design
113
+
114
+ - 🔍 Uses regular expressions to detect PEM types (`CERTIFICATE`, `PUBLIC KEY`, `PRIVATE KEY`)
115
+ - 🧪 Automatically parses PEM buffers and files depending on the runtime
116
+ - 🔐 Encrypts data with the selected algorithm (`RSA-OAEP`, etc.)
117
+ - 🧬 X.509 certificate metadata extraction is done via `node-forge`
118
+
119
+ ---
120
+
121
+ ## 🧰 Requirements
122
+
123
+ | Environment | Requirement |
124
+ |-------------|--------------------|
125
+ | Node.js | `node-forge` |
126
+ | Browser | Works with native `fetch()` and `TextDecoder` |
127
+
128
+ ---
129
+
130
+ ## 😺 Example Use Case
131
+
132
+ ```js
133
+ const crypto = new TinyCertCrypto({ publicCertPath: 'cert.pem', privateKeyPath: 'key.pem' });
134
+ await crypto.init();
135
+
136
+ const data = { secret: 'I love ponies' };
137
+ const encrypted = crypto.encryptJson(data);
138
+ const decrypted = crypto.decryptToJson(encrypted);
139
+
140
+ console.log(decrypted); // { secret: 'I love ponies' }
141
+ ```
142
+
143
+ ---
144
+
145
+ ### 🧾 `async generateX509Cert(subjectFields, options = {})`
146
+ Generates a new **RSA key pair** and a **self-signed X.509 certificate** using the provided subject information.
147
+
148
+ 🔐 This is ideal for internal services, development environments, or cryptographic testing tools where a trusted CA is not required.
149
+
150
+ ---
151
+
152
+ **🧬 Parameters:**
153
+
154
+ - `subjectFields` (`Object`) – Describes the identity fields that will be embedded into the certificate's subject and issuer:
155
+ - Common fields include:
156
+ - `CN`: Common Name (e.g. domain or hostname)
157
+ - `O`: Organization Name
158
+ - `OU`: Organizational Unit
159
+ - `L`: Locality (City)
160
+ - `ST`: State or Province
161
+ - `C`: Country (2-letter code)
162
+ - `emailAddress`: Optional email field
163
+
164
+ - `options` (`Object`) – Optional configuration:
165
+ - `keySize` (`number`) – RSA key size in bits (default: `2048`)
166
+ - `validityInYears` (`number`) – Certificate validity period (default: `1`)
167
+ - `randomBytesLength` (`number`) – Length of the serial number (default: `16`)
168
+ - `digestAlgorithm` (`string`) – Digest algorithm used to sign the certificate (default: `'sha256'`)
169
+ - `forgeInstance` (`object`) – Optionally inject a specific instance of `node-forge`
170
+ - `cryptoType` (`string`) – Encryption scheme used for later operations (e.g., `'RSA-OAEP'`, `'RSAES-PKCS1-V1_5'`)
171
+
172
+ ---
173
+
174
+ **✅ Returns:**
175
+
176
+ An object containing all the generated artifacts:
177
+
178
+ ```js
179
+ {
180
+ publicKey: '-----BEGIN PUBLIC KEY-----...',
181
+ privateKey: '-----BEGIN PRIVATE KEY-----...',
182
+ cert: '-----BEGIN CERTIFICATE-----...'
183
+ }
184
+ ```
185
+
186
+ - `publicKey`: The newly generated **PEM-encoded RSA public key**
187
+ - `privateKey`: The corresponding **PEM-encoded RSA private key**
188
+ - `cert`: A **PEM-encoded X.509 certificate** that is **self-signed** with the private key and matches the provided subject
189
+
190
+ ---
191
+
192
+ **📌 Notes:**
193
+
194
+ - 🔄 The `subject` and `issuer` of the certificate are the same (self-signed).
195
+ - ⏳ The certificate `validFrom` is set to the current date, and `validTo` is based on the `validityInYears` option.
196
+ - 🔢 A secure random `serialNumber` is generated using `crypto.randomBytes`.
197
+
198
+ ---
199
+
200
+ **⚠️ Availability:**
201
+
202
+ > This method is only available in **Node.js environments** due to its dependency on the native `crypto` module and synchronous file access via `fs`.
package/package.json CHANGED
@@ -1,15 +1,19 @@
1
1
  {
2
2
  "name": "tiny-essentials",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.",
5
5
  "scripts": {
6
6
  "test": "npm run test:mjs && npm run test:cjs && npm run test:js",
7
7
  "test:js": "npx babel-node test/index.js",
8
8
  "test:mjs": "node test/index.mjs",
9
9
  "test:cjs": "node test/index.cjs",
10
- "fix:prettier": "prettier --write ./src/* && prettier --write ./test/*",
10
+ "fix:prettier": "npm run fix:prettier:src && npm run fix:prettier:test && npm run fix:prettier:rollup.config && npm run fix:prettier:webpack.config",
11
+ "fix:prettier:src": "prettier --write ./src/*",
12
+ "fix:prettier:test": "prettier --write ./test/*",
13
+ "fix:prettier:rollup.config": "prettier --write ./rollup.config.mjs",
14
+ "fix:prettier:webpack.config": "prettier --write ./webpack.config.mjs",
11
15
  "auto-build": "npm run build",
12
- "build": "tsc -p tsconfig.json && rollup -c",
16
+ "build": "tsc -p tsconfig.json && rollup -c && webpack --mode production",
13
17
  "build-clean": "npm run clean && npm run build",
14
18
  "build-dist": "npm run build",
15
19
  "build-browserify": "npx browserify build/browserify.js -p esmify > dist/TinyAiApi.web.js",
@@ -58,7 +62,6 @@
58
62
  "@rollup/plugin-commonjs": "^28.0.3",
59
63
  "@rollup/plugin-json": "^6.1.0",
60
64
  "@rollup/plugin-node-resolve": "^16.0.1",
61
- "@rollup/plugin-terser": "^0.4.4",
62
65
  "@rollup/plugin-typescript": "^12.1.2",
63
66
  "babel-preset-es2015": "^6.24.1",
64
67
  "byte-length": "^1.0.2",
@@ -72,15 +75,17 @@
72
75
  "moment-timezone": "^0.5.48",
73
76
  "mysql": "^2.18.1",
74
77
  "node-fetch": "2.7.0",
78
+ "node-forge": "^1.3.1",
79
+ "node-polyfill-webpack-plugin": "^4.1.0",
75
80
  "object-hash": "^3.0.0",
76
81
  "prettier": "3.5.3",
77
82
  "rollup": "^4.40.0",
78
- "rollup-plugin-polyfill-node": "^0.13.0",
79
83
  "rollup-preserve-directives": "^1.1.3",
80
84
  "tinycolor2": "^1.6.0",
81
85
  "tslib": "^2.8.1",
82
86
  "type-fest": "^4.40.0",
83
87
  "typescript": "^5.8.3",
84
- "util": "^0.12.5"
88
+ "webpack": "^5.99.6",
89
+ "webpack-cli": "^6.0.1"
85
90
  }
86
91
  }
@@ -0,0 +1,69 @@
1
+ import path from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ import webpack from 'webpack';
4
+ import NodePolyfillPlugin from 'node-polyfill-webpack-plugin';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ // Add modules
10
+ const modules = [];
11
+ const addModule = (entry, library, isClass = false) => {
12
+ const baseConfig = {
13
+ entry,
14
+ output: {
15
+ path: path.resolve(__dirname, 'dist'),
16
+ library,
17
+ libraryTarget: 'window',
18
+ libraryExport: isClass ? library : undefined,
19
+ },
20
+ optimization: {
21
+ runtimeChunk: false,
22
+ splitChunks: false,
23
+ },
24
+ plugins: [
25
+ new NodePolyfillPlugin(),
26
+ new webpack.ProvidePlugin({
27
+ process: 'process/browser',
28
+ }),
29
+ ],
30
+ };
31
+ modules.push(
32
+ // Non-minified version
33
+ {
34
+ ...baseConfig,
35
+ mode: 'development',
36
+ output: {
37
+ ...baseConfig.output,
38
+ filename: `${library}.js`,
39
+ },
40
+ optimization: {
41
+ ...baseConfig.optimization,
42
+ minimize: false,
43
+ },
44
+ },
45
+ // Minified version
46
+ {
47
+ ...baseConfig,
48
+ mode: 'production',
49
+ output: {
50
+ ...baseConfig.output,
51
+ filename: `${library}.min.js`,
52
+ },
53
+ optimization: {
54
+ ...baseConfig.optimization,
55
+ minimize: true,
56
+ },
57
+ },
58
+ );
59
+ };
60
+
61
+ // Main
62
+ addModule('./src/v1/index.mjs', 'TinyEssentials');
63
+ addModule('./src/v1/basics/index.mjs', 'TinyBasicsEs');
64
+
65
+ addModule('./src/v1/build/TinyLevelUp.mjs', 'TinyLevelUp', true);
66
+ addModule('./src/v1/build/TinyCertCrypto.mjs', 'TinyCertCrypto', true);
67
+ addModule('./src/v1/build/TinyCrypto.mjs', 'TinyCrypto', true);
68
+
69
+ export default modules;