bufferbase 1.3.0 → 3.0.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 (144) hide show
  1. package/README.md +186 -17
  2. package/dist/cjs/bases.d.ts +189 -0
  3. package/dist/cjs/bases.d.ts.map +1 -0
  4. package/dist/cjs/bases.js +134 -0
  5. package/dist/cjs/bases.js.map +1 -0
  6. package/dist/cjs/bufferbase.d.ts +22 -45
  7. package/dist/cjs/bufferbase.d.ts.map +1 -1
  8. package/dist/cjs/bufferbase.js +26 -120
  9. package/dist/cjs/bufferbase.js.map +1 -1
  10. package/dist/cjs/codec-base.d.ts +56 -0
  11. package/dist/cjs/codec-base.d.ts.map +1 -0
  12. package/dist/cjs/codec-base.js +132 -0
  13. package/dist/cjs/codec-base.js.map +1 -0
  14. package/dist/cjs/codec-block.d.ts +47 -0
  15. package/dist/cjs/codec-block.d.ts.map +1 -0
  16. package/dist/cjs/codec-block.js +213 -0
  17. package/dist/cjs/codec-block.js.map +1 -0
  18. package/dist/cjs/codec-block85.d.ts +56 -0
  19. package/dist/cjs/codec-block85.d.ts.map +1 -0
  20. package/dist/cjs/codec-block85.js +271 -0
  21. package/dist/cjs/codec-block85.js.map +1 -0
  22. package/dist/cjs/codec-radix.d.ts +46 -0
  23. package/dist/cjs/codec-radix.d.ts.map +1 -0
  24. package/dist/cjs/codec-radix.js +181 -0
  25. package/dist/cjs/codec-radix.js.map +1 -0
  26. package/dist/cjs/codec.d.ts +38 -0
  27. package/dist/cjs/codec.d.ts.map +1 -0
  28. package/dist/cjs/codec.js +69 -0
  29. package/dist/cjs/codec.js.map +1 -0
  30. package/dist/cjs/codecs.d.ts +20 -0
  31. package/dist/cjs/codecs.d.ts.map +1 -0
  32. package/dist/cjs/codecs.js +19 -0
  33. package/dist/cjs/codecs.js.map +1 -0
  34. package/dist/cjs/errors.d.ts +93 -0
  35. package/dist/cjs/errors.d.ts.map +1 -0
  36. package/dist/cjs/errors.js +130 -0
  37. package/dist/cjs/errors.js.map +1 -0
  38. package/dist/cjs/example.js +49 -33
  39. package/dist/cjs/example.js.map +1 -1
  40. package/dist/cjs/functions.d.ts +58 -0
  41. package/dist/cjs/functions.d.ts.map +1 -0
  42. package/dist/cjs/functions.js +71 -0
  43. package/dist/cjs/functions.js.map +1 -0
  44. package/dist/cjs/index.d.ts +10 -1
  45. package/dist/cjs/index.d.ts.map +1 -1
  46. package/dist/cjs/index.js +35 -4
  47. package/dist/cjs/index.js.map +1 -1
  48. package/dist/cjs/package.json +17 -12
  49. package/dist/cjs/types.d.ts +144 -0
  50. package/dist/cjs/types.d.ts.map +1 -0
  51. package/dist/cjs/types.js +3 -0
  52. package/dist/cjs/types.js.map +1 -0
  53. package/dist/esm/bases.d.ts +189 -0
  54. package/dist/esm/bases.d.ts.map +1 -0
  55. package/dist/esm/bases.js +129 -0
  56. package/dist/esm/bases.js.map +1 -0
  57. package/dist/esm/bufferbase.d.ts +22 -45
  58. package/dist/esm/bufferbase.d.ts.map +1 -1
  59. package/dist/esm/bufferbase.js +21 -115
  60. package/dist/esm/bufferbase.js.map +1 -1
  61. package/dist/esm/codec-base.d.ts +56 -0
  62. package/dist/esm/codec-base.d.ts.map +1 -0
  63. package/dist/esm/codec-base.js +127 -0
  64. package/dist/esm/codec-base.js.map +1 -0
  65. package/dist/esm/codec-block.d.ts +47 -0
  66. package/dist/esm/codec-block.d.ts.map +1 -0
  67. package/dist/esm/codec-block.js +209 -0
  68. package/dist/esm/codec-block.js.map +1 -0
  69. package/dist/esm/codec-block85.d.ts +56 -0
  70. package/dist/esm/codec-block85.d.ts.map +1 -0
  71. package/dist/esm/codec-block85.js +267 -0
  72. package/dist/esm/codec-block85.js.map +1 -0
  73. package/dist/esm/codec-radix.d.ts +46 -0
  74. package/dist/esm/codec-radix.d.ts.map +1 -0
  75. package/dist/esm/codec-radix.js +177 -0
  76. package/dist/esm/codec-radix.js.map +1 -0
  77. package/dist/esm/codec.d.ts +38 -0
  78. package/dist/esm/codec.d.ts.map +1 -0
  79. package/dist/esm/codec.js +60 -0
  80. package/dist/esm/codec.js.map +1 -0
  81. package/dist/esm/codecs.d.ts +20 -0
  82. package/dist/esm/codecs.d.ts.map +1 -0
  83. package/dist/esm/codecs.js +16 -0
  84. package/dist/esm/codecs.js.map +1 -0
  85. package/dist/esm/errors.d.ts +93 -0
  86. package/dist/esm/errors.d.ts.map +1 -0
  87. package/dist/esm/errors.js +119 -0
  88. package/dist/esm/errors.js.map +1 -0
  89. package/dist/esm/example.js +48 -32
  90. package/dist/esm/example.js.map +1 -1
  91. package/dist/esm/functions.d.ts +58 -0
  92. package/dist/esm/functions.d.ts.map +1 -0
  93. package/dist/esm/functions.js +65 -0
  94. package/dist/esm/functions.js.map +1 -0
  95. package/dist/esm/index.d.ts +10 -1
  96. package/dist/esm/index.d.ts.map +1 -1
  97. package/dist/esm/index.js +12 -1
  98. package/dist/esm/index.js.map +1 -1
  99. package/dist/esm/package.json +17 -12
  100. package/dist/esm/types.d.ts +144 -0
  101. package/dist/esm/types.d.ts.map +1 -0
  102. package/dist/esm/types.js +2 -0
  103. package/dist/esm/types.js.map +1 -0
  104. package/package.json +19 -14
  105. package/src/algorithms.test.ts +442 -0
  106. package/src/bases.ts +142 -0
  107. package/src/bufferbase.test.ts +44 -27
  108. package/src/bufferbase.ts +32 -117
  109. package/src/codec-base.ts +181 -0
  110. package/src/codec-block.ts +258 -0
  111. package/src/codec-block85.ts +315 -0
  112. package/src/codec-radix.ts +206 -0
  113. package/src/codec.test.ts +328 -0
  114. package/src/codec.ts +67 -0
  115. package/src/codecs.ts +24 -0
  116. package/src/errors.ts +127 -0
  117. package/src/example.ts +49 -34
  118. package/src/functions.ts +73 -0
  119. package/src/index.ts +39 -6
  120. package/src/types.ts +156 -0
  121. package/dist/cjs/bufferbase.d.mts +0 -60
  122. package/dist/cjs/bufferbase.d.mts.map +0 -1
  123. package/dist/cjs/bufferbase.mjs +0 -150
  124. package/dist/cjs/bufferbase.mjs.map +0 -1
  125. package/dist/cjs/example.d.mts +0 -2
  126. package/dist/cjs/example.d.mts.map +0 -1
  127. package/dist/cjs/example.mjs +0 -39
  128. package/dist/cjs/example.mjs.map +0 -1
  129. package/dist/cjs/index.d.mts +0 -2
  130. package/dist/cjs/index.d.mts.map +0 -1
  131. package/dist/cjs/index.mjs +0 -11
  132. package/dist/cjs/index.mjs.map +0 -1
  133. package/dist/esm/bufferbase.d.mts +0 -60
  134. package/dist/esm/bufferbase.d.mts.map +0 -1
  135. package/dist/esm/bufferbase.mjs +0 -141
  136. package/dist/esm/bufferbase.mjs.map +0 -1
  137. package/dist/esm/example.d.mts +0 -2
  138. package/dist/esm/example.d.mts.map +0 -1
  139. package/dist/esm/example.mjs +0 -37
  140. package/dist/esm/example.mjs.map +0 -1
  141. package/dist/esm/index.d.mts +0 -2
  142. package/dist/esm/index.d.mts.map +0 -1
  143. package/dist/esm/index.mjs +0 -2
  144. package/dist/esm/index.mjs.map +0 -1
