@posthog/core 1.28.5 → 1.28.7
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/dist/gzip.d.ts +1 -0
- package/dist/gzip.d.ts.map +1 -1
- package/dist/gzip.js +43 -1
- package/dist/gzip.mjs +41 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.mjs +2 -2
- package/package.json +2 -2
- package/src/gzip.ts +71 -1
- package/src/index.ts +1 -1
package/dist/gzip.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export declare function isGzipSupported(): boolean;
|
|
6
6
|
export declare const isNativeAsyncGzipReadError: (error: unknown) => boolean;
|
|
7
|
+
export declare const isNativeAsyncGzipError: (error: unknown) => boolean;
|
|
7
8
|
export type GzipCompressOptions = {
|
|
8
9
|
/**
|
|
9
10
|
* By default this helper swallows compression errors and returns null.
|
package/dist/gzip.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gzip.d.ts","sourceRoot":"","sources":["../src/gzip.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAOzC;
|
|
1
|
+
{"version":3,"file":"gzip.d.ts","sourceRoot":"","sources":["../src/gzip.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAOzC;AAID,eAAO,MAAM,0BAA0B,GAAI,OAAO,OAAO,KAAG,OAQ3D,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,KAAG,OAQvD,CAAA;AA0DD,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,UAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAgCrH"}
|
package/dist/gzip.js
CHANGED
|
@@ -26,21 +26,60 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
26
26
|
__webpack_require__.d(__webpack_exports__, {
|
|
27
27
|
gzipCompress: ()=>gzipCompress,
|
|
28
28
|
isGzipSupported: ()=>isGzipSupported,
|
|
29
|
+
isNativeAsyncGzipError: ()=>isNativeAsyncGzipError,
|
|
29
30
|
isNativeAsyncGzipReadError: ()=>isNativeAsyncGzipReadError
|
|
30
31
|
});
|
|
31
32
|
function isGzipSupported() {
|
|
32
33
|
return 'CompressionStream' in globalThis && 'TextEncoder' in globalThis && 'Response' in globalThis && 'function' == typeof Response.prototype.blob;
|
|
33
34
|
}
|
|
35
|
+
const NATIVE_GZIP_VALIDATION_ERROR = 'NativeGzipValidationError';
|
|
34
36
|
const isNativeAsyncGzipReadError = (error)=>{
|
|
35
37
|
if (!error || 'object' != typeof error) return false;
|
|
36
38
|
const name = 'name' in error ? String(error.name) : '';
|
|
37
39
|
return 'NotReadableError' === name;
|
|
38
40
|
};
|
|
41
|
+
const isNativeAsyncGzipError = (error)=>{
|
|
42
|
+
if (!error || 'object' != typeof error) return false;
|
|
43
|
+
const name = 'name' in error ? String(error.name) : '';
|
|
44
|
+
return isNativeAsyncGzipReadError(error) || name === NATIVE_GZIP_VALIDATION_ERROR;
|
|
45
|
+
};
|
|
46
|
+
let crc32Table;
|
|
47
|
+
const getCrc32Table = ()=>{
|
|
48
|
+
if (crc32Table) return crc32Table;
|
|
49
|
+
crc32Table = [];
|
|
50
|
+
for(let i = 0; i < 256; i++){
|
|
51
|
+
let crc = i;
|
|
52
|
+
for(let j = 0; j < 8; j++)crc = 1 & crc ? 0xedb88320 ^ crc >>> 1 : crc >>> 1;
|
|
53
|
+
crc32Table[i] = crc >>> 0;
|
|
54
|
+
}
|
|
55
|
+
return crc32Table;
|
|
56
|
+
};
|
|
57
|
+
const crc32 = (bytes)=>{
|
|
58
|
+
const table = getCrc32Table();
|
|
59
|
+
let crc = 0xffffffff;
|
|
60
|
+
for(let i = 0; i < bytes.length; i++)crc = table[(crc ^ bytes[i]) & 0xff] ^ crc >>> 8;
|
|
61
|
+
return (0xffffffff ^ crc) >>> 0;
|
|
62
|
+
};
|
|
63
|
+
const throwNativeGzipValidationError = (reason)=>{
|
|
64
|
+
const error = new Error(`Native gzip produced invalid output: ${reason}`);
|
|
65
|
+
error.name = NATIVE_GZIP_VALIDATION_ERROR;
|
|
66
|
+
throw error;
|
|
67
|
+
};
|
|
68
|
+
const validateNativeGzip = async (compressed, inputBytes)=>{
|
|
69
|
+
if (compressed.size < 18) throwNativeGzipValidationError('too-short');
|
|
70
|
+
const header = new Uint8Array(await compressed.slice(0, 10).arrayBuffer());
|
|
71
|
+
if (0x1f !== header[0] || 0x8b !== header[1] || 0x08 !== header[2]) throwNativeGzipValidationError('invalid-header');
|
|
72
|
+
const trailer = new DataView(await compressed.slice(compressed.size - 8).arrayBuffer());
|
|
73
|
+
if (trailer.getUint32(0, true) !== crc32(inputBytes)) throwNativeGzipValidationError('invalid-crc');
|
|
74
|
+
const inputSize = inputBytes.length >>> 0;
|
|
75
|
+
if (trailer.getUint32(4, true) !== inputSize) throwNativeGzipValidationError('invalid-size');
|
|
76
|
+
};
|
|
39
77
|
async function gzipCompress(input, isDebug = true, options) {
|
|
40
78
|
try {
|
|
79
|
+
const inputBytes = new TextEncoder().encode(input);
|
|
41
80
|
const compressedStream = new CompressionStream('gzip');
|
|
42
81
|
const writer = compressedStream.writable.getWriter();
|
|
43
|
-
const writePromise = writer.write(
|
|
82
|
+
const writePromise = writer.write(inputBytes).then(()=>writer.close()).catch(async (err)=>{
|
|
44
83
|
try {
|
|
45
84
|
await writer.abort(err);
|
|
46
85
|
} catch {}
|
|
@@ -51,6 +90,7 @@ async function gzipCompress(input, isDebug = true, options) {
|
|
|
51
90
|
responsePromise,
|
|
52
91
|
writePromise
|
|
53
92
|
]);
|
|
93
|
+
await validateNativeGzip(compressed, inputBytes);
|
|
54
94
|
return compressed;
|
|
55
95
|
} catch (error) {
|
|
56
96
|
if (options?.rethrow) throw error;
|
|
@@ -60,10 +100,12 @@ async function gzipCompress(input, isDebug = true, options) {
|
|
|
60
100
|
}
|
|
61
101
|
exports.gzipCompress = __webpack_exports__.gzipCompress;
|
|
62
102
|
exports.isGzipSupported = __webpack_exports__.isGzipSupported;
|
|
103
|
+
exports.isNativeAsyncGzipError = __webpack_exports__.isNativeAsyncGzipError;
|
|
63
104
|
exports.isNativeAsyncGzipReadError = __webpack_exports__.isNativeAsyncGzipReadError;
|
|
64
105
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
65
106
|
"gzipCompress",
|
|
66
107
|
"isGzipSupported",
|
|
108
|
+
"isNativeAsyncGzipError",
|
|
67
109
|
"isNativeAsyncGzipReadError"
|
|
68
110
|
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
69
111
|
Object.defineProperty(exports, '__esModule', {
|
package/dist/gzip.mjs
CHANGED
|
@@ -1,16 +1,54 @@
|
|
|
1
1
|
function isGzipSupported() {
|
|
2
2
|
return 'CompressionStream' in globalThis && 'TextEncoder' in globalThis && 'Response' in globalThis && 'function' == typeof Response.prototype.blob;
|
|
3
3
|
}
|
|
4
|
+
const NATIVE_GZIP_VALIDATION_ERROR = 'NativeGzipValidationError';
|
|
4
5
|
const isNativeAsyncGzipReadError = (error)=>{
|
|
5
6
|
if (!error || 'object' != typeof error) return false;
|
|
6
7
|
const name = 'name' in error ? String(error.name) : '';
|
|
7
8
|
return 'NotReadableError' === name;
|
|
8
9
|
};
|
|
10
|
+
const isNativeAsyncGzipError = (error)=>{
|
|
11
|
+
if (!error || 'object' != typeof error) return false;
|
|
12
|
+
const name = 'name' in error ? String(error.name) : '';
|
|
13
|
+
return isNativeAsyncGzipReadError(error) || name === NATIVE_GZIP_VALIDATION_ERROR;
|
|
14
|
+
};
|
|
15
|
+
let crc32Table;
|
|
16
|
+
const getCrc32Table = ()=>{
|
|
17
|
+
if (crc32Table) return crc32Table;
|
|
18
|
+
crc32Table = [];
|
|
19
|
+
for(let i = 0; i < 256; i++){
|
|
20
|
+
let crc = i;
|
|
21
|
+
for(let j = 0; j < 8; j++)crc = 1 & crc ? 0xedb88320 ^ crc >>> 1 : crc >>> 1;
|
|
22
|
+
crc32Table[i] = crc >>> 0;
|
|
23
|
+
}
|
|
24
|
+
return crc32Table;
|
|
25
|
+
};
|
|
26
|
+
const crc32 = (bytes)=>{
|
|
27
|
+
const table = getCrc32Table();
|
|
28
|
+
let crc = 0xffffffff;
|
|
29
|
+
for(let i = 0; i < bytes.length; i++)crc = table[(crc ^ bytes[i]) & 0xff] ^ crc >>> 8;
|
|
30
|
+
return (0xffffffff ^ crc) >>> 0;
|
|
31
|
+
};
|
|
32
|
+
const throwNativeGzipValidationError = (reason)=>{
|
|
33
|
+
const error = new Error(`Native gzip produced invalid output: ${reason}`);
|
|
34
|
+
error.name = NATIVE_GZIP_VALIDATION_ERROR;
|
|
35
|
+
throw error;
|
|
36
|
+
};
|
|
37
|
+
const validateNativeGzip = async (compressed, inputBytes)=>{
|
|
38
|
+
if (compressed.size < 18) throwNativeGzipValidationError('too-short');
|
|
39
|
+
const header = new Uint8Array(await compressed.slice(0, 10).arrayBuffer());
|
|
40
|
+
if (0x1f !== header[0] || 0x8b !== header[1] || 0x08 !== header[2]) throwNativeGzipValidationError('invalid-header');
|
|
41
|
+
const trailer = new DataView(await compressed.slice(compressed.size - 8).arrayBuffer());
|
|
42
|
+
if (trailer.getUint32(0, true) !== crc32(inputBytes)) throwNativeGzipValidationError('invalid-crc');
|
|
43
|
+
const inputSize = inputBytes.length >>> 0;
|
|
44
|
+
if (trailer.getUint32(4, true) !== inputSize) throwNativeGzipValidationError('invalid-size');
|
|
45
|
+
};
|
|
9
46
|
async function gzipCompress(input, isDebug = true, options) {
|
|
10
47
|
try {
|
|
48
|
+
const inputBytes = new TextEncoder().encode(input);
|
|
11
49
|
const compressedStream = new CompressionStream('gzip');
|
|
12
50
|
const writer = compressedStream.writable.getWriter();
|
|
13
|
-
const writePromise = writer.write(
|
|
51
|
+
const writePromise = writer.write(inputBytes).then(()=>writer.close()).catch(async (err)=>{
|
|
14
52
|
try {
|
|
15
53
|
await writer.abort(err);
|
|
16
54
|
} catch {}
|
|
@@ -21,6 +59,7 @@ async function gzipCompress(input, isDebug = true, options) {
|
|
|
21
59
|
responsePromise,
|
|
22
60
|
writePromise
|
|
23
61
|
]);
|
|
62
|
+
await validateNativeGzip(compressed, inputBytes);
|
|
24
63
|
return compressed;
|
|
25
64
|
} catch (error) {
|
|
26
65
|
if (options?.rethrow) throw error;
|
|
@@ -28,4 +67,4 @@ async function gzipCompress(input, isDebug = true, options) {
|
|
|
28
67
|
return null;
|
|
29
68
|
}
|
|
30
69
|
}
|
|
31
|
-
export { gzipCompress, isGzipSupported, isNativeAsyncGzipReadError };
|
|
70
|
+
export { gzipCompress, isGzipSupported, isNativeAsyncGzipError, isNativeAsyncGzipReadError };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { getFeatureFlagValue } from './featureFlagUtils';
|
|
2
|
-
export { gzipCompress, isNativeAsyncGzipReadError } from './gzip';
|
|
2
|
+
export { gzipCompress, isNativeAsyncGzipError, isNativeAsyncGzipReadError } from './gzip';
|
|
3
3
|
export * from './utils';
|
|
4
4
|
export * as ErrorTracking from './error-tracking';
|
|
5
5
|
export { buildOtlpLogRecord, buildOtlpLogsPayload, getOtlpSeverityNumber, getOtlpSeverityText, toOtlpAnyValue, toOtlpKeyValueList, } from './logs/logs-utils';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,QAAQ,CAAA;AACzF,cAAc,SAAS,CAAA;AACvB,OAAO,KAAK,aAAa,MAAM,kBAAkB,CAAA;AACjD,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,kBAAkB,GACnB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpC,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,cAAc,CAAA;AAIrB,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACzG,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -92,6 +92,7 @@ var __webpack_exports__ = {};
|
|
|
92
92
|
getRequirementsHint: ()=>_surveys_validation__WEBPACK_IMPORTED_MODULE_11__.getRequirementsHint,
|
|
93
93
|
getValidationError: ()=>_surveys_validation__WEBPACK_IMPORTED_MODULE_11__.getValidationError,
|
|
94
94
|
gzipCompress: ()=>_gzip__WEBPACK_IMPORTED_MODULE_1__.gzipCompress,
|
|
95
|
+
isNativeAsyncGzipError: ()=>_gzip__WEBPACK_IMPORTED_MODULE_1__.isNativeAsyncGzipError,
|
|
95
96
|
isNativeAsyncGzipReadError: ()=>_gzip__WEBPACK_IMPORTED_MODULE_1__.isNativeAsyncGzipReadError,
|
|
96
97
|
toOtlpAnyValue: ()=>_logs_logs_utils__WEBPACK_IMPORTED_MODULE_4__.toOtlpAnyValue,
|
|
97
98
|
toOtlpKeyValueList: ()=>_logs_logs_utils__WEBPACK_IMPORTED_MODULE_4__.toOtlpKeyValueList,
|
|
@@ -104,6 +105,7 @@ var __webpack_exports__ = {};
|
|
|
104
105
|
for(var __WEBPACK_IMPORT_KEY__ in _utils__WEBPACK_IMPORTED_MODULE_2__)if ([
|
|
105
106
|
"toOtlpKeyValueList",
|
|
106
107
|
"PostHogLogs",
|
|
108
|
+
"isNativeAsyncGzipError",
|
|
107
109
|
"getOtlpSeverityText",
|
|
108
110
|
"isNativeAsyncGzipReadError",
|
|
109
111
|
"getFeatureFlagValue",
|
|
@@ -131,6 +133,7 @@ var __webpack_exports__ = {};
|
|
|
131
133
|
for(var __WEBPACK_IMPORT_KEY__ in _posthog_core__WEBPACK_IMPORTED_MODULE_7__)if ([
|
|
132
134
|
"toOtlpKeyValueList",
|
|
133
135
|
"PostHogLogs",
|
|
136
|
+
"isNativeAsyncGzipError",
|
|
134
137
|
"getOtlpSeverityText",
|
|
135
138
|
"isNativeAsyncGzipReadError",
|
|
136
139
|
"getFeatureFlagValue",
|
|
@@ -154,6 +157,7 @@ var __webpack_exports__ = {};
|
|
|
154
157
|
for(var __WEBPACK_IMPORT_KEY__ in _posthog_core_stateless__WEBPACK_IMPORTED_MODULE_8__)if ([
|
|
155
158
|
"toOtlpKeyValueList",
|
|
156
159
|
"PostHogLogs",
|
|
160
|
+
"isNativeAsyncGzipError",
|
|
157
161
|
"getOtlpSeverityText",
|
|
158
162
|
"isNativeAsyncGzipReadError",
|
|
159
163
|
"getFeatureFlagValue",
|
|
@@ -177,6 +181,7 @@ var __webpack_exports__ = {};
|
|
|
177
181
|
for(var __WEBPACK_IMPORT_KEY__ in _tracing_headers__WEBPACK_IMPORTED_MODULE_9__)if ([
|
|
178
182
|
"toOtlpKeyValueList",
|
|
179
183
|
"PostHogLogs",
|
|
184
|
+
"isNativeAsyncGzipError",
|
|
180
185
|
"getOtlpSeverityText",
|
|
181
186
|
"isNativeAsyncGzipReadError",
|
|
182
187
|
"getFeatureFlagValue",
|
|
@@ -200,6 +205,7 @@ var __webpack_exports__ = {};
|
|
|
200
205
|
for(var __WEBPACK_IMPORT_KEY__ in _types__WEBPACK_IMPORTED_MODULE_10__)if ([
|
|
201
206
|
"toOtlpKeyValueList",
|
|
202
207
|
"PostHogLogs",
|
|
208
|
+
"isNativeAsyncGzipError",
|
|
203
209
|
"getOtlpSeverityText",
|
|
204
210
|
"isNativeAsyncGzipReadError",
|
|
205
211
|
"getFeatureFlagValue",
|
|
@@ -231,6 +237,7 @@ exports.getOtlpSeverityText = __webpack_exports__.getOtlpSeverityText;
|
|
|
231
237
|
exports.getRequirementsHint = __webpack_exports__.getRequirementsHint;
|
|
232
238
|
exports.getValidationError = __webpack_exports__.getValidationError;
|
|
233
239
|
exports.gzipCompress = __webpack_exports__.gzipCompress;
|
|
240
|
+
exports.isNativeAsyncGzipError = __webpack_exports__.isNativeAsyncGzipError;
|
|
234
241
|
exports.isNativeAsyncGzipReadError = __webpack_exports__.isNativeAsyncGzipReadError;
|
|
235
242
|
exports.toOtlpAnyValue = __webpack_exports__.toOtlpAnyValue;
|
|
236
243
|
exports.toOtlpKeyValueList = __webpack_exports__.toOtlpKeyValueList;
|
|
@@ -247,6 +254,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
|
247
254
|
"getRequirementsHint",
|
|
248
255
|
"getValidationError",
|
|
249
256
|
"gzipCompress",
|
|
257
|
+
"isNativeAsyncGzipError",
|
|
250
258
|
"isNativeAsyncGzipReadError",
|
|
251
259
|
"toOtlpAnyValue",
|
|
252
260
|
"toOtlpKeyValueList",
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getFeatureFlagValue } from "./featureFlagUtils.mjs";
|
|
2
|
-
import { gzipCompress, isNativeAsyncGzipReadError } from "./gzip.mjs";
|
|
2
|
+
import { gzipCompress, isNativeAsyncGzipError, isNativeAsyncGzipReadError } from "./gzip.mjs";
|
|
3
3
|
import { buildOtlpLogRecord, buildOtlpLogsPayload, getOtlpSeverityNumber, getOtlpSeverityText, toOtlpAnyValue, toOtlpKeyValueList } from "./logs/logs-utils.mjs";
|
|
4
4
|
import { PostHogLogs } from "./logs/index.mjs";
|
|
5
5
|
import { uuidv7 } from "./vendor/uuidv7.mjs";
|
|
@@ -10,4 +10,4 @@ export * from "./posthog-core-stateless.mjs";
|
|
|
10
10
|
export * from "./tracing-headers.mjs";
|
|
11
11
|
export * from "./types.mjs";
|
|
12
12
|
import * as __WEBPACK_EXTERNAL_MODULE__error_tracking_index_mjs_b3406d6f__ from "./error-tracking/index.mjs";
|
|
13
|
-
export { __WEBPACK_EXTERNAL_MODULE__error_tracking_index_mjs_b3406d6f__ as ErrorTracking, PostHogLogs, buildOtlpLogRecord, buildOtlpLogsPayload, getFeatureFlagValue, getLengthFromRules, getOtlpSeverityNumber, getOtlpSeverityText, getRequirementsHint, getValidationError, gzipCompress, isNativeAsyncGzipReadError, toOtlpAnyValue, toOtlpKeyValueList, uuidv7 };
|
|
13
|
+
export { __WEBPACK_EXTERNAL_MODULE__error_tracking_index_mjs_b3406d6f__ as ErrorTracking, PostHogLogs, buildOtlpLogRecord, buildOtlpLogsPayload, getFeatureFlagValue, getLengthFromRules, getOtlpSeverityNumber, getOtlpSeverityText, getRequirementsHint, getValidationError, gzipCompress, isNativeAsyncGzipError, isNativeAsyncGzipReadError, toOtlpAnyValue, toOtlpKeyValueList, uuidv7 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@posthog/core",
|
|
3
|
-
"version": "1.28.
|
|
3
|
+
"version": "1.28.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
}
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@posthog/types": "1.373.
|
|
70
|
+
"@posthog/types": "1.373.2"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@rslib/core": "0.10.6",
|
package/src/gzip.ts
CHANGED
|
@@ -11,6 +11,8 @@ export function isGzipSupported(): boolean {
|
|
|
11
11
|
)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
const NATIVE_GZIP_VALIDATION_ERROR = 'NativeGzipValidationError'
|
|
15
|
+
|
|
14
16
|
export const isNativeAsyncGzipReadError = (error: unknown): boolean => {
|
|
15
17
|
if (!error || typeof error !== 'object') {
|
|
16
18
|
return false
|
|
@@ -21,6 +23,72 @@ export const isNativeAsyncGzipReadError = (error: unknown): boolean => {
|
|
|
21
23
|
return name === 'NotReadableError'
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
export const isNativeAsyncGzipError = (error: unknown): boolean => {
|
|
27
|
+
if (!error || typeof error !== 'object') {
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const name = 'name' in error ? String(error.name) : ''
|
|
32
|
+
|
|
33
|
+
return isNativeAsyncGzipReadError(error) || name === NATIVE_GZIP_VALIDATION_ERROR
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type NativeGzipValidationReason = 'too-short' | 'invalid-header' | 'invalid-crc' | 'invalid-size'
|
|
37
|
+
|
|
38
|
+
let crc32Table: number[] | undefined
|
|
39
|
+
|
|
40
|
+
const getCrc32Table = (): number[] => {
|
|
41
|
+
if (crc32Table) {
|
|
42
|
+
return crc32Table
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
crc32Table = []
|
|
46
|
+
for (let i = 0; i < 256; i++) {
|
|
47
|
+
let crc = i
|
|
48
|
+
for (let j = 0; j < 8; j++) {
|
|
49
|
+
crc = crc & 1 ? 0xedb88320 ^ (crc >>> 1) : crc >>> 1
|
|
50
|
+
}
|
|
51
|
+
crc32Table[i] = crc >>> 0
|
|
52
|
+
}
|
|
53
|
+
return crc32Table
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const crc32 = (bytes: Uint8Array): number => {
|
|
57
|
+
const table = getCrc32Table()
|
|
58
|
+
let crc = 0xffffffff
|
|
59
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
60
|
+
crc = table[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8)
|
|
61
|
+
}
|
|
62
|
+
return (crc ^ 0xffffffff) >>> 0
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const throwNativeGzipValidationError = (reason: NativeGzipValidationReason): never => {
|
|
66
|
+
const error = new Error(`Native gzip produced invalid output: ${reason}`)
|
|
67
|
+
error.name = NATIVE_GZIP_VALIDATION_ERROR
|
|
68
|
+
throw error
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const validateNativeGzip = async (compressed: Blob, inputBytes: Uint8Array): Promise<void> => {
|
|
72
|
+
if (compressed.size < 18) {
|
|
73
|
+
throwNativeGzipValidationError('too-short')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const header = new Uint8Array(await compressed.slice(0, 10).arrayBuffer())
|
|
77
|
+
if (header[0] !== 0x1f || header[1] !== 0x8b || header[2] !== 0x08) {
|
|
78
|
+
throwNativeGzipValidationError('invalid-header')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const trailer = new DataView(await compressed.slice(compressed.size - 8).arrayBuffer())
|
|
82
|
+
if (trailer.getUint32(0, true) !== crc32(inputBytes)) {
|
|
83
|
+
throwNativeGzipValidationError('invalid-crc')
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const inputSize = inputBytes.length >>> 0
|
|
87
|
+
if (trailer.getUint32(4, true) !== inputSize) {
|
|
88
|
+
throwNativeGzipValidationError('invalid-size')
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
24
92
|
export type GzipCompressOptions = {
|
|
25
93
|
/**
|
|
26
94
|
* By default this helper swallows compression errors and returns null.
|
|
@@ -36,11 +104,12 @@ export type GzipCompressOptions = {
|
|
|
36
104
|
*/
|
|
37
105
|
export async function gzipCompress(input: string, isDebug = true, options?: GzipCompressOptions): Promise<Blob | null> {
|
|
38
106
|
try {
|
|
107
|
+
const inputBytes = new TextEncoder().encode(input)
|
|
39
108
|
const compressedStream = new CompressionStream('gzip')
|
|
40
109
|
const writer = compressedStream.writable.getWriter()
|
|
41
110
|
|
|
42
111
|
const writePromise = writer
|
|
43
|
-
.write(
|
|
112
|
+
.write(inputBytes)
|
|
44
113
|
.then(() => writer.close())
|
|
45
114
|
.catch(async (err) => {
|
|
46
115
|
try {
|
|
@@ -53,6 +122,7 @@ export async function gzipCompress(input: string, isDebug = true, options?: Gzip
|
|
|
53
122
|
const responsePromise = new Response(compressedStream.readable).blob()
|
|
54
123
|
|
|
55
124
|
const [compressed] = await Promise.all([responsePromise, writePromise])
|
|
125
|
+
await validateNativeGzip(compressed, inputBytes)
|
|
56
126
|
return compressed
|
|
57
127
|
} catch (error) {
|
|
58
128
|
if (options?.rethrow) {
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { getFeatureFlagValue } from './featureFlagUtils'
|
|
2
|
-
export { gzipCompress, isNativeAsyncGzipReadError } from './gzip'
|
|
2
|
+
export { gzipCompress, isNativeAsyncGzipError, isNativeAsyncGzipReadError } from './gzip'
|
|
3
3
|
export * from './utils'
|
|
4
4
|
export * as ErrorTracking from './error-tracking'
|
|
5
5
|
export {
|