@ddunigma/node 2.1.1 → 2.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.
- package/README.md +101 -11
- package/dist/DduStream-KO75MEEM.js +2 -0
- package/dist/chunk-CZMUPXSK.js +5 -0
- package/dist/index.cjs +8 -0
- package/dist/index.d.cts +813 -0
- package/dist/index.d.ts +813 -0
- package/dist/index.js +5 -0
- package/package.json +33 -15
- package/dist/cjs/base/BaseDdu.d.ts +0 -53
- package/dist/cjs/base/BaseDdu.js +0 -29
- package/dist/cjs/base/index.d.ts +0 -1
- package/dist/cjs/base/index.js +0 -5
- package/dist/cjs/charSets/index.d.ts +0 -18
- package/dist/cjs/charSets/index.js +0 -4385
- package/dist/cjs/encoders/Ddu64.d.ts +0 -302
- package/dist/cjs/encoders/Ddu64.js +0 -1308
- package/dist/cjs/encoders/index.d.ts +0 -1
- package/dist/cjs/encoders/index.js +0 -5
- package/dist/cjs/index.d.ts +0 -5
- package/dist/cjs/index.js +0 -16
- package/dist/cjs/package.json +0 -3
- package/dist/cjs/types/DduDefaultTypes.d.ts +0 -3
- package/dist/cjs/types/DduDefaultTypes.js +0 -17
- package/dist/cjs/types/DduEnums.d.ts +0 -6
- package/dist/cjs/types/DduEnums.js +0 -10
- package/dist/cjs/types/DduInterface.d.ts +0 -91
- package/dist/cjs/types/DduInterface.js +0 -2
- package/dist/cjs/types/index.d.ts +0 -3
- package/dist/cjs/types/index.js +0 -19
- package/dist/cjs/utils/CharsetBuilder.d.ts +0 -129
- package/dist/cjs/utils/CharsetBuilder.js +0 -246
- package/dist/cjs/utils/DduPipeline.d.ts +0 -114
- package/dist/cjs/utils/DduPipeline.js +0 -229
- package/dist/cjs/utils/DduStream.d.ts +0 -64
- package/dist/cjs/utils/DduStream.js +0 -221
- package/dist/cjs/utils/crypto.d.ts +0 -30
- package/dist/cjs/utils/crypto.js +0 -84
- package/dist/cjs/utils/index.d.ts +0 -3
- package/dist/cjs/utils/index.js +0 -12
- package/dist/mjs/base/BaseDdu.d.ts +0 -53
- package/dist/mjs/base/BaseDdu.js +0 -23
- package/dist/mjs/base/index.d.ts +0 -1
- package/dist/mjs/base/index.js +0 -1
- package/dist/mjs/charSets/index.d.ts +0 -18
- package/dist/mjs/charSets/index.js +0 -4380
- package/dist/mjs/encoders/Ddu64.d.ts +0 -302
- package/dist/mjs/encoders/Ddu64.js +0 -1343
- package/dist/mjs/encoders/index.d.ts +0 -1
- package/dist/mjs/encoders/index.js +0 -1
- package/dist/mjs/index.d.ts +0 -5
- package/dist/mjs/index.js +0 -4
- package/dist/mjs/package.json +0 -3
- package/dist/mjs/types/DduDefaultTypes.d.ts +0 -3
- package/dist/mjs/types/DduDefaultTypes.js +0 -14
- package/dist/mjs/types/DduEnums.d.ts +0 -6
- package/dist/mjs/types/DduEnums.js +0 -7
- package/dist/mjs/types/DduInterface.d.ts +0 -91
- package/dist/mjs/types/DduInterface.js +0 -1
- package/dist/mjs/types/index.d.ts +0 -3
- package/dist/mjs/types/index.js +0 -3
- package/dist/mjs/utils/CharsetBuilder.d.ts +0 -129
- package/dist/mjs/utils/CharsetBuilder.js +0 -241
- package/dist/mjs/utils/DduPipeline.d.ts +0 -114
- package/dist/mjs/utils/DduPipeline.js +0 -223
- package/dist/mjs/utils/DduStream.d.ts +0 -64
- package/dist/mjs/utils/DduStream.js +0 -225
- package/dist/mjs/utils/crypto.d.ts +0 -30
- package/dist/mjs/utils/crypto.js +0 -78
- package/dist/mjs/utils/index.d.ts +0 -3
- package/dist/mjs/utils/index.js +0 -3
package/README.md
CHANGED
|
@@ -8,6 +8,12 @@ Node.js implementation of [ddunigma](https://github.com/i3l3/ddunigma) (Python o
|
|
|
8
8
|
|
|
9
9
|
커스텀 charset을 사용하는 Base64 스타일 인코더/디코더 라이브러리입니다.
|
|
10
10
|
|
|
11
|
+
## Documents
|
|
12
|
+
|
|
13
|
+
- `README.md`: 설치, 사용법, 공개 API 요약
|
|
14
|
+
- `CHANGELOG.md`: 공개 변경 이력
|
|
15
|
+
- `RELEASE.md`: 배포 체크리스트와 릴리즈 기준
|
|
16
|
+
|
|
11
17
|
### Credits
|
|
12
18
|
|
|
13
19
|
- Original Python Implementation by:
|
|
@@ -17,7 +23,8 @@ Node.js implementation of [ddunigma](https://github.com/i3l3/ddunigma) (Python o
|
|
|
17
23
|
|
|
18
24
|
## Requirements
|
|
19
25
|
|
|
20
|
-
- **Node.js >=
|
|
26
|
+
- **Node.js >= 18.0.0**
|
|
27
|
+
- 라이브러리는 `ES2022` 타깃으로 빌드되며, 현재 스트림 암호화/압축 조합은 Node 18+ 기준으로 검증됩니다.
|
|
21
28
|
|
|
22
29
|
## Install
|
|
23
30
|
|
|
@@ -92,10 +99,11 @@ const decoded = encoder.decode(encoded); // 자동으로 압축 해제
|
|
|
92
99
|
### URL-Safe 인코딩
|
|
93
100
|
|
|
94
101
|
```typescript
|
|
95
|
-
import { Ddu64 } from "@ddunigma/node";
|
|
102
|
+
import { CharsetBuilder, Ddu64 } from "@ddunigma/node";
|
|
96
103
|
|
|
97
|
-
const
|
|
98
|
-
|
|
104
|
+
const { charset, padding } = CharsetBuilder.base64().buildWithPadding("=");
|
|
105
|
+
|
|
106
|
+
const encoder = new Ddu64(charset, padding, {
|
|
99
107
|
urlSafe: true, // +, /, = 를 URL 안전 문자로 변환
|
|
100
108
|
});
|
|
101
109
|
|
|
@@ -103,6 +111,8 @@ const encoded = encoder.encode("Hello World!");
|
|
|
103
111
|
// URL에서 안전하게 사용 가능한 문자열 반환
|
|
104
112
|
```
|
|
105
113
|
|
|
114
|
+
`urlSafe` 는 charset/padding이 `-`, `_`, `.` 를 포함하지 않을 때만 활성화됩니다. 또한 chunk 정규화를 위해 custom charset/padding에는 `\r`, `\n` 을 사용할 수 없습니다.
|
|
115
|
+
|
|
106
116
|
### 체크섬 (무결성 검증)
|
|
107
117
|
|
|
108
118
|
```typescript
|
|
@@ -153,12 +163,14 @@ import { Ddu64 } from "@ddunigma/node";
|
|
|
153
163
|
|
|
154
164
|
const encoder = new Ddu64();
|
|
155
165
|
|
|
156
|
-
// 비동기 인코딩
|
|
166
|
+
// 비동기 인코딩
|
|
157
167
|
const encoded = await encoder.encodeAsync(largeData);
|
|
158
168
|
const decoded = await encoder.decodeAsync(encoded);
|
|
159
169
|
const buffer = await encoder.decodeToBufferAsync(encoded);
|
|
160
170
|
```
|
|
161
171
|
|
|
172
|
+
큰 입력에서 기본 경로는 이벤트 루프에 양보하면서 처리합니다. 다만 압축, 암호화, 체크섬, URL-safe 같은 옵션이 함께 켜진 복합 경로는 안전성을 위해 전체 payload 기준 fallback을 사용할 수 있습니다.
|
|
173
|
+
|
|
162
174
|
### 진행률 콜백
|
|
163
175
|
|
|
164
176
|
```typescript
|
|
@@ -253,7 +265,7 @@ const encoder = new Ddu64();
|
|
|
253
265
|
|
|
254
266
|
// 압축 → 암호화 → 인코딩 파이프라인
|
|
255
267
|
const pipeline = new DduPipeline()
|
|
256
|
-
.compress()
|
|
268
|
+
.compress(6, "brotli")
|
|
257
269
|
.encrypt("my-secret-key")
|
|
258
270
|
.encode(encoder);
|
|
259
271
|
|
|
@@ -286,6 +298,48 @@ fs.createReadStream("output.txt")
|
|
|
286
298
|
.pipe(fs.createWriteStream("restored.bin"));
|
|
287
299
|
```
|
|
288
300
|
|
|
301
|
+
압축과 암호화를 함께 사용하는 스트림도 바로 연결할 수 있습니다.
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
import { Ddu64, DduSetSymbol, createEncodeStream, createDecodeStream } from "@ddunigma/node";
|
|
305
|
+
import fs from "fs";
|
|
306
|
+
|
|
307
|
+
const encoder = new Ddu64(undefined, undefined, {
|
|
308
|
+
dduSetSymbol: DduSetSymbol.ONECHARSET,
|
|
309
|
+
compress: true,
|
|
310
|
+
compressionAlgorithm: "brotli",
|
|
311
|
+
encryptionKey: "stream-secret-key",
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
fs.createReadStream("input.log")
|
|
315
|
+
.pipe(createEncodeStream(encoder))
|
|
316
|
+
.pipe(fs.createWriteStream("input.log.ddu"));
|
|
317
|
+
|
|
318
|
+
fs.createReadStream("input.log.ddu")
|
|
319
|
+
.pipe(createDecodeStream(encoder))
|
|
320
|
+
.pipe(fs.createWriteStream("input-restored.log"));
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
기본 `createEncodeStream()` 은 작은 스트림 헤더를 함께 기록하고, 기본 `createDecodeStream()` 은 이 헤더를 읽어 압축/암호화 설정을 초기에 auto-detect 합니다. 그래서 기본 경로도 조기 스트리밍 복원이 가능합니다. 암호화된 payload는 동일한 `encryptionKey`가 필요합니다.
|
|
324
|
+
|
|
325
|
+
기존 footer-only 스트림 payload도 계속 디코드됩니다. 다만 과거 포맷은 디코드 쪽에서 전체 payload를 버퍼링할 수 있습니다.
|
|
326
|
+
|
|
327
|
+
헤더 없이 명시적 설정만으로 encode/decode 하려면 양쪽 모두에서 `streamAutoDetect: false` 와 함께 동일한 `compress`, `compressionAlgorithm`, `encryptionKey` 설정을 맞춰 주세요.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Benchmark
|
|
332
|
+
|
|
333
|
+
대표 시나리오 기준으로 인코딩/디코딩 시간과 샘플링 기반 peak heap 변화를 확인할 수 있습니다.
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
pnpm bench
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
벤치마크는 `--expose-gc`로 실행되며, 일반 인코딩, 청크 인코딩, 압축, 암호화 비동기 경로, 공개 스트림 API 조합을 함께 측정합니다.
|
|
340
|
+
|
|
341
|
+
샘플링 기반 측정이므로 profiler 수준의 정확한 peak memory는 아니며, 긴 동기 CPU 구간에서는 실제 피크보다 낮게 보일 수 있습니다.
|
|
342
|
+
|
|
289
343
|
---
|
|
290
344
|
|
|
291
345
|
## API Reference
|
|
@@ -310,7 +364,10 @@ fs.createReadStream("output.txt")
|
|
|
310
364
|
| `encoding` | `BufferEncoding` | `'utf-8'` | 문자열 인코딩 |
|
|
311
365
|
| `usePowerOfTwo` | `boolean` | `true` | 2의 제곱수 강제 여부 |
|
|
312
366
|
| `useBuildErrorReturn` | `boolean` | `false` | 에러 발생 시 throw 여부 |
|
|
367
|
+
| `throwOnError` | `boolean` | `false` | 초기화 오류 시 throw 여부 |
|
|
313
368
|
| `compress` | `boolean` | `false` | 기본 압축 활성화 |
|
|
369
|
+
| `compressionAlgorithm` | `"deflate" \| "brotli"` | `'deflate'` | 기본 압축 알고리즘 |
|
|
370
|
+
| `compressionLevel` | `number` | `6` | 압축 레벨 |
|
|
314
371
|
| `maxDecodedBytes` | `number` | `67108864` | 최대 디코딩 바이트 (64MB) |
|
|
315
372
|
| `maxDecompressedBytes` | `number` | `67108864` | 최대 압축해제 바이트 (64MB) |
|
|
316
373
|
| `urlSafe` | `boolean` | `false` | URL-Safe 모드 |
|
|
@@ -319,20 +376,29 @@ fs.createReadStream("output.txt")
|
|
|
319
376
|
| `chunkSize` | `number` | `undefined` | 청크 분할 크기 |
|
|
320
377
|
| `chunkSeparator` | `string` | `'\n'` | 청크 구분자 |
|
|
321
378
|
|
|
379
|
+
`urlSafe` 는 charset/padding이 `-`, `_`, `.` 를 포함하지 않을 때만 켜집니다. 기본 chunk 정규화와 충돌하므로 custom `charset` 과 `paddingChar` 에는 `\r`, `\n` 을 사용할 수 없습니다.
|
|
380
|
+
|
|
322
381
|
### `encode(data, options?): string`
|
|
323
382
|
|
|
324
383
|
데이터를 인코딩합니다.
|
|
325
384
|
|
|
326
385
|
**DduOptions:**
|
|
327
386
|
|
|
328
|
-
| Option
|
|
329
|
-
|
|
|
330
|
-
| `compress`
|
|
331
|
-
| `
|
|
332
|
-
| `
|
|
387
|
+
| Option | Type | Description |
|
|
388
|
+
| ------ | ---- | ----------- |
|
|
389
|
+
| `compress` | `boolean` | 압축 사용 여부 |
|
|
390
|
+
| `streamAutoDetect` | `boolean` | 기본 스트림 헤더 기반 auto-detect 사용 여부 (`false`이면 footer-only 명시 설정 모드) |
|
|
391
|
+
| `compressionAlgorithm` | `"deflate" \| "brotli"` | 압축 알고리즘 |
|
|
392
|
+
| `compressionLevel` | `number` | 압축 레벨 |
|
|
393
|
+
| `checksum` | `boolean` | 체크섬 추가 여부 |
|
|
394
|
+
| `maxDecodedBytes` | `number` | 최대 디코딩 바이트 |
|
|
395
|
+
| `maxDecompressedBytes` | `number` | 최대 압축해제 바이트 |
|
|
396
|
+
| `chunkSize` | `number` | 청크 분할 크기 |
|
|
333
397
|
| `chunkSeparator` | `string` | 청크 구분자 |
|
|
334
398
|
| `onProgress` | `function` | 진행률 콜백 |
|
|
335
399
|
|
|
400
|
+
`encrypt` 와 `omitFooter` 는 스트림 내부 파이프라인 제어용 옵션이며 일반적인 공개 사용 시에는 직접 지정할 필요가 없습니다.
|
|
401
|
+
|
|
336
402
|
### `decode(encoded, options?): string`
|
|
337
403
|
|
|
338
404
|
인코딩된 문자열을 디코딩합니다.
|
|
@@ -386,6 +452,30 @@ fs.createReadStream("output.txt")
|
|
|
386
452
|
|
|
387
453
|
---
|
|
388
454
|
|
|
455
|
+
## Testing
|
|
456
|
+
|
|
457
|
+
This project uses [Vitest](https://vitest.dev/) for testing.
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
# Run all tests
|
|
461
|
+
pnpm test
|
|
462
|
+
|
|
463
|
+
# Run tests in watch mode
|
|
464
|
+
pnpm test:watch
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Verification
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
pnpm lint
|
|
471
|
+
pnpm build
|
|
472
|
+
pnpm test
|
|
473
|
+
pnpm pack:check
|
|
474
|
+
pnpm bench
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
389
479
|
## License
|
|
390
480
|
|
|
391
481
|
BSD-2-Clause
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import {Transform,PassThrough}from'stream';import {createBrotliCompress,constants,createDeflate,createBrotliDecompress,createInflate}from'zlib';var R={"-":"+",_:"/",".":"="},T=(()=>{let n=new Uint32Array(256);for(let e=0;e<256;e++){let r=e;for(let t=0;t<8;t++)r=r>>>1^(r&1?3988292384:0);n[e]=r;}return n})(),_="ELYSIA",P="GRISEO",b="CHK",N="ENC";function W(n){if(n.length===0)return n;let e=new Array(n.length);for(let r=0;r<n.length;r++){let t=n[r];t==="+"?e[r]="-":t==="/"?e[r]="_":t==="="?e[r]=".":e[r]=t;}return e.join("")}function H(n){if(n.length===0)return n;let e=new Array(n.length);for(let r=0;r<n.length;r++){let t=n[r];t==="-"?e[r]="+":t==="_"?e[r]="/":t==="."?e[r]="=":e[r]=t;}return e.join("")}function K(n,e,r){if(e<=0||n.length<=e)return n;let t=Math.ceil(n.length/e),i=new Array(t*2-1),s=0;for(let o=0;o<n.length;o+=e)i[s++]=n.slice(o,o+e),o+e<n.length&&(i[s++]=r);return i.join("")}function h(n,e){if(n.length===0)return n;let r=e&&e!==`
|
|
2
|
+
`&&e!==`\r
|
|
3
|
+
`&&e!=="\r"?e:"",t=r.length,i="";for(let s=0;s<n.length;s++){let o=n[s];if(!(o===`
|
|
4
|
+
`||o==="\r")){if(t>0&&o===r[0]&&n.startsWith(r,s)){s+=t-1;continue}i+=o;}}return i}function j(n){let e=4294967295;for(let r=0;r<n.length;r++)e=e>>>8^T[(e^n[r])&255];return ((e^4294967295)>>>0).toString(16).padStart(8,"0")}function F(n){let e=n.lastIndexOf(b);if(e===-1)return {data:n,checksum:null};let r=n.slice(e+b.length);return r.length!==8||!/^[0-9a-f]+$/i.test(r)?{data:n,checksum:null}:{data:n.slice(0,e),checksum:r.toLowerCase()}}var c="DDS1";function I(n,e){let t=n===void 0||!Number.isFinite(n)?6:Math.floor(n);return Math.min(e==="brotli"?11:9,Math.max(0,t))}function C(n){return n.length*2+c.length+2}function k(n,e){let r=e.compressionAlgorithm==="brotli"?"B":e.compressionAlgorithm==="deflate"?"D":"N",t=e.encrypted?"1":"0";return `${n}${c}${r}${t}${n}`}function D(n,e){let r=C(e);if(n.length<r||!n.startsWith(e))return null;let t=e.length;if(n.slice(t,t+c.length)!==c)throw new Error("[DduStream decode] Invalid stream header magic");let s=n[t+c.length],o=n[t+c.length+1];if(n.slice(r-e.length,r)!==e)throw new Error("[DduStream decode] Invalid stream header terminator");let a=s==="B"?"brotli":s==="D"?"deflate":s==="N"?void 0:null;if(a===null)throw new Error("[DduStream decode] Invalid stream header compression flag");if(o!=="0"&&o!=="1")throw new Error("[DduStream decode] Invalid stream header encryption flag");return {compressionAlgorithm:a,encrypted:o==="1"}}var m=class extends Transform{prefix;emittedPrefix=false;constructor(e){super(),this.prefix=e;}_transform(e,r,t){try{this.emittedPrefix||(this.push(this.prefix),this.emittedPrefix=!0),this.push(e),t();}catch(i){t(i);}}};function L(n,e){let r=new PassThrough,t=r.write.bind(r);return r.write=function(i,s,o){return typeof s=="function"?n.write(i,s):n.write(i,s,o)},r.end=function(i,s,o){return typeof i=="function"?n.end(i):typeof s=="function"?n.end(i,s):n.end(i,s,o)},e.on("data",i=>t(i)),e.on("end",()=>r.push(null)),e.on("error",i=>r.destroy(i)),n.on("error",i=>r.destroy(i)),r}function v(n){if(n.length===0)return new PassThrough;for(let r=0;r<n.length-1;r++)n[r].pipe(n[r+1]);let e=L(n[0],n[n.length-1]);for(let r of n)r.on("error",t=>{e.destroy(t);});return e}var p=class extends Transform{encoder;buffers;bufferOffset;totalLength;chunkSize;footerCompressionAlgorithm;footerEncrypted;constructor(e,r){super({...r,readableObjectMode:false,writableObjectMode:false}),this.encoder=e;let t=e.getCharSetInfo();this.buffers=[],this.bufferOffset=0,this.totalLength=0,this.footerCompressionAlgorithm=r?.compress??t.defaultCompress?r?.compressionAlgorithm??t.defaultCompressionAlgorithm:void 0,this.footerEncrypted=(r?.encrypt??true)&&t.hasEncryptionKey,this.chunkSize=this.calculateChunkSize(t.bitLength);}calculateChunkSize(e){let r=(s,o)=>o===0?s:r(o,s%o),t=8*e/r(8,e),i=Math.max(1,Math.floor(4096/t));return t*i}_transform(e,r,t){try{for(this.buffers.push(e),this.totalLength+=e.length;this.totalLength>=this.chunkSize;){let i=this.readBytes(this.chunkSize),s=this.encodeChunk(i,!1);this.push(s);}t();}catch(i){t(i);}}_flush(e){try{if(this.totalLength>0){let r=this.readBytes(this.totalLength),t=this.encodeChunk(r,!0);this.push(t);}e();}catch(r){e(r);}}encodeChunk(e,r){return this.encoder.encodeRawBuffer(e,{compressionAlgorithm:r?this.footerCompressionAlgorithm:void 0,encrypted:r?this.footerEncrypted:false,omitFooter:!r})}readBytes(e){if(e<=0||this.totalLength<e)return Buffer.alloc(0);let r=this.buffers[0];if(this.buffers.length===1&&r&&this.bufferOffset===0&&r.length===e)return this.buffers=[],this.totalLength=0,r;let t=Buffer.allocUnsafe(e),i=0;for(;i<e&&this.buffers.length>0;){let s=this.buffers[0],o=s.length-this.bufferOffset,f=Math.min(e-i,o);s.copy(t,i,this.bufferOffset,this.bufferOffset+f),i+=f,this.bufferOffset+=f,this.bufferOffset>=s.length&&(this.buffers.shift(),this.bufferOffset=0);}return this.totalLength-=e,t}},g=class extends Transform{encoder;options;normalizedBuffer;charLength;chunkSize;chunkSeparator;separatorTail;constructor(e,r){super({...r,readableObjectMode:false,writableObjectMode:false}),this.encoder=e,this.options={...r,compress:false,checksum:false,encrypt:false},this.normalizedBuffer="";let t=e.getCharSetInfo();this.charLength=t.charLength,this.chunkSeparator=r?.chunkSeparator??t.defaultChunkSeparator,this.separatorTail="",this.chunkSize=this.calculateChunkSize(t.charLength);}calculateChunkSize(e){return e*1024}_transform(e,r,t){try{this.appendNormalizedChunk(e.toString("utf-8"));let i=100;for(;this.normalizedBuffer.length>=this.chunkSize+i;){let s=this.normalizedBuffer.slice(0,this.chunkSize);this.normalizedBuffer=this.normalizedBuffer.slice(this.chunkSize);let o=this.encoder.decodeToBuffer(s,this.options);this.push(o);}t();}catch(i){t(i);}}_flush(e){try{if(this.separatorTail.length>0&&(this.normalizedBuffer+=h(this.separatorTail,this.chunkSeparator),this.separatorTail=""),this.normalizedBuffer.length>0){let r=this.encoder.decodeStreamToBuffer(this.normalizedBuffer,this.options);this.push(r),this.normalizedBuffer="";}e();}catch(r){e(r);}}appendNormalizedChunk(e){if(e.length===0)return;let r=Math.max(0,this.chunkSeparator.length-1);if(r===0){this.normalizedBuffer+=h(e,this.chunkSeparator);return}let t=this.separatorTail+e;if(t.length<=r){this.separatorTail=t;return}let i=t.length-r,s=t.slice(0,i);this.separatorTail=t.slice(i),this.normalizedBuffer+=h(s,this.chunkSeparator);}},y=class extends Transform{encoder;options;normalizedBuffer;chunkSeparator;separatorTail;paddingChar;headerLength;mode;innerStream;constructor(e,r){super({...r,readableObjectMode:false,writableObjectMode:false}),this.encoder=e,this.options={...r},this.normalizedBuffer="";let t=e.getCharSetInfo();this.paddingChar=t.paddingChar,this.headerLength=C(t.paddingChar),this.chunkSeparator=r?.chunkSeparator??t.defaultChunkSeparator,this.separatorTail="",this.mode="pending",this.innerStream=null;}_transform(e,r,t){try{if(this.appendNormalizedChunk(e.toString("utf-8")),this.maybeInitializeMode(!1),this.mode==="pipeline"){this.flushBufferedToInner(t);return}t();}catch(i){t(i);}}_flush(e){try{if(this.separatorTail.length>0&&(this.normalizedBuffer+=h(this.separatorTail,this.chunkSeparator),this.separatorTail=""),this.maybeInitializeMode(!0),this.mode==="pipeline"){this.finishInnerPipeline(e);return}if(this.normalizedBuffer.length>0){let r=this.encoder.decodeStreamToBuffer(this.normalizedBuffer,this.options);this.push(r),this.normalizedBuffer="";}e();}catch(r){e(r);}}appendNormalizedChunk(e){if(e.length===0)return;let r=Math.max(0,this.chunkSeparator.length-1);if(r===0){this.normalizedBuffer+=h(e,this.chunkSeparator);return}let t=this.separatorTail+e;if(t.length<=r){this.separatorTail=t;return}let i=t.length-r,s=t.slice(0,i);this.separatorTail=t.slice(i),this.normalizedBuffer+=h(s,this.chunkSeparator);}maybeInitializeMode(e){if(this.mode!=="pending")return;let r=this.paddingChar.length;if(this.normalizedBuffer.length<r){e&&this.normalizedBuffer.length>0&&(this.mode="legacy");return}if(!this.normalizedBuffer.startsWith(this.paddingChar)){this.mode="legacy";return}if(this.normalizedBuffer.length<this.headerLength){if(e)throw new Error("[DduStream decode] Incomplete stream header");return}let t=this.normalizedBuffer.slice(0,this.headerLength),i=D(t,this.paddingChar);if(!i){this.mode="legacy";return}this.mode="pipeline",this.normalizedBuffer=this.normalizedBuffer.slice(this.headerLength),this.initializeInnerPipeline(i);}initializeInnerPipeline(e){if(e.encrypted&&!this.encoder.getCharSetInfo().hasEncryptionKey)throw new Error("[DduStream decode] Encrypted stream requires an encryptionKey");let r=O(this.encoder,{...this.options,streamAutoDetect:false,compress:!!e.compressionAlgorithm,compressionAlgorithm:e.compressionAlgorithm,encrypt:e.encrypted});r.on("data",t=>{this.push(t);}),r.on("error",t=>{this.destroy(t);}),this.innerStream=r;}flushBufferedToInner(e){if(!this.innerStream||this.normalizedBuffer.length===0){e();return}let r=this.normalizedBuffer;if(this.normalizedBuffer="",!this.innerStream.write(Buffer.from(r,"utf-8"))){this.innerStream.once("drain",()=>e());return}e();}finishInnerPipeline(e){if(!this.innerStream){e();return}let r=this.innerStream,t=()=>{r.once("end",()=>e()),r.end();};if(this.normalizedBuffer.length>0){let i=this.normalizedBuffer;if(this.normalizedBuffer="",!r.write(Buffer.from(i,"utf-8"))){r.once("drain",t);return}}t();}};function Q(n,e){let r=n.getCharSetInfo(),t=e?.compress??r.defaultCompress,i=(e?.encrypt??true)&&r.hasEncryptionKey,s=e?.streamAutoDetect!==false,o=t?e?.compressionAlgorithm??r.defaultCompressionAlgorithm:void 0,f=new p(n,e),a=[];if(t){let l=o??r.defaultCompressionAlgorithm,u=l==="brotli",S=I(e?.compressionLevel??r.defaultCompressionLevel,l),E=u?createBrotliCompress({params:{[constants.BROTLI_PARAM_QUALITY]:Math.min(11,Math.max(0,S))}}):createDeflate({level:Math.min(9,Math.max(0,S))});a.push(E);}if(i){let l=n.createEncryptionStream();l&&a.push(l);}return a.push(f),s&&a.push(new m(k(r.paddingChar,{compressionAlgorithm:o,encrypted:i}))),a.length===1?f:v(a)}function O(n,e){if(e?.streamAutoDetect??true)return new y(n,e);let t=n.getCharSetInfo(),i=e?.compress??t.defaultCompress,s=(e?.encrypt??true)&&t.hasEncryptionKey,o=new g(n,e),f=[o];if(s){let a=n.createDecryptionStream();a&&f.push(a);}if(i){let u=(e?.compressionAlgorithm??t.defaultCompressionAlgorithm)==="brotli"?createBrotliDecompress():createInflate();f.push(u);}return f.length===1?o:v(f)}export{R as a,_ as b,P as c,b as d,N as e,W as f,H as g,K as h,h as i,j,F as k,p as l,g as m,Q as n,O as o};//# sourceMappingURL=chunk-CZMUPXSK.js.map
|
|
5
|
+
//# sourceMappingURL=chunk-CZMUPXSK.js.map
|