@lumjs/encode 2.3.2 → 2.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/CHANGELOG.md CHANGED
@@ -6,6 +6,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.4.1] - 2026-02-09
10
+ ### Changed
11
+ - Refactored hashifier a bit to make resetting progressive digests simpler.
12
+ - Made all the debugging info in hotp/totp modules optional.
13
+ - Added `expires` to compiled options for totp module; provides the number
14
+ of seconds until the _current_ code expires.
15
+ - Added a getExpiry() method to totp class that calculates and returns
16
+ just the current expiry information (useful for countdown displays).
17
+ - Muted an expected error message in a test file.
18
+ - Some other minor cleanups.
19
+
20
+ ## [2.4.0] - 2026-01-19
21
+ ### Added
22
+ - A new `pem` module (which exports a `PEM` class) for parsing PEM strings.
23
+ - Tests for the `pem` module.
24
+ - A `str2ta()` function was added to the `util` module.
25
+ ### Fixed
26
+ - A fatal error in the `base64.encodeData()` function.
27
+
9
28
  ## [2.3.2] - 2026-01-14
10
29
  ### Fixed
11
30
  - More things I missed, sigh.
@@ -77,7 +96,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
96
  ### Added
78
97
  - Initial release.
79
98
 
80
- [Unreleased]: https://github.com/supernovus/lum.encode.js/compare/v2.3.2...HEAD
99
+ [Unreleased]: https://github.com/supernovus/lum.encode.js/compare/v2.4.1...HEAD
100
+ [2.4.1]: https://github.com/supernovus/lum.encode.js/compare/v2.4.0...v2.4.1
101
+ [2.4.0]: https://github.com/supernovus/lum.encode.js/compare/v2.3.2...v2.4.0
81
102
  [2.3.2]: https://github.com/supernovus/lum.encode.js/compare/v2.3.1...v2.3.2
82
103
  [2.3.1]: https://github.com/supernovus/lum.encode.js/compare/v2.3.0...v2.3.1
83
104
  [2.3.0]: https://github.com/supernovus/lum.encode.js/compare/v2.2.2...v2.3.0
package/lib/base64.js CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- const {S,B,F,isObj} = require('@lumjs/core/types');
2
+ const { isObj } = require('@lumjs/core/types');
3
3
 
4
4
  const D_MIME = 'application/octet-stream';
5
5
  const D_ENC = 'utf-8';
@@ -8,7 +8,7 @@ const P_B64 = ';base64,';
8
8
  const R_PRE = /^data\:(.*?);base64,/;
9
9
  const B_64U = 'base64url';
10
10
 
11
- const UI8_FB64 = (typeof Uint8Array.fromBase64 === F);
11
+ const UI8_FB64 = (typeof Uint8Array.fromBase64 === 'function');
12
12
  const URL_CHARS = /_-/;
13
13
 
14
14
  /**
@@ -103,7 +103,7 @@ function toBytes(base64, options={})
103
103
  */
104
104
  function fromBytes(bytes, options={})