@@ -1,150 +1,56 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validate = exports.Validator = exports.Converter = exports.BufferEncoder = exports.BufferSizeError = exports.InvalidCharacterError = exports.Chars = void 0;
4
- /**
5
- * A collection of common bases.
6
- */
7
- exports.Chars = {
8
- Decimal: '0123456789',
9
- Base16: '0123456789ABCDEF',
10
- Base32: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
11
- Base32Crockford: '0123456789ABCDEFGHJKMNPQRSTVWXYZ',
12
- Base36: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
13
- Base52: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
14
- Base58: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
15
- Base64_STD: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
16
- Base64_URL_SAFE: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
17
- Base64_XML_NMTOKEN: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._',
18
- Base64_XML_NAME: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_:',
19
- Ascii85: '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstu',
20
- Base85: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&()*+-;<=>?@^_`{|}~',
21
- Z85: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#',
22
- };
23
- class InvalidCharacterError extends Error {
24
- constructor() {
25
- super(...arguments);
26
- this.message = 'Invalid character found';
27
- }
28
- }
29
- exports.InvalidCharacterError = InvalidCharacterError;
30
- class BufferSizeError extends Error {
31
- constructor() {
32
- super(...arguments);
33
- this.message = 'Buffer size exceeds specified size';
34
- }
35
- }
36
- exports.BufferSizeError = BufferSizeError;
37
2
  /**
38
- * Encodes and decodes buffers to and from a base.
3
+ * @deprecated Use the current API instead:
4
+ * - `encode(buffer, 'base58')` or `Codecs.base58.encode(buffer)`
5
+ * - `decode(encoded, 'base58')` or `Codecs.base58.decode(encoded)`
6
+ * - `convert(input, 'base58', 'base64')` or `Codecs.base58.convertTo(...)`
7
+ * - `validate(input, 'base58')` or `Codecs.base58.validate(input)`
8
+ *
9
+ * These classes take a bare alphabet, which always meant a radix conversion,
10
+ * so they keep behaving exactly as they did.
39
11
  */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.Validator = exports.Converter = exports.BufferEncoder = exports.InvalidCharacterError = exports.BufferSizeError = exports.Chars = void 0;
14
+ const codec_radix_js_1 = require("./codec-radix.js");
15
+ /** @deprecated Import `Chars` from the package root. */
16
+ var bases_js_1 = require("./bases.js");
17
+ Object.defineProperty(exports, "Chars", { enumerable: true, get: function () { return bases_js_1.Chars; } });
18
+ /** @deprecated Import these from the package root. */
19
+ var errors_js_1 = require("./errors.js");
20
+ Object.defineProperty(exports, "BufferSizeError", { enumerable: true, get: function () { return errors_js_1.BufferSizeError; } });
21
+ Object.defineProperty(exports, "InvalidCharacterError", { enumerable: true, get: function () { return errors_js_1.InvalidCharacterError; } });
22
+ /** @deprecated Use `createCodec(alphabet)`. */
40
23
  class BufferEncoder {
41
24
  constructor(baseChars) {
42
- this.baseChars = baseChars;
25
+ this.codec = new codec_radix_js_1.RadixCodec({ alphabet: baseChars, algorithm: 'radix' });
43
26
  }
44
- /**
45
- * Encodes a buffer to a string.
46
- */
47
27
  encode(buffer) {
48
- let result = [];
49
- for (const byte of buffer) {
50
- let carry = byte;
51
- for (let j = 0; j < result.length; j++) {
52
- carry += result[j] * 256;
53
- result[j] = carry % this.baseChars.length;
54
- carry = Math.floor(carry / this.baseChars.length);
55
- }
56
- while (carry > 0) {
57
- result.push(carry % this.baseChars.length);
58
- carry = Math.floor(carry / this.baseChars.length);
59
- }
60
- }
61
- for (const byte of buffer) {
62
- if (byte === 0) {
63
- result.push(0);
64
- }
65
- else {
66
- break;
67
- }
68
- }
69
- return result
70
- .reverse()
71
- .map((index) => this.baseChars[index])
72
- .join('');
28
+ return this.codec.encode(buffer);
73
29
  }
74
- /**
75
- * Decodes a string to a buffer.
76
- */
77
30
  decode(encoded, bufferSize) {
78
- let result = Buffer.alloc(0);
79
- for (const char of encoded) {
80
- const value = this.baseChars.indexOf(char);
81
- if (value === -1)
82
- throw new InvalidCharacterError();
83
- let carry = value;
84
- let tempResult = Buffer.alloc(result.length);
85
- let i;
86
- for (i = 0; i < result.length; i++) {
87
- carry += result[i] * this.baseChars.length;
88
- tempResult[i] = carry % 256;
89
- carry = Math.floor(carry / 256);
90
- }
91
- while (carry > 0) {
92
- tempResult = Buffer.concat([tempResult, Buffer.from([carry % 256])]);
93
- carry = Math.floor(carry / 256);
94
- }
95
- result = tempResult;
96
- }
97
- // buffer size
98
- if (bufferSize && result.length < bufferSize) {
99
- result = Buffer.concat([
100
- result,
101
- Buffer.from(Array(bufferSize - result.length).fill(0)),
102
- ]);
103
- }
104
- if (bufferSize && result.length > bufferSize) {
105
- throw new BufferSizeError();
106
- }
107
- result.reverse();
108
- return result;
31
+ return this.codec.decode(encoded, bufferSize === undefined ? undefined : { size: bufferSize });
109
32
  }
110
33
  }
111
34
  exports.BufferEncoder = BufferEncoder;
112
- /**
113
- * Creates a converter function that can convert between two bases.
114
- */
35
+ /** @deprecated Use `convert()` or `codec.convertTo()`. */
115
36
  class Converter {
116
37
  constructor(inputBase, outputBase) {
117
38
  this.decoder = new BufferEncoder(inputBase);
118
39
  this.encoder = new BufferEncoder(outputBase);
119
40
  }
120
- /**
121
- * Converts a string from the input base to the output base.
122
- */
123
41
  convert(input) {
124
42
  return this.encoder.encode(this.decoder.decode(input));
125
43
  }
126
44
  }
127
45
  exports.Converter = Converter;
46
+ /** @deprecated Use `validate()` or `codec.validate()`. */
128
47
  class Validator {
129
48
  constructor(inputBase) {
130
- this.decorder = new BufferEncoder(inputBase);
49
+ this.codec = new codec_radix_js_1.RadixCodec({ alphabet: inputBase, algorithm: 'radix' });
131
50
  }
132
51
  validate(input) {
133
- try {
134
- this.decorder.decode(input);
135
- return true;
136
- }
137
- catch (e) {
138
- if (e instanceof InvalidCharacterError) {
139
- return false;
140
- }
141
- throw e;
142
- }
52
+ return this.codec.validate(input);
143
53
  }
144
54
  }
145
55
  exports.Validator = Validator;
146
- const validate = (input, base) => {
147
- return new Validator(base).validate(input);
148
- };
149
- exports.validate = validate;
150
56
  //# sourceMappingURL=bufferbase.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bufferbase.js","sourceRoot":"","sources":["../../src/bufferbase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bufferbase.js","sourceRoot":"","sources":["../../src/bufferbase.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAIH,qDAA8C;AAE9C,wDAAwD;AACxD,uCAAmC;AAA1B,iGAAA,KAAK,OAAA;AAEd,sDAAsD;AACtD,yCAAqE;AAA5D,4GAAA,eAAe,OAAA;AAAE,kHAAA,qBAAqB,OAAA;AAE/C,+CAA+C;AAC/C,MAAa,aAAa;IAGxB,YAAY,SAAiB;QAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,2BAAU,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,CAAC,MAAkB;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,CAAC,OAAe,EAAE,UAAmB;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IACjG,CAAC;CACF;AAdD,sCAcC;AAED,0DAA0D;AAC1D,MAAa,SAAS;IAIpB,YAAY,SAAiB,EAAE,UAAkB;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,CAAC,KAAa;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACzD,CAAC;CACF;AAZD,8BAYC;AAED,0DAA0D;AAC1D,MAAa,SAAS;IAGpB,YAAY,SAAiB;QAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,2BAAU,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,QAAQ,CAAC,KAAa;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;CACF;AAVD,8BAUC"}
@@ -0,0 +1,56 @@
1
+ import { Buffer } from 'node:buffer';
2
+ import type { Algorithm, BufferLike, CodecSpec, DecodeOptions, ICodec } from './types.js';
3
+ /** Converts a `BufferLike` to a `Buffer` without copying when possible. */
4
+ export declare function toBuffer(input: BufferLike): Buffer;
5
+ /**
6
+ * Shared alphabet handling for the three codec implementations.
7
+ *
8
+ * Subclasses provide the mapping between bytes and characters; this class owns
9
+ * the alphabet, the character lookup, optional case folding, and `convertTo`.
10
+ */
11
+ export declare abstract class BaseCodec implements ICodec {
12
+ /** Character set used for encoding. */
13
+ readonly chars: string;
14
+ /** The algorithm this codec applies to `chars`. */
15
+ abstract readonly algorithm: Algorithm;
16
+ /** Whether non-canonical input is rejected. */
17
+ protected readonly strict: boolean;
18
+ private readonly charToIndex;
19
+ /** Characters dropped from the input before decoding. */
20
+ private readonly ignored;
21
+ /**
22
+ * The alphabet as one byte per character, or `null` when some character does
23
+ * not fit in a byte.
24
+ *
25
+ * Assembling output as bytes and decoding it once is several times faster
26
+ * than concatenating characters, and every alphabet in practical use is
27
+ * single-byte.
28
+ */
29
+ protected readonly codes: Uint8Array | null;
30
+ /**
31
+ * The value of every decodable character, indexed by code unit, or `-1`.
32
+ * `null` when some character does not fit in a byte.
33
+ *
34
+ * Reading a character by index and looking it up here avoids allocating a
35
+ * string and hashing it for every character of the input.
36
+ */
37
+ private readonly valueByCode;
38
+ protected constructor(spec: CodecSpec);
39
+ /** Reads the first `length` bytes of `written` back as text. */
40
+ protected textFrom(written: Uint8Array, length: number): string;
41
+ /** Drops the characters this codec ignores, such as readability hyphens. */
42
+ protected strip(input: string): string;
43
+ /** Returns the value of a character, or `undefined` if it is not in the alphabet. */
44
+ protected valueOf(char: string): number | undefined;
45
+ /**
46
+ * Returns the value of the character at `index`, or `-1` if it is not
47
+ * decodable. This is the hot path of every decoder.
48
+ */
49
+ protected valueAt(input: string, index: number): number;
50
+ abstract encode(buffer: BufferLike): string;
51
+ abstract decode(encoded: string, options?: DecodeOptions): Buffer;
52
+ abstract validate(input: string): boolean;
53
+ /** Decodes with this codec, then re-encodes with `target`. */
54
+ convertTo(target: ICodec, input: string): string;
55
+ }
56
+ //# sourceMappingURL=codec-base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec-base.d.ts","sourceRoot":"","sources":["../../src/codec-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA6B1F,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAElD;AAED;;;;;GAKG;AACH,8BAAsB,SAAU,YAAW,MAAM;IAC/C,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAEvC,+CAA+C;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAElD,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAE9C;;;;;;;OAOG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAE5C;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAEhD,SAAS,aAAa,IAAI,EAAE,SAAS;IA0DrC,gEAAgE;IAChE,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAI/D,4EAA4E;IAC5E,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IActC,qFAAqF;IACrF,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAInD;;;OAGG;IACH,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAUvD,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;IAC3C,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM;IACjE,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAEzC,8DAA8D;IAC9D,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;CAGjD"}
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseCodec = void 0;
4
+ exports.toBuffer = toBuffer;
5
+ const node_buffer_1 = require("node:buffer");
6
+ const errors_js_1 = require("./errors.js");
7
+ /** Returns one byte per character, or `null` if the alphabet needs more. */
8
+ function singleByteCodes(alphabet) {
9
+ const codes = new Uint8Array(alphabet.length);
10
+ for (let i = 0; i < alphabet.length; i++) {
11
+ const code = alphabet.charCodeAt(i);
12
+ if (code > 0xff) {
13
+ return null;
14
+ }
15
+ codes[i] = code;
16
+ }
17
+ return codes;
18
+ }
19
+ /** Indexes the decodable characters by code unit, or `null` if any needs more than a byte. */
20
+ function codeTable(charToIndex) {
21
+ const table = new Int16Array(256).fill(-1);
22
+ for (const [char, value] of charToIndex) {
23
+ const code = char.charCodeAt(0);
24
+ if (char.length !== 1 || code > 0xff) {
25
+ return null;
26
+ }
27
+ table[code] = value;
28
+ }
29
+ return table;
30
+ }
31
+ /** Converts a `BufferLike` to a `Buffer` without copying when possible. */
32
+ function toBuffer(input) {
33
+ return node_buffer_1.Buffer.isBuffer(input) ? input : node_buffer_1.Buffer.from(input.buffer, input.byteOffset, input.length);
34
+ }
35
+ /**
36
+ * Shared alphabet handling for the three codec implementations.
37
+ *
38
+ * Subclasses provide the mapping between bytes and characters; this class owns
39
+ * the alphabet, the character lookup, optional case folding, and `convertTo`.
40
+ */
41
+ class BaseCodec {
42
+ constructor(spec) {
43
+ const { alphabet, strict = true, caseInsensitive = false, aliases, ignore } = spec;
44
+ if (alphabet.length < 2) {
45
+ throw new errors_js_1.InvalidCodecError(`alphabet needs at least 2 characters, got ${alphabet.length}`);
46
+ }
47
+ if (new Set(alphabet).size !== alphabet.length) {
48
+ throw new errors_js_1.InvalidCodecError('alphabet contains duplicate characters');
49
+ }
50
+ if ([...alphabet].some((char) => char.length !== 1)) {
51
+ throw new errors_js_1.InvalidCodecError('every alphabet character must be a single code unit');
52
+ }
53
+ if (caseInsensitive && new Set(alphabet.toLowerCase()).size !== alphabet.length) {
54
+ throw new errors_js_1.InvalidCodecError('caseInsensitive needs an alphabet that does not contain both cases of a letter');
55
+ }
56
+ this.chars = alphabet;
57
+ this.strict = strict;
58
+ this.charToIndex = new Map();
59
+ const accept = (char, value) => {
60
+ this.charToIndex.set(char, value);
61
+ if (caseInsensitive) {
62
+ this.charToIndex.set(char.toLowerCase(), value);
63
+ this.charToIndex.set(char.toUpperCase(), value);
64
+ }
65
+ };
66
+ for (let i = 0; i < alphabet.length; i++) {
67
+ accept(alphabet[i], i);
68
+ }
69
+ for (const [from, to] of Object.entries(aliases ?? {})) {
70
+ if (from.length !== 1) {
71
+ throw new errors_js_1.InvalidCodecError(`alias '${from}' must be a single character`);
72
+ }
73
+ const value = this.charToIndex.get(to);
74
+ if (value === undefined) {
75
+ throw new errors_js_1.InvalidCodecError(`alias '${from}' points at '${to}', which is not in the alphabet`);
76
+ }
77
+ if (alphabet.includes(from)) {
78
+ throw new errors_js_1.InvalidCodecError(`alias '${from}' is already in the alphabet`);
79
+ }
80
+ accept(from, value);
81
+ }
82
+ this.codes = singleByteCodes(alphabet);
83
+ this.valueByCode = codeTable(this.charToIndex);
84
+ this.ignored = new Set(ignore ?? '');
85
+ for (const char of this.ignored) {
86
+ if (this.charToIndex.has(char)) {
87
+ throw new errors_js_1.InvalidCodecError(`ignored character '${char}' is also decodable`);
88
+ }
89
+ }
90
+ }
91
+ /** Reads the first `length` bytes of `written` back as text. */
92
+ textFrom(written, length) {
93
+ return node_buffer_1.Buffer.from(written.buffer, written.byteOffset, length).toString('latin1');
94
+ }
95
+ /** Drops the characters this codec ignores, such as readability hyphens. */
96
+ strip(input) {
97
+ if (this.ignored.size === 0) {
98
+ return input;
99
+ }
100
+ let out = '';
101
+ for (let i = 0; i < input.length; i++) {
102
+ const char = input[i];
103
+ if (!this.ignored.has(char)) {
104
+ out += char;
105
+ }
106
+ }
107
+ return out;
108
+ }
109
+ /** Returns the value of a character, or `undefined` if it is not in the alphabet. */
110
+ valueOf(char) {
111
+ return this.charToIndex.get(char);
112
+ }
113
+ /**
114
+ * Returns the value of the character at `index`, or `-1` if it is not
115
+ * decodable. This is the hot path of every decoder.
116
+ */
117
+ valueAt(input, index) {
118
+ const table = this.valueByCode;
119
+ if (table === null) {
120
+ const value = this.charToIndex.get(input[index]);
121
+ return value === undefined ? -1 : value;
122
+ }
123
+ const code = input.charCodeAt(index);
124
+ return code > 0xff ? -1 : table[code];
125
+ }
126
+ /** Decodes with this codec, then re-encodes with `target`. */
127
+ convertTo(target, input) {
128
+ return target.encode(this.decode(input));
129
+ }
130
+ }
131
+ exports.BaseCodec = BaseCodec;
132
+ //# sourceMappingURL=codec-base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec-base.js","sourceRoot":"","sources":["../../src/codec-base.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { Buffer } from 'node:buffer';
2
+ import type { BlockSpec, BufferLike, DecodeOptions } from './types.js';
3
+ import { BaseCodec } from './codec-base.js';
4
+ /**
5
+ * Regroups the bit stream into fixed-width chunks, as specified by RFC 4648.
6
+ *
7
+ * Each character carries `log2(alphabet.length)` bits, so the alphabet must
8
+ * hold 2, 4, 8, 16, 32, or 64 characters. Unlike a radix conversion the output
9
+ * length is a fixed function of the input length, which is what makes Base64
10
+ * and Base32 splittable and streamable.
11
+ *
12
+ * A trailing partial block leaves spare bits in the final character. RFC 4648
13
+ * §3.5 requires those bits to be zero for the encoding to be canonical; input
14
+ * that sets them is rejected unless the spec passes `strict: false`.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { Codecs } from 'bufferbase';
19
+ *
20
+ * Codecs.base64.encode(Buffer.from('fo')); // 'Zm8='
21
+ * Codecs.base64.validate('Zm9='); // false — spare bits are not zero
22
+ * ```
23
+ */
24
+ export declare class BlockCodec extends BaseCodec {
25
+ readonly algorithm: "block";
26
+ /** Bits carried by one character. */
27
+ private readonly bitsPerChar;
28
+ /** Characters in a whole block. */
29
+ private readonly charsPerBlock;
30
+ private readonly padChar;
31
+ private readonly native;
32
+ constructor(spec: BlockSpec);
33
+ encode(input: BufferLike): string;
34
+ /** The character-by-character path, for an alphabet that is not single-byte. */
35
+ private encodeAsText;
36
+ decode(encoded: string, options?: DecodeOptions): Buffer;
37
+ validate(input: string): boolean;
38
+ /**
39
+ * Strips and checks the padding, then verifies that what remains can be the
40
+ * encoding of some byte sequence. Returns the data characters.
41
+ *
42
+ * Everything `decode` can reject other than `DecodeOptions.size` is checked
43
+ * here, so `validate` and `decode` always agree.
44
+ */
45
+ private checkStructure;
46
+ }
47
+ //# sourceMappingURL=codec-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec-block.d.ts","sourceRoot":"","sources":["../../src/codec-block.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,SAAS,EAAY,MAAM,iBAAiB,CAAC;AAwCtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,UAAW,SAAQ,SAAS;IACvC,QAAQ,CAAC,SAAS,EAAG,OAAO,CAAU;IAEtC,qCAAqC;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,mCAAmC;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,IAAI,EAAE,SAAS;IA0B3B,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM;IA4CjC,gFAAgF;IAChF,OAAO,CAAC,YAAY;IA0BpB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM;IA4BxD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAShC;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;CA4CvB"}
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BlockCodec = void 0;
4
+ const node_buffer_1 = require("node:buffer");
5
+ const codec_base_js_1 = require("./codec-base.js");
6
+ const errors_js_1 = require("./errors.js");
7
+ const RFC_BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
8
+ const RFC_BASE64URL = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
9
+ const HEX_LOWER = '0123456789abcdef';
10
+ const HEX_UPPER = '0123456789ABCDEF';
11
+ /**
12
+ * Finds the Node encoding equivalent to a spec, if there is one.
13
+ *
14
+ * Node's encoders are 100-250x faster than the loop below and always emit
15
+ * canonical output, so an exact match is handed off. Decoding is never handed
16
+ * off: Node's decoders are lenient, and rejecting non-canonical input is the
17
+ * point of this codec.
18
+ */
19
+ function nativeEncoderFor(alphabet, pad) {
20
+ if (alphabet === RFC_BASE64 && pad === '=') {
21
+ return { encoding: 'base64', upper: false };
22
+ }
23
+ if (alphabet === RFC_BASE64URL && pad === false) {
24
+ return { encoding: 'base64url', upper: false };
25
+ }
26
+ if (pad === false && (alphabet === HEX_LOWER || alphabet === HEX_UPPER)) {
27
+ return { encoding: 'hex', upper: alphabet === HEX_UPPER };
28
+ }
29
+ return null;
30
+ }
31
+ const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
32
+ /**
33
+ * Regroups the bit stream into fixed-width chunks, as specified by RFC 4648.
34
+ *
35
+ * Each character carries `log2(alphabet.length)` bits, so the alphabet must
36
+ * hold 2, 4, 8, 16, 32, or 64 characters. Unlike a radix conversion the output
37
+ * length is a fixed function of the input length, which is what makes Base64
38
+ * and Base32 splittable and streamable.
39
+ *
40
+ * A trailing partial block leaves spare bits in the final character. RFC 4648
41
+ * §3.5 requires those bits to be zero for the encoding to be canonical; input
42
+ * that sets them is rejected unless the spec passes `strict: false`.
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * import { Codecs } from 'bufferbase';
47
+ *
48
+ * Codecs.base64.encode(Buffer.from('fo')); // 'Zm8='
49
+ * Codecs.base64.validate('Zm9='); // false — spare bits are not zero
50
+ * ```
51
+ */
52
+ class BlockCodec extends codec_base_js_1.BaseCodec {
53
+ constructor(spec) {
54
+ super(spec);
55
+ this.algorithm = 'block';
56
+ const bits = Math.log2(spec.alphabet.length);
57
+ if (!Number.isInteger(bits)) {
58
+ throw new errors_js_1.InvalidCodecError(`'block' needs an alphabet of 2, 4, 8, 16, 32, or 64 characters, got ${spec.alphabet.length}`);
59
+ }
60
+ const pad = spec.pad ?? '=';
61
+ if (pad !== false) {
62
+ if (pad.length !== 1) {
63
+ throw new errors_js_1.InvalidCodecError(`pad must be a single character, got '${pad}'`);
64
+ }
65
+ if (this.valueOf(pad) !== undefined) {
66
+ throw new errors_js_1.InvalidCodecError(`pad character '${pad}' is part of the alphabet`);
67
+ }
68
+ }
69
+ this.bitsPerChar = bits;
70
+ this.charsPerBlock = 8 / gcd(8, bits);
71
+ this.padChar = pad;
72
+ this.native = nativeEncoderFor(spec.alphabet, pad);
73
+ }
74
+ encode(input) {
75
+ const buffer = (0, codec_base_js_1.toBuffer)(input);
76
+ if (this.native !== null) {
77
+ const encoded = buffer.toString(this.native.encoding);
78
+ return this.native.upper ? encoded.toUpperCase() : encoded;
79
+ }
80
+ const bits = this.bitsPerChar;
81
+ const mask = this.chars.length - 1;
82
+ const codes = this.codes;
83
+ if (codes === null) {
84
+ return this.encodeAsText(buffer);
85
+ }
86
+ const dataChars = Math.ceil((buffer.length * 8) / bits);
87
+ const total = this.padChar === false
88
+ ? dataChars
89
+ : Math.ceil(dataChars / this.charsPerBlock) * this.charsPerBlock;
90
+ const written = new Uint8Array(total);
91
+ let at = 0;
92
+ let acc = 0;
93
+ let held = 0;
94
+ for (let i = 0; i < buffer.length; i++) {
95
+ acc = ((acc << 8) | buffer[i]) & 0xffff;
96
+ held += 8;
97
+ while (held >= bits) {
98
+ held -= bits;
99
+ written[at++] = codes[(acc >>> held) & mask];
100
+ }
101
+ }
102
+ if (held > 0) {
103
+ written[at++] = codes[(acc << (bits - held)) & mask];
104
+ }
105
+ if (this.padChar !== false) {
106
+ const padCode = this.padChar.charCodeAt(0);
107
+ while (at < total) {
108
+ written[at++] = padCode;
109
+ }
110
+ }
111
+ return this.textFrom(written, at);
112
+ }
113
+ /** The character-by-character path, for an alphabet that is not single-byte. */
114
+ encodeAsText(buffer) {
115
+ const bits = this.bitsPerChar;
116
+ const mask = this.chars.length - 1;
117
+ let out = '';
118
+ let acc = 0;
119
+ let held = 0;
120
+ for (const byte of buffer) {
121
+ acc = ((acc << 8) | byte) & 0xffff;
122
+ held += 8;
123
+ while (held >= bits) {
124
+ held -= bits;
125
+ out += this.chars[(acc >>> held) & mask];
126
+ }
127
+ }
128
+ if (held > 0) {
129
+ out += this.chars[(acc << (bits - held)) & mask];
130
+ }
131
+ if (this.padChar !== false) {
132
+ while (out.length % this.charsPerBlock !== 0) {
133
+ out += this.padChar;
134
+ }
135
+ }
136
+ return out;
137
+ }
138
+ decode(encoded, options) {
139
+ const data = this.checkStructure(this.strip(encoded));
140
+ const bits = this.bitsPerChar;
141
+ const bytes = node_buffer_1.Buffer.alloc(Math.floor((data.length * bits) / 8));
142
+ let at = 0;
143
+ let acc = 0;
144
+ let held = 0;
145
+ for (let i = 0; i < data.length; i++) {
146
+ const value = this.valueAt(data, i);
147
+ if (value < 0) {
148
+ throw new errors_js_1.InvalidCharacterError(data[i]);
149
+ }
150
+ acc = ((acc << bits) | value) & 0xffff;
151
+ held += bits;
152
+ if (held >= 8) {
153
+ held -= 8;
154
+ bytes[at++] = (acc >>> held) & 0xff;
155
+ }
156
+ }
157
+ const size = options?.size;
158
+ if (size !== undefined && bytes.length !== size) {
159
+ throw new errors_js_1.BufferSizeError(bytes.length, size);
160
+ }
161
+ return bytes;
162
+ }
163
+ validate(input) {
164
+ try {
165
+ this.checkStructure(this.strip(input));
166
+ return true;
167
+ }
168
+ catch {
169
+ return false;
170
+ }
171
+ }
172
+ /**
173
+ * Strips and checks the padding, then verifies that what remains can be the
174
+ * encoding of some byte sequence. Returns the data characters.
175
+ *
176
+ * Everything `decode` can reject other than `DecodeOptions.size` is checked
177
+ * here, so `validate` and `decode` always agree.
178
+ */
179
+ checkStructure(input) {
180
+ let data = input;
181
+ if (this.padChar !== false) {
182
+ let dataLength = input.length;
183
+ while (dataLength > 0 && input[dataLength - 1] === this.padChar) {
184
+ dataLength--;
185
+ }
186
+ data = input.slice(0, dataLength);
187
+ if (input.length % this.charsPerBlock !== 0) {
188
+ throw new errors_js_1.InvalidLengthError(input.length, `padded input must be a multiple of ${this.charsPerBlock} characters`);
189
+ }
190
+ if (input.length - dataLength >= this.charsPerBlock) {
191
+ throw new errors_js_1.InvalidLengthError(input.length, 'too many padding characters');
192
+ }
193
+ }
194
+ const bits = this.bitsPerChar;
195
+ const spare = (data.length * bits) % 8;
196
+ if (spare >= bits) {
197
+ throw new errors_js_1.InvalidLengthError(data.length, `${data.length} characters carry ${data.length * bits} bits, which is not a whole number of bytes`);
198
+ }
199
+ let last = -1;
200
+ for (let i = 0; i < data.length; i++) {
201
+ last = this.valueAt(data, i);
202
+ if (last < 0) {
203
+ throw new errors_js_1.InvalidCharacterError(data[i]);
204
+ }
205
+ }
206
+ if (this.strict && spare > 0 && last >= 0 && (last & ((1 << spare) - 1)) !== 0) {
207
+ throw new errors_js_1.NonCanonicalError(`the final character carries ${spare} spare bits that must be zero`);
208
+ }
209
+ return data;
210
+ }
211
+ }
212
+ exports.BlockCodec = BlockCodec;
213
+ //# sourceMappingURL=codec-block.js.map