@posthog/plugin-utils 1.1.1 → 1.1.3
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/LICENSE +56 -2
- package/dist/chunk-ids.d.ts +30 -0
- package/dist/chunk-ids.d.ts.map +1 -0
- package/dist/chunk-ids.js +64 -0
- package/dist/chunk-ids.mjs +21 -0
- package/dist/cli.d.ts +11 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -4
- package/dist/cli.mjs +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.mjs +1 -0
- package/package.json +4 -1
- package/src/chunk-ids.ts +60 -0
- package/src/cli.ts +18 -6
- package/src/index.ts +1 -0
package/LICENSE
CHANGED
|
@@ -219,8 +219,8 @@ limitations under the License.
|
|
|
219
219
|
|
|
220
220
|
---
|
|
221
221
|
|
|
222
|
-
Some files in this codebase contain code from getsentry/sentry-javascript
|
|
223
|
-
In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases.
|
|
222
|
+
Some files in this codebase contain code from getsentry/sentry-javascript.
|
|
223
|
+
In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases.
|
|
224
224
|
|
|
225
225
|
MIT License
|
|
226
226
|
|
|
@@ -246,6 +246,33 @@ SOFTWARE.
|
|
|
246
246
|
|
|
247
247
|
---
|
|
248
248
|
|
|
249
|
+
Some files in this codebase contain code from getsentry/sentry-react-native.
|
|
250
|
+
In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases.
|
|
251
|
+
|
|
252
|
+
The MIT License (MIT)
|
|
253
|
+
|
|
254
|
+
Copyright (c) 2017 Sentry
|
|
255
|
+
|
|
256
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
257
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
258
|
+
in the Software without restriction, including without limitation the rights
|
|
259
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
260
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
261
|
+
furnished to do so, subject to the following conditions:
|
|
262
|
+
|
|
263
|
+
The above copyright notice and this permission notice shall be included in all
|
|
264
|
+
copies or substantial portions of the Software.
|
|
265
|
+
|
|
266
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
267
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
268
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
269
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
270
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
271
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
272
|
+
SOFTWARE.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
249
276
|
Some files in this codebase contain code from facebook/metro by Meta Platforms, Inc. and affiliates.
|
|
250
277
|
In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases.
|
|
251
278
|
|
|
@@ -297,3 +324,30 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
297
324
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
298
325
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
299
326
|
SOFTWARE.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
Some files in this codebase contain code from agentcathq/agentcat-typescript-sdk (formerly MCPCat/mcpcat-typescript-sdk).
|
|
331
|
+
In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases.
|
|
332
|
+
|
|
333
|
+
MIT License
|
|
334
|
+
|
|
335
|
+
Copyright (c) 2025 AgentCat, Inc. (formerly MCPcat)
|
|
336
|
+
|
|
337
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
338
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
339
|
+
in the Software without restriction, including without limitation the rights
|
|
340
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
341
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
342
|
+
furnished to do so, subject to the following conditions:
|
|
343
|
+
|
|
344
|
+
The above copyright notice and this permission notice shall be included in all
|
|
345
|
+
copies or substantial portions of the Software.
|
|
346
|
+
|
|
347
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
348
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
349
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
350
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
351
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
352
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
353
|
+
SOFTWARE.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the minified chunk-id IIFE the SDK reads at runtime to map an
|
|
3
|
+
* error's stack back to a chunk id.
|
|
4
|
+
*
|
|
5
|
+
* Byte-for-byte contract with posthog-cli (`CODE_SNIPPET_TEMPLATE` in
|
|
6
|
+
* cli/src/sourcemaps/constant.rs): the CLI recognizes and removes previously
|
|
7
|
+
* injected snippets by exact substring match, so any change here must ship in
|
|
8
|
+
* the CLI constants too. Covered by a parity test in chunk-ids.spec.ts.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createChunkIdSnippet(chunkId: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Returns the comment posthog-cli discovers chunk ids from at upload time
|
|
13
|
+
* (`CHUNKID_COMMENT_PREFIX` in cli/src/sourcemaps/constant.rs), including the
|
|
14
|
+
* leading newline the CLI's exact-match removal expects.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createChunkIdComment(chunkId: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Mints a fresh random chunk id: a new id per chunk, per build.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createChunkId(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Extracts the chunk id from source that already carries one, using the same
|
|
23
|
+
* detection the CLI uses: a `//# chunkId=` comment at the start of a line.
|
|
24
|
+
* The injected IIFE is deliberately not matched — its marker text can appear
|
|
25
|
+
* inside string literals of bundled code (docs strings, bundled PostHog
|
|
26
|
+
* tooling), and the CLI only ever reads the line-anchored comment. Keeping the
|
|
27
|
+
* two in sync guarantees this returning an id ⟺ the CLI finding one.
|
|
28
|
+
*/
|
|
29
|
+
export declare function determineChunkIdFromSource(code: string): string | undefined;
|
|
30
|
+
//# sourceMappingURL=chunk-ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-ids.d.ts","sourceRoot":"","sources":["../src/chunk-ids.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AASD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAa3E"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
createChunkIdSnippet: ()=>createChunkIdSnippet,
|
|
28
|
+
createChunkId: ()=>createChunkId,
|
|
29
|
+
createChunkIdComment: ()=>createChunkIdComment,
|
|
30
|
+
determineChunkIdFromSource: ()=>determineChunkIdFromSource
|
|
31
|
+
});
|
|
32
|
+
const external_crypto_namespaceObject = require("crypto");
|
|
33
|
+
function createChunkIdSnippet(chunkId) {
|
|
34
|
+
return `!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._posthogChunkIds=e._posthogChunkIds||{},e._posthogChunkIds[n]="${chunkId}")}catch(e){}}();`;
|
|
35
|
+
}
|
|
36
|
+
function createChunkIdComment(chunkId) {
|
|
37
|
+
return `\n//# chunkId=${chunkId}`;
|
|
38
|
+
}
|
|
39
|
+
function createChunkId() {
|
|
40
|
+
return external_crypto_namespaceObject.randomUUID();
|
|
41
|
+
}
|
|
42
|
+
const COMMENT_REGEX = /^\/\/# chunkId=(\S{1,128})/;
|
|
43
|
+
const COMMENT_MARKER = '//# chunkId=';
|
|
44
|
+
const WINDOW = 256;
|
|
45
|
+
function determineChunkIdFromSource(code) {
|
|
46
|
+
for(let at = code.indexOf(COMMENT_MARKER); -1 !== at; at = code.indexOf(COMMENT_MARKER, at + COMMENT_MARKER.length)){
|
|
47
|
+
if (0 !== at && '\n' !== code[at - 1]) continue;
|
|
48
|
+
const match = COMMENT_REGEX.exec(code.slice(at, at + WINDOW));
|
|
49
|
+
if (match) return match[1];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.createChunkId = __webpack_exports__.createChunkId;
|
|
53
|
+
exports.createChunkIdComment = __webpack_exports__.createChunkIdComment;
|
|
54
|
+
exports.createChunkIdSnippet = __webpack_exports__.createChunkIdSnippet;
|
|
55
|
+
exports.determineChunkIdFromSource = __webpack_exports__.determineChunkIdFromSource;
|
|
56
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
57
|
+
"createChunkId",
|
|
58
|
+
"createChunkIdComment",
|
|
59
|
+
"createChunkIdSnippet",
|
|
60
|
+
"determineChunkIdFromSource"
|
|
61
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
62
|
+
Object.defineProperty(exports, '__esModule', {
|
|
63
|
+
value: true
|
|
64
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { randomUUID } from "crypto";
|
|
2
|
+
function createChunkIdSnippet(chunkId) {
|
|
3
|
+
return `!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._posthogChunkIds=e._posthogChunkIds||{},e._posthogChunkIds[n]="${chunkId}")}catch(e){}}();`;
|
|
4
|
+
}
|
|
5
|
+
function createChunkIdComment(chunkId) {
|
|
6
|
+
return `\n//# chunkId=${chunkId}`;
|
|
7
|
+
}
|
|
8
|
+
function createChunkId() {
|
|
9
|
+
return randomUUID();
|
|
10
|
+
}
|
|
11
|
+
const COMMENT_REGEX = /^\/\/# chunkId=(\S{1,128})/;
|
|
12
|
+
const COMMENT_MARKER = '//# chunkId=';
|
|
13
|
+
const WINDOW = 256;
|
|
14
|
+
function determineChunkIdFromSource(code) {
|
|
15
|
+
for(let at = code.indexOf(COMMENT_MARKER); -1 !== at; at = code.indexOf(COMMENT_MARKER, at + COMMENT_MARKER.length)){
|
|
16
|
+
if (0 !== at && '\n' !== code[at - 1]) continue;
|
|
17
|
+
const match = COMMENT_REGEX.exec(code.slice(at, at + WINDOW));
|
|
18
|
+
if (match) return match[1];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export { createChunkId, createChunkIdComment, createChunkIdSnippet, determineChunkIdFromSource };
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { ResolvedPluginConfig } from './config';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* `process` injects chunk ids into the built files on disk and uploads them.
|
|
4
|
+
* `upload` only reads the files, expecting chunk ids to already be present
|
|
5
|
+
* (e.g. injected in-memory by a bundler plugin before the files were written).
|
|
6
|
+
*/
|
|
7
|
+
export type SourcemapCliCommand = 'process' | 'upload';
|
|
8
|
+
/**
|
|
9
|
+
* Build CLI arguments for `posthog-cli sourcemap <command>`.
|
|
4
10
|
*/
|
|
5
11
|
export declare function buildSourcemapCliArgs(config: ResolvedPluginConfig, mode: {
|
|
6
12
|
stdin: true;
|
|
7
13
|
} | {
|
|
8
14
|
directory: string;
|
|
9
|
-
}): string[];
|
|
15
|
+
}, command?: SourcemapCliCommand): string[];
|
|
10
16
|
/**
|
|
11
17
|
* Build environment variables for CLI invocation.
|
|
12
18
|
* Plugin config values override any existing process.env values.
|
|
@@ -15,9 +21,11 @@ export declare function buildCliEnv(config: ResolvedPluginConfig): NodeJS.Proces
|
|
|
15
21
|
/**
|
|
16
22
|
* Spawn the PostHog CLI for sourcemap processing via stdin (file list).
|
|
17
23
|
*/
|
|
18
|
-
export declare function runSourcemapCli(config: ResolvedPluginConfig, options: {
|
|
24
|
+
export declare function runSourcemapCli(config: ResolvedPluginConfig, options: ({
|
|
19
25
|
filePaths: string[];
|
|
20
26
|
} | {
|
|
21
27
|
directory: string;
|
|
28
|
+
}) & {
|
|
29
|
+
command?: SourcemapCliCommand;
|
|
22
30
|
}): Promise<void>;
|
|
23
31
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAG/C;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,oBAAoB,EAC5B,IAAI,EAAE;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAG/C;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,QAAQ,CAAA;AAEtD;;GAEG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,oBAAoB,EAC5B,IAAI,EAAE;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7C,OAAO,GAAE,mBAA+B,GACzC,MAAM,EAAE,CAkCV;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAAC,UAAU,CAQ3E;AAED;;GAEG;AACH,wBAAsB,eAAe,CACjC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,mBAAmB,CAAA;CAAE,GAC/F,OAAO,CAAC,IAAI,CAAC,CAgBf"}
|
package/dist/cli.js
CHANGED
|
@@ -29,17 +29,17 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
29
29
|
buildSourcemapCliArgs: ()=>buildSourcemapCliArgs
|
|
30
30
|
});
|
|
31
31
|
const external_spawn_local_js_namespaceObject = require("./spawn-local.js");
|
|
32
|
-
function buildSourcemapCliArgs(config, mode) {
|
|
32
|
+
function buildSourcemapCliArgs(config, mode, command = 'process') {
|
|
33
33
|
const args = [
|
|
34
34
|
'sourcemap',
|
|
35
|
-
|
|
35
|
+
command
|
|
36
36
|
];
|
|
37
37
|
if ('stdin' in mode) args.push('--stdin');
|
|
38
38
|
else args.push('--directory', mode.directory);
|
|
39
39
|
if (config.sourcemaps.releaseName) args.push('--release-name', config.sourcemaps.releaseName);
|
|
40
40
|
if (config.sourcemaps.releaseVersion) args.push('--release-version', config.sourcemaps.releaseVersion);
|
|
41
41
|
if (void 0 !== config.sourcemaps.build && '' !== config.sourcemaps.build) args.push('--build', config.sourcemaps.build);
|
|
42
|
-
if (config.sourcemaps.deleteAfterUpload) args.push('--delete-after');
|
|
42
|
+
if (config.sourcemaps.deleteAfterUpload && 'process' === command) args.push('--delete-after');
|
|
43
43
|
if (config.sourcemaps.batchSize) args.push('--batch-size', config.sourcemaps.batchSize.toString());
|
|
44
44
|
return args;
|
|
45
45
|
}
|
|
@@ -58,7 +58,7 @@ async function runSourcemapCli(config, options) {
|
|
|
58
58
|
} : {
|
|
59
59
|
directory: options.directory
|
|
60
60
|
};
|
|
61
|
-
const args = buildSourcemapCliArgs(config, mode);
|
|
61
|
+
const args = buildSourcemapCliArgs(config, mode, options.command ?? 'process');
|
|
62
62
|
const env = buildCliEnv(config);
|
|
63
63
|
const spawnOptions = {
|
|
64
64
|
cwd: process.cwd(),
|
package/dist/cli.mjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { spawnLocal } from "./spawn-local.mjs";
|
|
2
|
-
function buildSourcemapCliArgs(config, mode) {
|
|
2
|
+
function buildSourcemapCliArgs(config, mode, command = 'process') {
|
|
3
3
|
const args = [
|
|
4
4
|
'sourcemap',
|
|
5
|
-
|
|
5
|
+
command
|
|
6
6
|
];
|
|
7
7
|
if ('stdin' in mode) args.push('--stdin');
|
|
8
8
|
else args.push('--directory', mode.directory);
|
|
9
9
|
if (config.sourcemaps.releaseName) args.push('--release-name', config.sourcemaps.releaseName);
|
|
10
10
|
if (config.sourcemaps.releaseVersion) args.push('--release-version', config.sourcemaps.releaseVersion);
|
|
11
11
|
if (void 0 !== config.sourcemaps.build && '' !== config.sourcemaps.build) args.push('--build', config.sourcemaps.build);
|
|
12
|
-
if (config.sourcemaps.deleteAfterUpload) args.push('--delete-after');
|
|
12
|
+
if (config.sourcemaps.deleteAfterUpload && 'process' === command) args.push('--delete-after');
|
|
13
13
|
if (config.sourcemaps.batchSize) args.push('--batch-size', config.sourcemaps.batchSize.toString());
|
|
14
14
|
return args;
|
|
15
15
|
}
|
|
@@ -28,7 +28,7 @@ async function runSourcemapCli(config, options) {
|
|
|
28
28
|
} : {
|
|
29
29
|
directory: options.directory
|
|
30
30
|
};
|
|
31
|
-
const args = buildSourcemapCliArgs(config, mode);
|
|
31
|
+
const args = buildSourcemapCliArgs(config, mode, options.command ?? 'process');
|
|
32
32
|
const env = buildCliEnv(config);
|
|
33
33
|
const spawnOptions = {
|
|
34
34
|
cwd: process.cwd(),
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAClE,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAClE,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,aAAa,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_modules__ = {
|
|
3
|
+
"./chunk-ids": function(module) {
|
|
4
|
+
module.exports = require("./chunk-ids.js");
|
|
5
|
+
},
|
|
3
6
|
"./cli": function(module) {
|
|
4
7
|
module.exports = require("./cli.js");
|
|
5
8
|
},
|
|
@@ -91,6 +94,16 @@ var __webpack_exports__ = {};
|
|
|
91
94
|
return _cli__WEBPACK_IMPORTED_MODULE_3__[key];
|
|
92
95
|
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
93
96
|
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
97
|
+
var _chunk_ids__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./chunk-ids");
|
|
98
|
+
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
99
|
+
for(var __WEBPACK_IMPORT_KEY__ in _chunk_ids__WEBPACK_IMPORTED_MODULE_4__)if ([
|
|
100
|
+
"buildLocalBinaryPaths",
|
|
101
|
+
"resolveBinaryPath",
|
|
102
|
+
"default"
|
|
103
|
+
].indexOf(__WEBPACK_IMPORT_KEY__) < 0) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
104
|
+
return _chunk_ids__WEBPACK_IMPORTED_MODULE_4__[key];
|
|
105
|
+
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
106
|
+
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
94
107
|
})();
|
|
95
108
|
exports.buildLocalBinaryPaths = __webpack_exports__.buildLocalBinaryPaths;
|
|
96
109
|
exports.resolveBinaryPath = __webpack_exports__.resolveBinaryPath;
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@posthog/plugin-utils",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
|
+
"bugs": {
|
|
5
|
+
"url": "https://github.com/PostHog/posthog-js/issues"
|
|
6
|
+
},
|
|
4
7
|
"description": "Shared CLI and sourcemap utilities for PostHog build plugins",
|
|
5
8
|
"license": "MIT",
|
|
6
9
|
"repository": {
|
package/src/chunk-ids.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as crypto from 'crypto'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns the minified chunk-id IIFE the SDK reads at runtime to map an
|
|
5
|
+
* error's stack back to a chunk id.
|
|
6
|
+
*
|
|
7
|
+
* Byte-for-byte contract with posthog-cli (`CODE_SNIPPET_TEMPLATE` in
|
|
8
|
+
* cli/src/sourcemaps/constant.rs): the CLI recognizes and removes previously
|
|
9
|
+
* injected snippets by exact substring match, so any change here must ship in
|
|
10
|
+
* the CLI constants too. Covered by a parity test in chunk-ids.spec.ts.
|
|
11
|
+
*/
|
|
12
|
+
export function createChunkIdSnippet(chunkId: string): string {
|
|
13
|
+
return `!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._posthogChunkIds=e._posthogChunkIds||{},e._posthogChunkIds[n]="${chunkId}")}catch(e){}}();`
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Returns the comment posthog-cli discovers chunk ids from at upload time
|
|
18
|
+
* (`CHUNKID_COMMENT_PREFIX` in cli/src/sourcemaps/constant.rs), including the
|
|
19
|
+
* leading newline the CLI's exact-match removal expects.
|
|
20
|
+
*/
|
|
21
|
+
export function createChunkIdComment(chunkId: string): string {
|
|
22
|
+
return `\n//# chunkId=${chunkId}`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Mints a fresh random chunk id: a new id per chunk, per build.
|
|
27
|
+
*/
|
|
28
|
+
export function createChunkId(): string {
|
|
29
|
+
return crypto.randomUUID()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Anchored with a bounded quantifier and only ever run against a fixed-size
|
|
33
|
+
// window: an unbounded regex over the whole bundle is quadratic on adversarial
|
|
34
|
+
// input (a match attempt per marker occurrence, each scanning ahead).
|
|
35
|
+
const COMMENT_REGEX = /^\/\/# chunkId=(\S{1,128})/
|
|
36
|
+
const COMMENT_MARKER = '//# chunkId='
|
|
37
|
+
const WINDOW = 256
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Extracts the chunk id from source that already carries one, using the same
|
|
41
|
+
* detection the CLI uses: a `//# chunkId=` comment at the start of a line.
|
|
42
|
+
* The injected IIFE is deliberately not matched — its marker text can appear
|
|
43
|
+
* inside string literals of bundled code (docs strings, bundled PostHog
|
|
44
|
+
* tooling), and the CLI only ever reads the line-anchored comment. Keeping the
|
|
45
|
+
* two in sync guarantees this returning an id ⟺ the CLI finding one.
|
|
46
|
+
*/
|
|
47
|
+
export function determineChunkIdFromSource(code: string): string | undefined {
|
|
48
|
+
for (
|
|
49
|
+
let at = code.indexOf(COMMENT_MARKER);
|
|
50
|
+
at !== -1;
|
|
51
|
+
at = code.indexOf(COMMENT_MARKER, at + COMMENT_MARKER.length)
|
|
52
|
+
) {
|
|
53
|
+
if (at !== 0 && code[at - 1] !== '\n') continue
|
|
54
|
+
const match = COMMENT_REGEX.exec(code.slice(at, at + WINDOW))
|
|
55
|
+
if (match) {
|
|
56
|
+
return match[1]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return undefined
|
|
60
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -2,13 +2,21 @@ import { ResolvedPluginConfig } from './config'
|
|
|
2
2
|
import { spawnLocal } from './spawn-local'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* `process` injects chunk ids into the built files on disk and uploads them.
|
|
6
|
+
* `upload` only reads the files, expecting chunk ids to already be present
|
|
7
|
+
* (e.g. injected in-memory by a bundler plugin before the files were written).
|
|
8
|
+
*/
|
|
9
|
+
export type SourcemapCliCommand = 'process' | 'upload'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Build CLI arguments for `posthog-cli sourcemap <command>`.
|
|
6
13
|
*/
|
|
7
14
|
export function buildSourcemapCliArgs(
|
|
8
15
|
config: ResolvedPluginConfig,
|
|
9
|
-
mode: { stdin: true } | { directory: string }
|
|
16
|
+
mode: { stdin: true } | { directory: string },
|
|
17
|
+
command: SourcemapCliCommand = 'process'
|
|
10
18
|
): string[] {
|
|
11
|
-
const args = ['sourcemap',
|
|
19
|
+
const args = ['sourcemap', command]
|
|
12
20
|
|
|
13
21
|
if ('stdin' in mode) {
|
|
14
22
|
args.push('--stdin')
|
|
@@ -28,7 +36,11 @@ export function buildSourcemapCliArgs(
|
|
|
28
36
|
args.push('--build', config.sourcemaps.build)
|
|
29
37
|
}
|
|
30
38
|
|
|
31
|
-
|
|
39
|
+
// On `upload` the caller owns map deletion: `--delete-after` also rewrites
|
|
40
|
+
// the .js files (stripping sourcemap references), and callers pick `upload`
|
|
41
|
+
// precisely because the written files must not change — e.g. Subresource
|
|
42
|
+
// Integrity hashes were already computed from them.
|
|
43
|
+
if (config.sourcemaps.deleteAfterUpload && command === 'process') {
|
|
32
44
|
args.push('--delete-after')
|
|
33
45
|
}
|
|
34
46
|
|
|
@@ -58,10 +70,10 @@ export function buildCliEnv(config: ResolvedPluginConfig): NodeJS.ProcessEnv {
|
|
|
58
70
|
*/
|
|
59
71
|
export async function runSourcemapCli(
|
|
60
72
|
config: ResolvedPluginConfig,
|
|
61
|
-
options: { filePaths: string[] } | { directory: string }
|
|
73
|
+
options: ({ filePaths: string[] } | { directory: string }) & { command?: SourcemapCliCommand }
|
|
62
74
|
): Promise<void> {
|
|
63
75
|
const mode = 'filePaths' in options ? { stdin: true as const } : { directory: options.directory }
|
|
64
|
-
const args = buildSourcemapCliArgs(config, mode)
|
|
76
|
+
const args = buildSourcemapCliArgs(config, mode, options.command ?? 'process')
|
|
65
77
|
const env = buildCliEnv(config)
|
|
66
78
|
|
|
67
79
|
const spawnOptions: Parameters<typeof spawnLocal>[2] = {
|
package/src/index.ts
CHANGED