105
105
  {
106
- if (typeof bytes.toBase64 === F)
106
+ if (typeof bytes.toBase64 === 'function')
107
107
  {
108
108
  return bytes.toBase64(options);
109
109
  }
@@ -139,7 +139,7 @@ function fromBytes(bytes, options={})
139
139
  */
140
140
  function encodeText(data, options={})
141
141
  {
142
- if (typeof options === B)
142
+ if (typeof options === 'boolean')
143
143
  { // Assume the 'url' option.
144
144
  options = {url: options};
145
145
  }
@@ -149,15 +149,15 @@ function encodeText(data, options={})
149
149
  const encoder = new TextEncoder();
150
150
  data = encoder.encode(data);
151
151
  }
152
- const toB64 = (typeof data.toBase64 === F);
152
+ const toB64 = (typeof data.toBase64 === 'function');
153
153
 
154
154
  if (toB64 && options.url)
155
155
  {
156
- if (typeof options.alphabet !== S)
156
+ if (typeof options.alphabet !== 'string')
157
157
  {
158
158
  options.alphabet = B_64U;
159
159
  }
160
- if (!options.useTildes && typeof options.omitPadding !== B)
160
+ if (!options.useTildes && typeof options.omitPadding !== 'boolean')
161
161
  {
162
162
  options.omitPadding = true;
163
163
  }
@@ -192,7 +192,7 @@ function encodeText(data, options={})
192
192
  */
193
193
  function decodeText(base64, options={})
194
194
  {
195
- if (typeof options === B)
195
+ if (typeof options === 'boolean')
196
196
  { // Assume the 'url' option.
197
197
  options = {url: options};
198
198
  }
@@ -201,7 +201,7 @@ function decodeText(base64, options={})
201
201
  { // Unless explicitly disabled, use deurlize() first.
202
202
  if (UI8_FB64)
203
203
  {
204
- if (typeof options.alphabet !== S)
204
+ if (typeof options.alphabet !== 'string')
205
205
  {
206
206
  if (URL_CHARS.test(base64))
207
207
  {
@@ -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
 
@@ -365,7 +365,7 @@ async function decodeData(base64, options={})
365
365
  { // Unless explicitly disabled, use deurlize() first.
366
366
  base64 = deurlize(base64);
367
367
  }
368
- const type = (typeof options.type === S) ? options.type : D_MIME;
368
+ const type = (typeof options.type === 'string') ? options.type : D_MIME;
369
369
  base64 = P_DATA+type+P_B64+base64;
370
370
  }
371
371
 
@@ -392,7 +392,7 @@ async function decodeData(base64, options={})
392
392
  */
393
393
  function encode(data, options={})
394
394
  {
395
- if (options.blob || options.file || (typeof data !== S))
395
+ if (options.blob || options.file || (typeof data !== 'string'))
396
396
  {
397
397
  return encodeData(data, options);
398
398
  }
package/lib/base91.js CHANGED
@@ -1,5 +1,3 @@
1
- const {S,B} = require('@lumjs/core/types');
2
-
3
1
  /**
4
2
  * A pure-Javascript base91 library.
5
3
  *
@@ -33,7 +31,7 @@ exports.encode = function(data)
33
31
  {
34
32
  let output = '';
35
33
  let len = data.length,
36
- isStr = (typeof data === S),
34
+ isStr = (typeof data === 'string'),
37
35
  queue = 0,
38
36
  numbits = 0,
39
37
  value = 0;
@@ -131,7 +129,7 @@ exports.decode = function(data, opts={})
131
129
  {
132
130
  const output = [];
133
131
  let len = data.length,
134
- isStr = (typeof data === S),
132
+ isStr = (typeof data === 'string'),
135
133
  queue = 0,
136
134
  numbits = 0,
137
135
  value = -1,
@@ -164,7 +162,7 @@ exports.decode = function(data, opts={})
164
162
  output.push(queue | (value << numbits));
165
163
  }
166
164
 
167
- if (typeof opts === B)
165
+ if (typeof opts === 'boolean')
168
166
  {
169
167
  opts = {string: opts};
170
168
  }
package/lib/hash.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const {S,F,isObj,isNil} = require('@lumjs/core/types');
3
+ const { isObj, isNil } = require('@lumjs/core/types');
4
4
 
5
5
  const util = require('./util');
6
6
  const base32 = require('./base32');
@@ -130,7 +130,7 @@ module.exports = class
130
130
  */
131
131
  constructor(options={})
132
132
  {
133
- if (typeof options === S)
133
+ if (typeof options === 'string')
134
134
  {
135
135
  options = {algo: options};
136
136
  }
@@ -146,7 +146,7 @@ module.exports = class
146
146
  }
147
147
 
148
148
  this.algo = this.getAlgorithm(
149
- (typeof options.algo === S)
149
+ (typeof options.algo === 'string')
150
150
  ? options.algo
151
151
  : D_ALGO);
152
152
 
@@ -243,11 +243,11 @@ module.exports = class
243
243
 
244
244
  const joiner = this.current.joiner;
245
245
 
246
- if (typeof joiner === F)
246
+ if (typeof joiner === 'function')
247
247
  {
248
248
  input = joiner.call(this, this.current.hash);
249
249
  }
250
- else if (typeof joiner === S)
250
+ else if (typeof joiner === 'string')
251
251
  {
252
252
  input = this.current.hash.join(joiner);
253
253
  }
@@ -258,10 +258,10 @@ module.exports = class
258
258
  }
259
259
 
260
260
  // Now clear the current hash values.
261
- this.current.hash.length = 0;
261
+ this.reset();
262
262
  }
263
263
 
264
- if (typeof input === S)
264
+ if (typeof input === 'string')
265
265
  { // This is super simple.
266
266
  const encoder = new TextEncoder();
267
267
  input = encoder.encode(input);
@@ -377,12 +377,12 @@ module.exports = class
377
377
  */
378
378
  add(input, opts={})
379
379
  {
380
- if (typeof input !== S)
380
+ if (typeof input !== 'string')
381
381
  {
382
382
  let enc = this.current.encoder,
383
383
  eopts = null;
384
384
 
385
- if (typeof enc === S)
385
+ if (typeof enc === 'string')
386
386
  {
387
387
  enc = DATA_ENCODERS[enc];
388
388
  eopts = this.defaults[enc];
@@ -391,11 +391,11 @@ module.exports = class
391
391
  // Compile the options for the encoder.
392
392
  eopts = Object.assign({hashifier: this}, eopts, opts);
393
393
 
394
- if (typeof enc === F)
394
+ if (typeof enc === 'function')
395
395
  { // Call the function, using the hashifier instance as `this`.
396
396
  input = enc.call(this, input, eopts);
397
397
  }
398
- else if (isObj(enc) && typeof enc.encode === F)
398
+ else if (isObj(enc) && typeof enc.encode === 'function')
399
399
  { // Using an encoder object/instance.
400
400
  input = enc.encode(input, eopts);
401
401
  }
@@ -432,6 +432,11 @@ module.exports = class
432
432
  return this;
433
433
  }
434
434
 
435
+ reset() {
436
+ this.current.hash.length = 0;
437
+ return this;
438
+ }
439
+
435
440
  static new(opts={})
436
441
  {
437
442
  return new this(opts);
package/lib/hotp.js CHANGED
@@ -3,11 +3,17 @@
3
3
  const HmacEncoder = require('./hmac');
4
4
  const { intToBytes } = require('./util');
5
5
 
6
+ const DEBUG = Object.freeze({
7
+ LOG: 1,
8
+ INFO: 2,
9
+ });
10
+
6
11
  const DEF_OPTS = {
7
12
  algorithm: 'SHA-1',
8
13
  checkSize: 7,
9
- counter: 0,
10
- window: 50
14
+ counter: 0,
15
+ debug: 0,
16
+ window: 50
11
17
  };
12
18
 
13
19
  const cp = Object.assign;
@@ -50,9 +56,11 @@ class HOTP {
50
56
  return [DEF_OPTS];
51
57
  }
52
58
 
53
- async generate(key = this.defaultKey, opts) {
54
- needKey(key);
55
- opts = this.getOptions(opts);
59
+ async generate(key = this.defaultKey, opts, fromVerify=false) {
60
+ if (!fromVerify) {
61
+ needKey(key);
62
+ opts = this.getOptions(opts);
63
+ }
56
64
 
57
65
  let encoder = new HmacEncoder(key, opts);
58
66
  let data = new Uint8Array(intToBytes(opts.counter));
@@ -70,20 +78,27 @@ class HOTP {
70
78
  let code = Array(opts.checkSize - v2.length).join('0') + v2;
71
79
 
72
80
  let res = {
73
- opts,
74
- data,
75
- hash,
76
- hashBytes: hb,
77
- offset,
78
- v1,
79
- v2,
80
81
  code,
82
+ opts,
81
83
  toString() {
82
84
  return this.code;
83
85
  },
84
86
  }
85
87
 
86
- if (opts.debug) console.debug(res.code, res);
88
+ if (opts.debug & DEBUG.INFO) {
89
+ cp(res, {
90
+ data,
91
+ hash,
92
+ hashBytes: hb,
93
+ offset,
94
+ v1,
95
+ v2,
96
+ });
97
+ }
98
+
99
+ if (!fromVerify && (opts.debug & DEBUG.LOG)) {
100
+ console.debug(res.code, res);
101
+ }
87
102
 
88
103
  return res;
89
104
  }
@@ -95,25 +110,36 @@ class HOTP {
95
110
  let win = opts.window;
96
111
  let cnt = opts.counter;
97
112
  let info = { ok: false };
113
+ let di = (opts.debug & DEBUG.INFO);
98
114
 
99
- if (opts.debug) info.stack = [];
115
+ let done = (add) => {
116
+ if (add) cp(info, add); // add final info
117
+ if (opts.debug & DEBUG.LOG) console.debug(info);
118
+
119
+ if (!info.ok && opts.throw) {
120
+ let EClass = isError(opts.throw) ? opts.throw : Error;
121
+ throw new EClass("OTP verification failure");
122
+ }
123
+
124
+ return info;
125
+ }
126
+
127
+ if (di) info.stack = [];
100
128
 
101
129
  for (let i = cnt - win; i <= cnt + win; ++i) {
102
130
  opts.counter = i;
103
- let res = this.generate(key, opts);
104
- if (opts.debug) info.stack.push(res);
131
+ let res = this.generate(key, opts, true);
132
+ if (di) info.stack.push(res);
105
133
  if (res.code === token) {
106
- return cp(info, { ok: true, delta: i - cnt });
134
+ return done({ ok: true, delta: i - cnt });
107
135
  }
108
136
  }
109
137
 
110
- if (opts.throw) {
111
- let EClass = isError(opts.throw) ? opts.throw : Error;
112
- throw new EClass("OTP verification failure");
113
- }
114
-
115
- return info;
138
+ return done();
116
139
  }
117
140
  }
118
141
 
142
+ HOTP.DEBUG = DEBUG;
143
+ HOTP.prototype.DEBUG = DEBUG;
144
+
119
145
  module.exports = HOTP;
package/lib/index.js CHANGED
@@ -3,24 +3,22 @@
3
3
  * @module @lumjs/encode
4
4
  */
5
5
 
6
- const {def,lazy} = require('@lumjs/core/types');
7
-
8
- const E = def.e;
9
-
6
+ const {df,lazy} = require('@lumjs/core');
7
+ const E = {enumerable: true};
10
8
  const util = require('./util');
11
9
 
12
10
  /**
13
11
  * @alias module:@lumjs/encode.util
14
12
  * @see {@link module:@lumjs/encode/util}
15
13
  */
16
- def(exports, 'util', {value: util}, E);
14
+ df(exports, 'util', {value: util}, E);
17
15
 
18
16
  /**
19
17
  * @alias module:@lumjs/encode.ord
20
18
  * @deprecated this alias to `util.ord` will be removed in 3.x.
21
19
  * @see {@link module:@lumjs/encode/util.ord}
22
20
  */
23
- def(exports, 'ord', util.ord, E);
21
+ df(exports, 'ord', util.ord, E);
24
22
 
25
23
  /**
26
24
  * @name module:@lumjs/encode.numByteArray
@@ -28,7 +26,7 @@ def(exports, 'ord', util.ord, E);
28
26
  * @deprecated this alias to `util.numByteArray` will be removed in 3.x.
29
27
  * @see {@link module:@lumjs/encode/util.numByteArray}
30
28
  */
31
- def(exports, 'numByteArray', util.numByteArray, E);
29
+ df(exports, 'numByteArray', util.numByteArray, E);
32
30
 
33
31
  /**
34
32
  * @name module:@lumjs/encode.Base32
@@ -66,6 +64,12 @@ lazy(exports, 'HMAC', () => require('./hmac'), E);
66
64
  */
67
65
  lazy(exports, 'HOTP', () => require('./hotp'), E);
68
66
 
67
+ /**
68
+ * @name module:@lumjs/encode.PEM
69
+ * @see {@link module:@lumjs/encode/pem}
70
+ */
71
+ lazy(exports, 'PEM', () => require('./pem'), E);
72
+
69
73
  /**
70
74
  * @name module:@lumjs/encode.TOTP
71
75
  * @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/totp.js CHANGED
@@ -12,10 +12,16 @@ class TOTP extends HOTP {
12
12
  return [...super.defaultOptions, DEF_OPTS];
13
13
  }
14
14
 
15
+ getExpiry(opts) {
16
+ return this.getOptions(opts).expires;
17
+ }
18
+
15
19
  getOptions() {
16
20
  let opts = super.getOptions(...arguments);
17
21
  if (!opts.time) opts.time = Date.now();
18
- opts.counter = Math.floor((opts.time / 1000) / opts.step);
22
+ let ts = opts.time / 1000;
23
+ opts.counter = Math.floor(ts / opts.step);
24
+ opts.expires = 30 - Math.floor(ts) % 30;
19
25
  return opts;
20
26
  }
21
27
  }
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
  }
@@ -138,7 +138,7 @@ exports.numByteArray = function (numStr, options={})
138
138
  remainder = strLen % len;
139
139
  if (remainder !== 0)
140
140
  { // Something is wrong in the universe...
141
- console.debug({numStr, strLen, len, remainder, arguments});
141
+ console.error({numStr, strLen, len, remainder, arguments});
142
142
  throw new Error("string has remainder after padding");
143
143
  }
144
144
  }
@@ -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.1",
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",