@posthog/plugin-utils 1.1.2 → 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 +2 -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 +1 -1
- package/src/chunk-ids.ts +60 -0
- package/src/cli.ts +18 -6
- package/src/index.ts +1 -0
package/LICENSE
CHANGED
|
@@ -327,12 +327,12 @@ SOFTWARE.
|
|
|
327
327
|
|
|
328
328
|
---
|
|
329
329
|
|
|
330
|
-
Some files in this codebase contain code from MCPCat/mcpcat-typescript-sdk.
|
|
330
|
+
Some files in this codebase contain code from agentcathq/agentcat-typescript-sdk (formerly MCPCat/mcpcat-typescript-sdk).
|
|
331
331
|
In such cases it is explicitly stated in the file header. This license only applies to the relevant code in such cases.
|
|
332
332
|
|
|
333
333
|
MIT License
|
|
334
334
|
|
|
335
|
-
Copyright (c) 2025 MCPcat
|
|
335
|
+
Copyright (c) 2025 AgentCat, Inc. (formerly MCPcat)
|
|
336
336
|
|
|
337
337
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
338
338
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -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
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