@blaxel/core 0.3.29 → 0.3.30-preview.324
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/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/client/sdk.gen.js +93 -4
- package/dist/cjs/common/lazyInit.js +8 -0
- package/dist/cjs/common/posthog.js +256 -0
- package/dist/cjs/common/settings.js +2 -2
- package/dist/cjs/types/client/sdk.gen.d.ts +26 -1
- package/dist/cjs/types/client/types.gen.d.ts +156 -2
- package/dist/cjs/types/common/posthog.d.ts +51 -0
- package/dist/cjs-browser/.tsbuildinfo +1 -1
- package/dist/cjs-browser/client/sdk.gen.js +93 -4
- package/dist/cjs-browser/common/lazyInit.js +8 -0
- package/dist/cjs-browser/common/posthog.js +256 -0
- package/dist/cjs-browser/common/settings.js +2 -2
- package/dist/cjs-browser/types/client/sdk.gen.d.ts +26 -1
- package/dist/cjs-browser/types/client/types.gen.d.ts +156 -2
- package/dist/cjs-browser/types/common/posthog.d.ts +51 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/client/sdk.gen.js +84 -0
- package/dist/esm/common/lazyInit.js +8 -0
- package/dist/esm/common/posthog.js +250 -0
- package/dist/esm/common/settings.js +2 -2
- package/dist/esm-browser/.tsbuildinfo +1 -1
- package/dist/esm-browser/client/sdk.gen.js +84 -0
- package/dist/esm-browser/common/lazyInit.js +8 -0
- package/dist/esm-browser/common/posthog.js +250 -0
- package/dist/esm-browser/common/settings.js +2 -2
- package/package.json +2 -2
|
@@ -508,6 +508,22 @@ export const createDriveAccessToken = (options) => {
|
|
|
508
508
|
...options
|
|
509
509
|
});
|
|
510
510
|
};
|
|
511
|
+
/**
|
|
512
|
+
* Delete a folder and its contents
|
|
513
|
+
* Deletes a folder and all its contents directly in drive storage. This is synchronous and non-atomic. If it times out or fails, some contents may have been deleted; retry the same path to finish cleanup. An absent folder succeeds. The drive root and internal metadata cannot be deleted.
|
|
514
|
+
*/
|
|
515
|
+
export const deleteDriveFolder = (options) => {
|
|
516
|
+
return (options.client ?? _heyApiClient).delete({
|
|
517
|
+
security: [
|
|
518
|
+
{
|
|
519
|
+
scheme: 'bearer',
|
|
520
|
+
type: 'http'
|
|
521
|
+
}
|
|
522
|
+
],
|
|
523
|
+
url: '/drives/{driveName}/folders',
|
|
524
|
+
...options
|
|
525
|
+
});
|
|
526
|
+
};
|
|
511
527
|
/**
|
|
512
528
|
* Get drive by external ID
|
|
513
529
|
* Returns a drive matching the given external ID. If no drive is found, returns 404.
|
|
@@ -2060,6 +2076,74 @@ export const getSandboxScheduleMetrics = (options) => {
|
|
|
2060
2076
|
...options
|
|
2061
2077
|
});
|
|
2062
2078
|
};
|
|
2079
|
+
/**
|
|
2080
|
+
* Delete secret by query
|
|
2081
|
+
* Deletes a secret by name (query parameter) from the workspace.
|
|
2082
|
+
*/
|
|
2083
|
+
export const deleteSecretByQuery = (options) => {
|
|
2084
|
+
return (options.client ?? _heyApiClient).delete({
|
|
2085
|
+
security: [
|
|
2086
|
+
{
|
|
2087
|
+
scheme: 'bearer',
|
|
2088
|
+
type: 'http'
|
|
2089
|
+
}
|
|
2090
|
+
],
|
|
2091
|
+
url: '/secrets',
|
|
2092
|
+
...options
|
|
2093
|
+
});
|
|
2094
|
+
};
|
|
2095
|
+
/**
|
|
2096
|
+
* List secrets
|
|
2097
|
+
* Lists the secrets of the workspace. Values are write-only and never returned.
|
|
2098
|
+
*/
|
|
2099
|
+
export const listSecrets = (options) => {
|
|
2100
|
+
return (options?.client ?? _heyApiClient).get({
|
|
2101
|
+
security: [
|
|
2102
|
+
{
|
|
2103
|
+
scheme: 'bearer',
|
|
2104
|
+
type: 'http'
|
|
2105
|
+
}
|
|
2106
|
+
],
|
|
2107
|
+
url: '/secrets',
|
|
2108
|
+
...options
|
|
2109
|
+
});
|
|
2110
|
+
};
|
|
2111
|
+
/**
|
|
2112
|
+
* Upsert secret
|
|
2113
|
+
* Creates or updates a secret by name. Each call stores a new immutable version; the latest version is the one resolved by the proxy.
|
|
2114
|
+
*/
|
|
2115
|
+
export const upsertSecret = (options) => {
|
|
2116
|
+
return (options.client ?? _heyApiClient).post({
|
|
2117
|
+
security: [
|
|
2118
|
+
{
|
|
2119
|
+
scheme: 'bearer',
|
|
2120
|
+
type: 'http'
|
|
2121
|
+
}
|
|
2122
|
+
],
|
|
2123
|
+
url: '/secrets',
|
|
2124
|
+
...options,
|
|
2125
|
+
headers: {
|
|
2126
|
+
'Content-Type': 'application/json',
|
|
2127
|
+
...options?.headers
|
|
2128
|
+
}
|
|
2129
|
+
});
|
|
2130
|
+
};
|
|
2131
|
+
/**
|
|
2132
|
+
* Delete secret
|
|
2133
|
+
* Deletes a secret and all its versions from the workspace.
|
|
2134
|
+
*/
|
|
2135
|
+
export const deleteSecret = (options) => {
|
|
2136
|
+
return (options.client ?? _heyApiClient).delete({
|
|
2137
|
+
security: [
|
|
2138
|
+
{
|
|
2139
|
+
scheme: 'bearer',
|
|
2140
|
+
type: 'http'
|
|
2141
|
+
}
|
|
2142
|
+
],
|
|
2143
|
+
url: '/secrets/{secretName}',
|
|
2144
|
+
...options
|
|
2145
|
+
});
|
|
2146
|
+
};
|
|
2063
2147
|
/**
|
|
2064
2148
|
* List service accounts
|
|
2065
2149
|
* Returns all service accounts in the workspace. Service accounts are machine identities for external systems to authenticate with Blaxel via OAuth or API keys.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { client } from "../client/client.gen.js";
|
|
2
2
|
import { client as clientSandbox } from "../sandbox/client/client.gen.js";
|
|
3
3
|
import { controlPlaneFetch } from "./controlPlaneFetch.js";
|
|
4
|
+
import { trackSDKInstalled } from "./posthog.js";
|
|
4
5
|
import { initSentry } from "./sentry.js";
|
|
5
6
|
import { settings } from "./settings.js";
|
|
6
7
|
let autoloaded = false;
|
|
@@ -38,6 +39,13 @@ export function ensureAutoloaded() {
|
|
|
38
39
|
clientSandbox.setConfig({ baseUrl: settings.baseUrl });
|
|
39
40
|
// Initialize Sentry for SDK error tracking.
|
|
40
41
|
initSentry();
|
|
42
|
+
// Track SDK installation (fires once per new version).
|
|
43
|
+
try {
|
|
44
|
+
trackSDKInstalled();
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Silently ignore - telemetry should never break the SDK
|
|
48
|
+
}
|
|
41
49
|
// Background H2 connection warming (Node.js only)
|
|
42
50
|
const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
|
|
43
51
|
/* eslint-disable */
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { fs, os, path } from "../common/node.js";
|
|
2
|
+
import { settings } from "./settings.js";
|
|
3
|
+
// PostHog API key injected at build time via build:replace-imports
|
|
4
|
+
const BUILD_POSTHOG_KEY = "";
|
|
5
|
+
// PostHog API endpoint
|
|
6
|
+
const POSTHOG_HOST = "https://us.i.posthog.com";
|
|
7
|
+
/**
|
|
8
|
+
* How long a capture may stay outstanding.
|
|
9
|
+
*
|
|
10
|
+
* Node keeps the event loop alive while a fetch is pending, so this is what a
|
|
11
|
+
* short-lived script waits for before it can exit. A capture against
|
|
12
|
+
* us.i.posthog.com takes ~250-350ms end to end (DNS + TLS handshake + POST), so
|
|
13
|
+
* a second covers the happy path with headroom. The ceiling matters because a
|
|
14
|
+
* version is only recorded after a successful delivery: when the endpoint is
|
|
15
|
+
* unreachable every later run tries again, and networks that silently drop
|
|
16
|
+
* traffic rather than refusing it would otherwise pay the full timeout each
|
|
17
|
+
* time.
|
|
18
|
+
*/
|
|
19
|
+
export const POSTHOG_FLUSH_BUDGET_MS = 1000;
|
|
20
|
+
/** The single per-language entry this SDK owns in the shared telemetry file. */
|
|
21
|
+
const SDK_STATE_KEY = "typescript";
|
|
22
|
+
let telemetryState = null;
|
|
23
|
+
/**
|
|
24
|
+
* Get the PostHog API key (injected at build time).
|
|
25
|
+
*/
|
|
26
|
+
function getPosthogKey() {
|
|
27
|
+
const key = BUILD_POSTHOG_KEY;
|
|
28
|
+
// If the placeholder was not replaced, treat as empty
|
|
29
|
+
if (!key || key.startsWith("__BUILD_")) {
|
|
30
|
+
return "";
|
|
31
|
+
}
|
|
32
|
+
return key;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get the telemetry file path.
|
|
36
|
+
*/
|
|
37
|
+
function getTelemetryPath() {
|
|
38
|
+
if (os === null || path === null) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
return path.join(os.homedir(), ".blaxel", "telemetry.json");
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Load telemetry state from disk.
|
|
50
|
+
*/
|
|
51
|
+
function loadTelemetryState() {
|
|
52
|
+
if (telemetryState !== null) {
|
|
53
|
+
return telemetryState;
|
|
54
|
+
}
|
|
55
|
+
telemetryState = { distinct_id: "", sdks: {} };
|
|
56
|
+
if (fs === null) {
|
|
57
|
+
return telemetryState;
|
|
58
|
+
}
|
|
59
|
+
const telemetryPath = getTelemetryPath();
|
|
60
|
+
if (!telemetryPath) {
|
|
61
|
+
return telemetryState;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const data = fs.readFileSync(telemetryPath, "utf8");
|
|
65
|
+
const parsed = JSON.parse(data);
|
|
66
|
+
telemetryState = {
|
|
67
|
+
...parsed,
|
|
68
|
+
distinct_id: parsed.distinct_id || "",
|
|
69
|
+
sdks: parsed.sdks || {},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// File doesn't exist or is invalid - use defaults
|
|
74
|
+
}
|
|
75
|
+
return telemetryState;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Combine this process's telemetry snapshot with what is on disk right now.
|
|
79
|
+
*
|
|
80
|
+
* `~/.blaxel/telemetry.json` is shared with the CLI and the Python SDK, and
|
|
81
|
+
* each of them caches it in memory for the lifetime of its process. Writing
|
|
82
|
+
* this snapshot back wholesale would roll back anything the others recorded in
|
|
83
|
+
* the meantime, which makes them re-send their "Installed" event on every later
|
|
84
|
+
* run. Anything already on disk is at least as fresh as what is held here, so
|
|
85
|
+
* it wins, except for the fields this process actually owns.
|
|
86
|
+
*/
|
|
87
|
+
export function mergeTelemetryState(onDisk, ours) {
|
|
88
|
+
const merged = { ...ours, ...onDisk };
|
|
89
|
+
// Only re-assert the one language entry this process owns. Writing back the
|
|
90
|
+
// whole cached map would roll back a newer version another SDK recorded
|
|
91
|
+
// after this process started, and that SDK would then re-send its
|
|
92
|
+
// "Installed" event.
|
|
93
|
+
const onDiskSdks = typeof onDisk.sdks === "object" && onDisk.sdks !== null ? onDisk.sdks : {};
|
|
94
|
+
const ownVersion = ours.sdks?.[SDK_STATE_KEY];
|
|
95
|
+
merged.sdks = {
|
|
96
|
+
...onDiskSdks,
|
|
97
|
+
...(ownVersion ? { [SDK_STATE_KEY]: ownVersion } : {}),
|
|
98
|
+
};
|
|
99
|
+
// distinct_id is shared by every writer, so the first one persisted wins.
|
|
100
|
+
// Replacing it would split the same user across two PostHog identities.
|
|
101
|
+
const onDiskId = typeof onDisk.distinct_id === "string" ? onDisk.distinct_id : "";
|
|
102
|
+
merged.distinct_id = onDiskId || ours.distinct_id;
|
|
103
|
+
return merged;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Save telemetry state to disk, preserving concurrent writes from the CLI and
|
|
107
|
+
* the other SDK.
|
|
108
|
+
*/
|
|
109
|
+
function saveTelemetryState(state) {
|
|
110
|
+
if (fs === null || path === null || os === null) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const telemetryPath = getTelemetryPath();
|
|
114
|
+
if (!telemetryPath) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
const dir = path.dirname(telemetryPath);
|
|
119
|
+
if (!fs.existsSync(dir)) {
|
|
120
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
121
|
+
}
|
|
122
|
+
// Re-read immediately before writing rather than trusting the snapshot
|
|
123
|
+
// loaded when this process started.
|
|
124
|
+
let onDisk = {};
|
|
125
|
+
try {
|
|
126
|
+
const parsed = JSON.parse(fs.readFileSync(telemetryPath, "utf8"));
|
|
127
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
128
|
+
onDisk = parsed;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// No readable file yet - this process's state is all there is.
|
|
133
|
+
}
|
|
134
|
+
const merged = mergeTelemetryState(onDisk, state);
|
|
135
|
+
fs.writeFileSync(telemetryPath, JSON.stringify(merged, null, 2), {
|
|
136
|
+
mode: 0o600,
|
|
137
|
+
});
|
|
138
|
+
// Adopt the persisted identity so events match what other writers use.
|
|
139
|
+
if (typeof merged.distinct_id === "string" && merged.distinct_id) {
|
|
140
|
+
state.distinct_id = merged.distinct_id;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Silently fail
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Generate a UUID v4 without external dependencies.
|
|
149
|
+
*/
|
|
150
|
+
function generateUUID() {
|
|
151
|
+
const bytes = new Uint8Array(16);
|
|
152
|
+
crypto.getRandomValues(bytes);
|
|
153
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4
|
|
154
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 10
|
|
155
|
+
const hex = Array.from(bytes)
|
|
156
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
157
|
+
.join("");
|
|
158
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get or create a persistent distinct ID for PostHog events.
|
|
162
|
+
*/
|
|
163
|
+
function getDistinctID() {
|
|
164
|
+
const state = loadTelemetryState();
|
|
165
|
+
if (state.distinct_id) {
|
|
166
|
+
return state.distinct_id;
|
|
167
|
+
}
|
|
168
|
+
state.distinct_id = generateUUID();
|
|
169
|
+
saveTelemetryState(state);
|
|
170
|
+
return state.distinct_id;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Create an SDK install tracker. Exported from this internal module so delivery
|
|
174
|
+
* and deduplication behavior can be tested without build-time credentials.
|
|
175
|
+
*/
|
|
176
|
+
export function createSDKInstallTracker(options) {
|
|
177
|
+
const pendingVersions = new Set();
|
|
178
|
+
return function track() {
|
|
179
|
+
const apiKey = options.getApiKey();
|
|
180
|
+
if (!apiKey || !options.isTrackingEnabled() || !options.isNode()) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const version = options.getVersion();
|
|
184
|
+
if (!version ||
|
|
185
|
+
version === "unknown" ||
|
|
186
|
+
version === "__BUILD_VERSION__") {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const state = options.loadState();
|
|
190
|
+
const stateKey = SDK_STATE_KEY;
|
|
191
|
+
if (state.sdks?.[stateKey] === version || pendingVersions.has(version)) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
pendingVersions.add(version);
|
|
195
|
+
return (async () => {
|
|
196
|
+
try {
|
|
197
|
+
const payload = {
|
|
198
|
+
api_key: apiKey,
|
|
199
|
+
event: "Installed SDK",
|
|
200
|
+
distinct_id: options.getDistinctId(),
|
|
201
|
+
timestamp: new Date().toISOString(),
|
|
202
|
+
properties: {
|
|
203
|
+
language: "typescript",
|
|
204
|
+
sdk: "core",
|
|
205
|
+
version,
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
const response = await options.fetch(`${POSTHOG_HOST}/capture/`, {
|
|
209
|
+
method: "POST",
|
|
210
|
+
headers: { "Content-Type": "application/json" },
|
|
211
|
+
body: JSON.stringify(payload),
|
|
212
|
+
signal: options.getSignal(),
|
|
213
|
+
});
|
|
214
|
+
if (!response.ok) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
state.sdks ??= {};
|
|
218
|
+
state.sdks[stateKey] = version;
|
|
219
|
+
options.saveState(state);
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// Telemetry must never break the SDK. A later call may retry.
|
|
223
|
+
}
|
|
224
|
+
finally {
|
|
225
|
+
pendingVersions.delete(version);
|
|
226
|
+
}
|
|
227
|
+
})();
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
const sdkInstallTracker = createSDKInstallTracker({
|
|
231
|
+
getApiKey: getPosthogKey,
|
|
232
|
+
isTrackingEnabled: () => settings.tracking,
|
|
233
|
+
getVersion: () => settings.version,
|
|
234
|
+
isNode: () => typeof process !== "undefined" && Boolean(process.versions?.node),
|
|
235
|
+
loadState: loadTelemetryState,
|
|
236
|
+
saveState: saveTelemetryState,
|
|
237
|
+
getDistinctId: getDistinctID,
|
|
238
|
+
fetch: (...args) => globalThis.fetch(...args),
|
|
239
|
+
getSignal: () => typeof AbortSignal !== "undefined" &&
|
|
240
|
+
typeof AbortSignal.timeout === "function"
|
|
241
|
+
? AbortSignal.timeout(POSTHOG_FLUSH_BUDGET_MS)
|
|
242
|
+
: undefined,
|
|
243
|
+
});
|
|
244
|
+
/**
|
|
245
|
+
* Track SDK installation. Fires "Installed SDK" once per new version.
|
|
246
|
+
* Called during SDK autoload.
|
|
247
|
+
*/
|
|
248
|
+
export function trackSDKInstalled() {
|
|
249
|
+
void sdkInstallTracker();
|
|
250
|
+
}
|
|
@@ -24,8 +24,8 @@ function missingCredentialsMessage() {
|
|
|
24
24
|
return "No Blaxel credentials found. Set the BL_API_KEY and BL_WORKSPACE environment variables, or run `bl login`.";
|
|
25
25
|
}
|
|
26
26
|
// Build info - these placeholders are replaced at build time by build:replace-imports
|
|
27
|
-
const BUILD_VERSION = "0.3.
|
|
28
|
-
const BUILD_COMMIT = "
|
|
27
|
+
const BUILD_VERSION = "0.3.30-preview.324";
|
|
28
|
+
const BUILD_COMMIT = "e88b0db8a85b1db102dfedce7af3e5f5ebae1f52";
|
|
29
29
|
const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
|
|
30
30
|
const BLAXEL_API_VERSION = "2026-09-22";
|
|
31
31
|
// Bun < 1.3.11 never sends connection-level WINDOW_UPDATE: the pooled h2
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blaxel/core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.30-preview.324",
|
|
4
4
|
"description": "Blaxel Core SDK for TypeScript",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Blaxel, INC (https://blaxel.ai)",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"build:fix-esm": "node fix-esm-imports.js",
|
|
15
15
|
"build:esm-package": "echo '{\"type\":\"module\"}' > dist/esm/package.json",
|
|
16
16
|
"build:browser": "node fix-browser-imports.js",
|
|
17
|
-
"build:replace-imports": "node -e \"const fs=require('fs'),{execSync}=require('child_process'),pkg=require('./package.json');let commit='unknown';try{commit=execSync('git rev-parse HEAD',{encoding:'utf8'}).trim()}catch(e){console.log('⚠️ Could not get commit:',e.message)}const sentryDsn=process.env.SENTRY_DSN||'';const
|
|
17
|
+
"build:replace-imports": "node -e \"const fs=require('fs'),{execSync}=require('child_process'),pkg=require('./package.json');let commit='unknown';try{commit=execSync('git rev-parse HEAD',{encoding:'utf8'}).trim()}catch(e){console.log('⚠️ Could not get commit:',e.message)}const sentryDsn=process.env.SENTRY_DSN||'';const posthogKey=process.env.POSTHOG_KEY||'';const settingsPaths=['dist/cjs/common/settings.js','dist/esm/common/settings.js','dist/cjs-browser/common/settings.js','dist/esm-browser/common/settings.js'];settingsPaths.forEach(p=>{if(fs.existsSync(p)){let c=fs.readFileSync(p,'utf8');c=c.replace(/__BUILD_VERSION__/g,pkg.version);c=c.replace(/__BUILD_COMMIT__/g,commit);c=c.replace(/__BUILD_SENTRY_DSN__/g,sentryDsn);fs.writeFileSync(p,c);console.log('✅ Injected build info in',p,'(v'+pkg.version+', commit:'+commit.substring(0,7)+')');}});const posthogPaths=['dist/cjs/common/posthog.js','dist/esm/common/posthog.js','dist/cjs-browser/common/posthog.js','dist/esm-browser/common/posthog.js'];posthogPaths.forEach(p=>{if(fs.existsSync(p)){let c=fs.readFileSync(p,'utf8');c=c.replace(/__BUILD_POSTHOG_KEY__/g,posthogKey);fs.writeFileSync(p,c);console.log('✅ Injected PostHog key in',p);}});\"",
|
|
18
18
|
"test": "vitest --run",
|
|
19
19
|
"test:watch": "vitest --watch"
|
|
20
20
|
},
|