@lumjs/encode 2.3.2 → 2.4.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.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.4.0] - 2026-01-19
10
+ ### Added
11
+ - A new `pem` module (which exports a `PEM` class) for parsing PEM strings.
12
+ - Tests for the `pem` module.
13
+ - A `str2ta()` function was added to the `util` module.
14
+ ### Fixed
15
+ - A fatal error in the `base64.encodeData()` function.
16
+
9
17
  ## [2.3.2] - 2026-01-14
10
18
  ### Fixed
11
19
  - More things I missed, sigh.
@@ -77,7 +85,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
85
  ### Added
78
86
  - Initial release.
79
87
 
80
- [Unreleased]: https://github.com/supernovus/lum.encode.js/compare/v2.3.2...HEAD
88
+ [Unreleased]: https://github.com/supernovus/lum.encode.js/compare/v2.4.0...HEAD
89
+ [2.4.0]: https://github.com/supernovus/lum.encode.js/compare/v2.3.2...v2.4.0
81
90
  [2.3.2]: https://github.com/supernovus/lum.encode.js/compare/v2.3.1...v2.3.2
82
91
  [2.3.1]: https://github.com/supernovus/lum.encode.js/compare/v2.3.0...v2.3.1
83
92
  [2.3.0]: https://github.com/supernovus/lum.encode.js/compare/v2.2.2...v2.3.0
package/lib/base64.js CHANGED
@@ -339,7 +339,7 @@ async function fromDataUrl(dataUrl, options={})
339
339
  */
340
340
  async function encodeData(data, options={})
341
341
  {
342
- let base64 = await toDataUrl(data, options).replace(R_PRE, '');
342
+ let base64 = (await toDataUrl(data, options)).replace(R_PRE, '');
343
343
  return options.url ? urlize(base64, options) : base64;
344
344
  }
345
345
 
package/lib/index.js CHANGED
@@ -66,6 +66,12 @@ lazy(exports, 'HMAC', () => require('./hmac'), E);
66
66
  */
67
67
  lazy(exports, 'HOTP', () => require('./hotp'), E);
68
68
 
69
+ /**
70
+ * @name module:@lumjs/encode.PEM
71
+ * @see {@link module:@lumjs/encode/pem}
72
+ */
73
+ lazy(exports, 'PEM', () => require('./pem'), E);
74
+
69
75
  /**
70
76
  * @name module:@lumjs/encode.TOTP
71
77
  * @see {@link module:@lumjs/encode/totp}
package/lib/pem.js ADDED
@@ -0,0 +1,128 @@
1
+ 'use strict';
2
+
3
+ const { str2ta } = require('./util');
4
+
5
+ const UI8_FB64 = (typeof Uint8Array.fromBase64 === 'function');
6
+ const PEM_TEXT = /^\s*-----BEGIN\s+(?<label>[A-Z\s]+)-----\n(?<base64>.*?)\n-----END\s+\k<label>-----\s*$/s;
7
+ const parseText = (str) => (PEM_TEXT.exec(str)?.groups ?? null);
8
+ const validInfo = (pem) => (pem
9
+ && typeof pem === 'object'
10
+ && typeof pem.label === 'string'
11
+ && typeof pem.base64 === 'string'
12
+ );
13
+
14
+ /**
15
+ * A class for parsing and decoding PEM documents.
16
+ *
17
+ * PEM is a format commonly used for encryption keys.
18
+ * See: https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail
19
+ *
20
+ * @alias {module:@lumjs/encode/pem}
21
+ */
22
+ class PEM {
23
+
24
+ /**
25
+ * Parse a string into a PEM object instance.
26
+ *
27
+ * This method is strict and will throw an error on failure.
28
+ * For a more lenient way to parse PEM documents, see the
29
+ * {@link module:@lumjs/encode/pem.parse parse()} method.
30
+ *
31
+ * @param {string} pem - PEM format string to be parsed.
32
+ * @throws {TypeError} If the `pem` argument is an invalid value.
33
+ * @throws {SyntaxErrror} If the `pem` string was not able to be parsed.
34
+ */
35
+ constructor(pem) {
36
+
37
+ if (typeof pem === 'string') {
38
+ let pemStr = pem;
39
+ pem = parseText(pemStr);
40
+ if (!validInfo(pem)) {
41
+ console.error('new PEM()', pemStr);
42
+ throw new SyntaxError("invalid PEM string passed to PEM constructor");
43
+ }
44
+ }
45
+ else if (!validInfo(pem)) {
46
+ console.error('new PEM()', pem);
47
+ throw new TypeError("invalid argument passed to PEM constructor");
48
+ }
49
+
50
+ // Copy the properties from the info into this.
51
+ Object.assign(this, pem);
52
+ }
53
+
54
+ /**
55
+ * Decode the base64 content.
56
+ *
57
+ * @param {(boolean|function)} [typeClass=false] Return a TypedArray?
58
+ *
59
+ * This may be set to the constructor function of any TypedArray class.
60
+ * It may also be set to `true` as an alias for `Uint8Array`.
61
+ *
62
+ * If it is set to `false` (the default), then the binary string output
63
+ * from the `atob()` global function will be used as the return value.
64
+ *
65
+ * If this is set to Uint8Array (either explicitly or by using `true`),
66
+ * and a method named `Uint8Array.fromBase64` exists, then this will use
67
+ * that to parse the base64 content rather than using the
68
+ * {@link module:@lumjs/encode/util.str2ta str2ta()} function.
69
+ *
70
+ * @returns {(string|TypedArray|Error)}
71
+ *
72
+ * If an error is thrown by any functions being used to decode the base64
73
+ * content, that error will be the return value.
74
+ *
75
+ * Otherwise the `typeClass` argument will determine the returned type.
76
+ */
77
+ decode(typeClass=false) {
78
+ if (typeClass === true) {
79
+ typeClass = Uint8Array;
80
+ }
81
+
82
+ let val = null;
83
+
84
+ if (UI8_FB64 && typeClass === Uint8Array) {
85
+ try {
86
+ val = typeClass.fromBase64(this.base64);
87
+ } catch (err) {
88
+ return err;
89
+ }
90
+ return val;
91
+ }
92
+
93
+ try {
94
+ val = atob(this.base64);
95
+ } catch (err) {
96
+ return err;
97
+ }
98
+
99
+ if (typeClass && typeof val === 'string') {
100
+ try {
101
+ val = str2ta(val, typeClass);
102
+ } catch (err) {
103
+ return err;
104
+ }
105
+ }
106
+
107
+ return val;
108
+ }
109
+
110
+ /**
111
+ * Parse a string into a PEM object instance.
112
+ *
113
+ * This is almost identical to the main class constructor,
114
+ * except this version will simply return null if the argument
115
+ * could not be parsed as a valid PEM string.
116
+ *
117
+ * @param {string} pemText - PEM format string to be parsed.
118
+ * @returns {?module:@lumjs/encode/pem} A PEM instance;
119
+ * or null if the pemText could not be parsed.
120
+ */
121
+ static parse(pemText) {
122
+ let info = parseText(pemText);
123
+ return info ? new this(info) : info;
124
+ }
125
+
126
+ }
127
+
128
+ module.exports = PEM;
package/lib/util.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  'use strict';
6
6
 
7
- const {N} = require('@lumjs/core/types');
7
+ const { TypedArray } = require('@lumjs/core/types');
8
8
 
9
9
  /**
10
10
  * Return the ASCII/Unicode number for a character.
@@ -96,7 +96,7 @@ exports.ord = function (string)
96
96
  */
97
97
  exports.numByteArray = function (numStr, options={})
98
98
  {
99
- if (typeof options === N)
99
+ if (typeof options === 'number')
100
100
  {
101
101
  options = {size: options};
102
102
  }
@@ -104,7 +104,7 @@ exports.numByteArray = function (numStr, options={})
104
104
  const numOpt = (name, defval, min, max) =>
105
105
  {
106
106
  const optval = options[name];
107
- if (typeof optval !== N)
107
+ if (typeof optval !== 'number')
108
108
  { // Was not a number, skip it.
109
109
  return defval;
110
110
  }
@@ -230,3 +230,43 @@ exports.hexToBytes = function(hex) {
230
230
  return bytes;
231
231
  }
232
232
 
233
+ /**
234
+ * Convert a binary string into a TypedArray.
235
+ *
236
+ * Inspired by the str2ab() example from:
237
+ * https://developer.chrome.com/blog/how-to-convert-arraybuffer-to-and-from-string
238
+ *
239
+ * The biggest difference being this version supports specifying the specific
240
+ * TypedArray class you want to use, and it returns the TypedArray by default
241
+ * rather than the ArrayBuffer.
242
+ *
243
+ * To get the ArrayBuffer just use: `str2ta(string).buffer;`
244
+ *
245
+ * @param {string} str - Binary string to convert.
246
+ * @param {function} [typeClass=Uint8Array] TypedArray class to use;
247
+ * MUST be a TypedArray class constructor. Default is `Uint8Array`.
248
+ * @returns {TypedArray} Will be an instance of `typeClass`.
249
+ * @throws {TypeError} If invalid arguments were passed.
250
+ */
251
+ function str2ta(str, typeClass=Uint8Array)
252
+ {
253
+ let valid = {
254
+ str: (typeof str === 'string'),
255
+ typeClass: (TypedArray.isPrototypeOf(typeClass)),
256
+ }
257
+ if (!valid.str || !valid.typeClass) {
258
+ console.error('str2ab valid:', valid, 'values: ', {str, typeClass});
259
+ throw new TypeError("invalid arguments");
260
+ }
261
+
262
+ let buf = new ArrayBuffer(str.length*typeClass.BYTES_PER_ELEMENT);
263
+ let bufView = new typeClass(buf);
264
+ for (let i = 0, strLen = str.length; i < strLen; i++)
265
+ {
266
+ bufView[i] = str.charCodeAt(i);
267
+ }
268
+
269
+ return bufView;
270
+ }
271
+
272
+ exports.str2ta = str2ta;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumjs/encode",
3
- "version": "2.3.2",
3
+ "version": "2.4.0",
4
4
  "main": "lib/index.js",
5
5
  "exports":
6
6
  {
@@ -11,6 +11,7 @@
11
11
  "./hash": "./lib/hash.js",
12
12
  "./hmac": "./lib/hmac.js",
13
13
  "./hotp": "./lib/hotp.js",
14
+ "./pem": "./lib/pem.js",
14
15
  "./signature": "./lib/signature.js",
15
16
  "./totp": "./lib/totp.js",
16
17
  "./util": "./lib/util.js",