@codaco/analytics 9.0.0 → 11.0.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 CHANGED
@@ -1,15 +1,16 @@
1
1
  # @codaco/analytics
2
2
 
3
- PostHog analytics wrapper for Network Canvas applications with installation ID tracking, error reporting, and feature flags support.
3
+ PostHog analytics wrapper for Network Canvas applications with multi-app support, installation ID tracking, error reporting, and feature flags.
4
4
 
5
5
  ## Overview
6
6
 
7
- This package provides a simplified abstraction over PostHog analytics, designed specifically for Network Canvas applications. It ensures that every analytics event includes an installation ID, making it possible to track deployments without compromising user privacy.
7
+ This package provides a simplified abstraction over PostHog analytics, designed for Network Canvas applications. Multiple apps (Fresco, Architect, Studio, etc.) share a single PostHog project, with events segmented by the required `app` property. Every event also includes an `installationId`, making it possible to track deployments without compromising user privacy.
8
8
 
9
9
  **Important:** This package is designed to work exclusively with the Cloudflare Worker reverse proxy at `ph-relay.networkcanvas.com`. All PostHog authentication is handled by the worker, so you don't need to configure API keys in your application.
10
10
 
11
11
  ## Features
12
12
 
13
+ - **Multi-App Support**: Segment events by application within a single PostHog project
13
14
  - **Installation ID Tracking**: Automatically includes installation ID with every event
14
15
  - **Error Tracking**: Capture errors with full stack traces
15
16
  - **Feature Flags**: Built-in support for PostHog feature flags and A/B testing
@@ -37,86 +38,152 @@ DISABLE_ANALYTICS=true
37
38
  NEXT_PUBLIC_DISABLE_ANALYTICS=true
38
39
  ```
39
40
 
40
- ### Client-Side Usage (React)
41
+ ### Client-Side Usage
42
+
43
+ #### Pattern A: `instrumentation-client.ts` (recommended for Next.js 16+)
44
+
45
+ ```ts
46
+ // instrumentation-client.ts
47
+ import { createAnalytics, mergeConfig } from "@codaco/analytics";
48
+
49
+ createAnalytics(
50
+ mergeConfig({
51
+ app: "Fresco",
52
+ installationId: process.env.NEXT_PUBLIC_INSTALLATION_ID!,
53
+ }),
54
+ );
55
+ ```
56
+
57
+ #### Pattern B: React Provider (still supported)
41
58
 
42
59
  ```tsx
43
- // In your root layout (app/layout.tsx)
44
- import { AnalyticsProvider } from '@codaco/analytics';
60
+ // app/layout.tsx
61
+ import { AnalyticsProvider } from "@codaco/analytics";
45
62
 
46
63
  export default function RootLayout({ children }: { children: React.ReactNode }) {
47
- return (
48
- <html>
49
- <body>
50
- <AnalyticsProvider
51
- config={{
52
- installationId: 'your-unique-installation-id',
53
- }}
54
- >
55
- {children}
56
- </AnalyticsProvider>
57
- </body>
58
- </html>
59
- );
64
+ return (
65
+ <html>
66
+ <body>
67
+ <AnalyticsProvider
68
+ config={{
69
+ app: "Fresco",
70
+ installationId: "your-unique-installation-id",
71
+ }}
72
+ >
73
+ {children}
74
+ </AnalyticsProvider>
75
+ </body>
76
+ </html>
77
+ );
60
78
  }
61
79
  ```
62
80
 
63
81
  ```tsx
64
82
  // In your components
65
- import { useAnalytics } from '@codaco/analytics';
83
+ import { useAnalytics } from "@codaco/analytics";
66
84
 
67
85
  export function MyComponent() {
68
- const { trackEvent, trackError } = useAnalytics();
86
+ const { trackEvent, trackError } = useAnalytics();
69
87
 
70
- const handleSetup = () => {
71
- trackEvent('app_setup', {
72
- metadata: { version: '1.0.0' }
73
- });
74
- };
88
+ const handleSetup = () => {
89
+ trackEvent("app_setup", {
90
+ metadata: { version: "1.0.0" },
91
+ });
92
+ };
75
93
 
76
- const handleError = (error: Error) => {
77
- trackError(error, {
78
- metadata: { context: 'component-mount' }
79
- });
80
- };
94
+ const handleError = (error: Error) => {
95
+ trackError(error, {
96
+ metadata: { context: "component-mount" },
97
+ });
98
+ };
81
99
 
82
- return <button onClick={handleSetup}>Setup App</button>;
100
+ return <button onClick={handleSetup}>Setup App</button>;
83
101
  }
84
102
  ```
85
103
 
86
104
  ### Server-Side Usage
87
105
 
106
+ #### `instrumentation.ts` (recommended for Next.js 16+)
107
+
88
108
  ```ts
89
- // First, initialize in your root layout or middleware
90
- import { initServerAnalytics } from '@codaco/analytics/server';
109
+ // instrumentation.ts
110
+ export async function register() {
111
+ if (process.env.NEXT_RUNTIME === "nodejs") {
112
+ const { initServerAnalytics } = await import("@codaco/analytics/server");
113
+ initServerAnalytics({
114
+ app: "Fresco",
115
+ installationId: process.env.INSTALLATION_ID!,
116
+ });
117
+ }
118
+ }
119
+ ```
120
+
121
+ #### Direct initialization
122
+
123
+ ```ts
124
+ import { initServerAnalytics } from "@codaco/analytics/server";
91
125
 
92
126
  initServerAnalytics({
93
- installationId: 'your-unique-installation-id',
127
+ app: "Fresco",
128
+ installationId: "your-unique-installation-id",
94
129
  });
95
130
 
96
131
  // Then use in API routes or server actions
97
- import { serverAnalytics } from '@codaco/analytics/server';
132
+ import { serverAnalytics } from "@codaco/analytics/server";
98
133
 
99
134
  export async function POST(request: Request) {
100
- try {
101
- // Your logic here
102
-
103
- serverAnalytics.trackEvent('data_exported', {
104
- metadata: { format: 'csv', rowCount: 100 }
105
- });
106
-
107
- return Response.json({ success: true });
108
- } catch (error) {
109
- serverAnalytics.trackError(error as Error);
110
- return Response.json({ error: 'Failed' }, { status: 500 });
111
- }
135
+ try {
136
+ serverAnalytics.trackEvent("data_exported", {
137
+ metadata: { format: "csv", rowCount: 100 },
138
+ });
139
+
140
+ return Response.json({ success: true });
141
+ } catch (error) {
142
+ serverAnalytics.trackError(error as Error);
143
+ return Response.json({ error: "Failed" }, { status: 500 });
144
+ }
112
145
  }
113
146
  ```
114
147
 
115
148
  ## API Reference
116
149
 
150
+ ### Config Options
151
+
152
+ ```typescript
153
+ interface AnalyticsConfig {
154
+ // Required: Application identifier for PostHog segmentation
155
+ app: "Fresco" | "Studio" | "Architect" | "Interviewer" | "ArchitectWeb" | "CommunityForum" | "ProjectWebsite" | "Documentation";
156
+
157
+ // Required: Unique identifier for this installation
158
+ installationId: string;
159
+
160
+ // Optional: PostHog API key
161
+ // Defaults to a placeholder (authentication handled by the proxy)
162
+ apiKey?: string;
163
+
164
+ // Optional: PostHog API host
165
+ // Hardcoded to "https://ph-relay.networkcanvas.com" by default
166
+ apiHost?: string;
167
+
168
+ // Optional: Disable all tracking
169
+ disabled?: boolean;
170
+
171
+ // Optional: Enable debug mode
172
+ debug?: boolean;
173
+
174
+ // Optional: PostHog-specific options
175
+ posthogOptions?: {
176
+ disable_session_recording?: boolean;
177
+ autocapture?: boolean;
178
+ capture_pageview?: boolean;
179
+ // ... other PostHog options
180
+ };
181
+ }
182
+ ```
183
+
117
184
  ### Event Types
118
185
 
119
- The package supports the following standard event types:
186
+ The package includes common event types for discoverability:
120
187
 
121
188
  - `app_setup` - Initial application setup
122
189
  - `protocol_installed` - Protocol installation
@@ -125,7 +192,7 @@ The package supports the following standard event types:
125
192
  - `data_exported` - Data export
126
193
  - `error` - Error events (use `trackError()` instead)
127
194
 
128
- You can also send custom events with any string name.
195
+ This list is non-exhaustive. `trackEvent` accepts any string as the event name.
129
196
 
130
197
  ### Client-Side API
131
198
 
@@ -134,41 +201,16 @@ You can also send custom events with any string name.
134
201
  Wraps your application to provide analytics context.
135
202
 
136
203
  ```tsx
137
- <AnalyticsProvider config={config}>
138
- {children}
139
- </AnalyticsProvider>
204
+ <AnalyticsProvider config={config}>{children}</AnalyticsProvider>
140
205
  ```
141
206
 
142
- **Config Options:**
207
+ #### `createAnalytics(config)`
143
208
 
144
- ```typescript
145
- interface AnalyticsConfig {
146
- // Required: Unique identifier for this installation
147
- installationId: string;
148
-
149
- // Optional: PostHog API key
150
- // Defaults to a placeholder (authentication handled by the proxy)
151
- apiKey?: string;
152
-
153
- // Optional: PostHog API host
154
- // Hardcoded to "https://ph-relay.networkcanvas.com" by default
155
- // Only override if using a different proxy endpoint
156
- apiHost?: string;
157
-
158
- // Optional: Disable all tracking
159
- disabled?: boolean;
160
-
161
- // Optional: Enable debug mode
162
- debug?: boolean;
163
-
164
- // Optional: PostHog-specific options
165
- posthogOptions?: {
166
- disable_session_recording?: boolean;
167
- autocapture?: boolean;
168
- capture_pageview?: boolean;
169
- // ... other PostHog options
170
- };
171
- }
209
+ Creates a client-side analytics instance directly. Useful for `instrumentation-client.ts`.
210
+
211
+ ```ts
212
+ import { createAnalytics, mergeConfig } from "@codaco/analytics";
213
+ const analytics = createAnalytics(mergeConfig({ app: "Fresco", installationId: "..." }));
172
214
  ```
173
215
 
174
216
  #### `useAnalytics()`
@@ -177,106 +219,49 @@ React hook to access analytics in components.
177
219
 
178
220
  ```tsx
179
221
  const analytics = useAnalytics();
180
-
181
- // Track an event
182
- analytics.trackEvent('protocol_installed', {
183
- metadata: { protocolId: '123', version: '2.0' }
184
- });
185
-
186
- // Track an error
187
- analytics.trackError(error, {
188
- metadata: { context: 'import' }
189
- });
190
-
191
- // Feature flags
192
- const isEnabled = analytics.isFeatureEnabled('new-feature');
193
- const variant = analytics.getFeatureFlag('experiment');
194
- const allFlags = analytics.getFeatureFlags();
222
+ analytics.trackEvent("protocol_installed", { metadata: { protocolId: "123" } });
223
+ analytics.trackError(error, { metadata: { context: "import" } });
224
+ analytics.isFeatureEnabled("new-feature");
225
+ analytics.getFeatureFlag("experiment");
195
226
  analytics.reloadFeatureFlags();
196
-
197
- // User identification (optional, for advanced use cases)
198
- analytics.identify('user-123', { email: 'user@example.com' });
227
+ analytics.identify("user-123", { email: "user@example.com" });
199
228
  analytics.reset();
200
-
201
- // Utilities
202
- analytics.isEnabled(); // Check if analytics is enabled
203
- analytics.getInstallationId(); // Get the installation ID
229
+ analytics.isEnabled();
230
+ analytics.getInstallationId();
204
231
  ```
205
232
 
206
233
  #### `useFeatureFlag(flagKey: string)`
207
234
 
208
235
  React hook for feature flags (returns boolean).
209
236
 
210
- ```tsx
211
- const isNewUIEnabled = useFeatureFlag('new-ui');
212
-
213
- if (isNewUIEnabled) {
214
- return <NewUI />;
215
- }
216
-
217
- return <OldUI />;
218
- ```
219
-
220
237
  #### `useFeatureFlagValue(flagKey: string)`
221
238
 
222
239
  React hook for multivariate feature flags.
223
240
 
224
- ```tsx
225
- const theme = useFeatureFlagValue('theme-experiment');
226
-
227
- return <div className={theme === 'dark' ? 'dark' : 'light'}>
228
- Content
229
- </div>;
230
- ```
231
-
232
241
  ### Server-Side API
233
242
 
234
243
  #### `serverAnalytics`
235
244
 
236
- Pre-configured server-side analytics instance (auto-initializes from env vars).
237
-
238
- ```ts
239
- import { serverAnalytics } from '@codaco/analytics/server';
240
-
241
- serverAnalytics.trackEvent('interview_completed', {
242
- metadata: { duration: 300, completionRate: 0.95 }
243
- });
244
-
245
- serverAnalytics.trackError(error);
246
- ```
245
+ Pre-configured server-side analytics instance (requires `initServerAnalytics()` first).
247
246
 
248
247
  #### `initServerAnalytics(config)`
249
248
 
250
- Initialize server analytics (required before using serverAnalytics).
251
-
252
- ```ts
253
- import { initServerAnalytics, getServerAnalytics } from '@codaco/analytics/server';
249
+ Initialize server analytics. Call once in your app startup.
254
250
 
255
- // In your app startup (e.g., root layout)
256
- initServerAnalytics({
257
- installationId: 'your-unique-installation-id',
258
- // Optional overrides:
259
- // disabled: false,
260
- // debug: true,
261
- });
251
+ #### `getServerAnalytics()`
262
252
 
263
- // Later, in your code
264
- const analytics = getServerAnalytics();
265
- analytics.trackEvent('app_setup');
266
- ```
253
+ Get the server-side analytics instance.
267
254
 
268
- **Note:** Feature flags are **not supported** in server-side mode. Use client-side hooks for feature flags.
255
+ **Note:** Feature flags are **not supported** in server-side mode.
269
256
 
270
257
  ## Configuration
271
258
 
272
259
  ### Default Settings
273
260
 
274
- The package comes with sensible defaults (no environment variables needed):
275
-
276
261
  ```typescript
277
262
  {
278
- apiHost: "https://ph-relay.networkcanvas.com", // Hardcoded
279
- apiKey: "phc_proxy_mode_placeholder", // Placeholder for proxy mode
263
+ apiHost: "https://ph-relay.networkcanvas.com",
264
+ apiKey: "phc_proxy_mode_placeholder",
280
265
  disabled: false,
281
266
  debug: false,
282
267
  posthogOptions: {
@@ -291,172 +276,57 @@ The package comes with sensible defaults (no environment variables needed):
291
276
  }
292
277
  ```
293
278
 
294
- ### Configuration
295
-
296
- All configuration is passed directly via the `config` prop.
297
-
298
- **Environment Variables:**
299
- - `DISABLE_ANALYTICS` or `NEXT_PUBLIC_DISABLE_ANALYTICS` - Set to `"true"` to disable all tracking
300
-
301
- No other environment variables are used (API host and key are hardcoded for proxy mode).
302
-
303
279
  ### Disabling Analytics
304
280
 
305
- Analytics can be disabled in two ways:
281
+ Analytics can be disabled via environment variable or config:
306
282
 
307
- **1. Via environment variable (recommended for development/testing):**
308
283
  ```bash
309
284
  DISABLE_ANALYTICS=true
310
- # or for Next.js client-side
285
+ # or
311
286
  NEXT_PUBLIC_DISABLE_ANALYTICS=true
312
287
  ```
313
288
 
314
- **2. Via config prop:**
315
289
  ```tsx
316
- <AnalyticsProvider config={{
317
- installationId: 'your-id',
318
- disabled: true
319
- }}>
320
- {children}
290
+ <AnalyticsProvider config={{ app: "Fresco", installationId: "...", disabled: true }}>
291
+ {children}
321
292
  </AnalyticsProvider>
322
293
  ```
323
294
 
324
- When disabled (by either method), all analytics methods become no-ops (no tracking occurs).
325
-
326
- ## Feature Flags & A/B Testing
327
-
328
- PostHog feature flags allow you to:
329
-
330
- - Toggle features on/off remotely
331
- - Run A/B tests
332
- - Gradual rollouts
333
- - User targeting
334
-
335
- ### Setting Up Feature Flags
336
-
337
- 1. Create a feature flag in your PostHog dashboard
338
- 2. Use the hooks or API in your code:
339
-
340
- ```tsx
341
- function ExperimentComponent() {
342
- const variant = useFeatureFlagValue('checkout-flow');
343
-
344
- switch (variant) {
345
- case 'variant-a':
346
- return <CheckoutFlowA />;
347
- case 'variant-b':
348
- return <CheckoutFlowB />;
349
- default:
350
- return <CheckoutFlowDefault />;
351
- }
352
- }
353
- ```
354
-
355
- ## Error Tracking
356
-
357
- Errors are automatically enriched with:
358
-
359
- - Error message
360
- - Error name
361
- - Full stack trace
362
- - Cause (if available)
363
- - Any additional metadata you provide
364
-
365
- ```tsx
366
- try {
367
- // Your code
368
- } catch (error) {
369
- trackError(error as Error, {
370
- metadata: {
371
- context: 'data-import',
372
- fileName: 'protocol.json',
373
- attemptNumber: 3,
374
- }
375
- });
376
- }
377
- ```
378
-
379
- ## Migration from Old Analytics
380
-
381
- See [MIGRATION.md](./MIGRATION.md) for a complete migration guide from the old analytics system.
382
-
383
- Quick summary of changes:
384
-
385
- - **Event names**: Now use `snake_case` instead of `PascalCase`
386
- - `AppSetup` → `app_setup`
387
- - `ProtocolInstalled` → `protocol_installed`
388
- - **API**: `makeEventTracker()` → `useAnalytics()` hook
389
- - **Route handler**: No longer needed (PostHog handles everything)
390
- - **Installation ID**: Now set via config instead of route handler
391
-
392
295
  ## Architecture
393
296
 
394
- This package uses a reverse proxy architecture for security and reliability:
395
-
396
297
  ```
397
- ┌─────────────────────┐
398
- React App
399
- (Client)
400
- │ │
401
- useAnalytics()
402
- │ ↓ │
403
- PostHog JS SDK │
404
- (no API key)
405
- └──────────┬──────────┘
406
-
407
- HTTPS
408
-
409
- ┌─────────────────────┐
410
- Cloudflare Worker
411
- (Reverse Proxy)
412
- ph-relay.network
413
- │ canvas.com │
414
-
415
- Injects API key │
416
- │ • Adds CORS │
417
- │ • Bypasses blockers│
418
- └──────────┬──────────┘
419
-
420
- HTTPS + Auth
421
-
422
- ┌─────────────────────┐
423
- │ PostHog Cloud │
424
- │ (US Region) │
425
- │ │
426
- │ Analytics Dashboard│
427
- │ Feature Flags │
428
- │ A/B Testing │
429
- └─────────────────────┘
298
+ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
299
+ Fresco │ Architect-Web │ │ Studio │
300
+ app: "Fresco" │ app: "ArchitectWeb" │ │ app: "Studio" │
301
+ └──────────┬──────────┘ └──────────┬──────────┘ └──────────┬──────────┘
302
+
303
+ └────────────┬───────────┘────────────────────────┘
304
+
305
+ HTTPS (app super property on every event)
306
+
307
+ ┌─────────────────────┐
308
+ Cloudflare Worker │
309
+ │ ph-relay.network │
310
+ │ canvas.com │
311
+ Injects API key
312
+ Adds CORS
313
+ • Bypasses blockers
314
+ └──────────┬──────────┘
315
+
316
+ HTTPS + Auth
317
+
318
+ ┌─────────────────────┐
319
+ │ PostHog Cloud │
320
+ (Single Project) │
321
+ Filter by app prop │
322
+ └─────────────────────┘
430
323
  ```
431
324
 
432
- **Benefits:**
433
- - API key stays secure (server-side only)
434
- - Avoids ad-blockers
435
- - Uses your own domain
436
- - Centralized authentication
437
-
438
- ## Best Practices
439
-
440
- 1. **Always include metadata**: Helps with debugging and analysis
441
- ```ts
442
- trackEvent('data_exported', {
443
- metadata: { format: 'csv', size: 1024, duration: 230 }
444
- });
445
- ```
446
-
447
- 2. **Use typed event names**: Import event types for autocomplete
448
- ```ts
449
- import type { EventType } from '@codaco/analytics';
450
- const event: EventType = 'app_setup';
451
- ```
452
-
453
- 3. **Don't block on analytics**: All calls are non-blocking by design
454
-
455
- 4. **Test with analytics disabled**: Set `NEXT_PUBLIC_DISABLE_ANALYTICS=true`
325
+ ## Troubleshooting
456
326
 
457
- 5. **Use feature flags for gradual rollouts**: Test features with a small percentage of users first
327
+ ### `posthog-js` bundling issues with Turbopack
458
328
 
459
- ## Troubleshooting
329
+ Certain `posthog-js` versions have Turbopack bundling issues when used in `instrumentation-client.ts`. If you encounter `node:child_process` errors, either pin to a compatible `posthog-js` version or fall back to the React Provider pattern.
460
330
 
461
331
  ### Events not appearing in PostHog
462
332
 
@@ -464,8 +334,6 @@ This package uses a reverse proxy architecture for security and reliability:
464
334
  2. Check that the Cloudflare Worker has the `POSTHOG_API_KEY` environment variable set
465
335
  3. Enable debug mode: `debug: true` in config
466
336
  4. Check browser console for errors
467
- 5. Verify PostHog dashboard shows your project
468
- 6. Test the proxy endpoint directly: `curl https://ph-relay.networkcanvas.com`
469
337
 
470
338
  ### Feature flags not working
471
339
 
@@ -474,11 +342,12 @@ This package uses a reverse proxy architecture for security and reliability:
474
342
  3. Reload flags: `analytics.reloadFeatureFlags()`
475
343
  4. Feature flags only work client-side, not in server components
476
344
 
477
- ### TypeScript errors
345
+ ## Migration from v9
478
346
 
479
- 1. Ensure `@types/react` is installed
480
- 2. Check TypeScript version is compatible (>= 5.0)
481
- 3. Rebuild the package: `pnpm build`
347
+ - `app` is a new **required** field on `AnalyticsConfig`. All consuming apps must pass it.
348
+ - `createAnalytics` is now a public export for use in `instrumentation-client.ts`.
349
+ - `AppName` and `appNames` are new exports.
350
+ - Event types are documented as non-exhaustive.
482
351
 
483
352
  ## License
484
353
 
@@ -1,3 +1,18 @@
1
+ // src/utils.ts
2
+ function ensureError(value) {
3
+ if (!value) return new Error("No value was thrown");
4
+ if (value instanceof Error) return value;
5
+ if (Object.prototype.isPrototypeOf.call(value, Error)) return value;
6
+ let stringified = "[Unable to stringify the thrown value]";
7
+ try {
8
+ stringified = JSON.stringify(value);
9
+ } catch (e) {
10
+ console.error(e);
11
+ }
12
+ const error = new Error(`This value was thrown as is, not through an Error: ${stringified}`);
13
+ return error;
14
+ }
15
+
1
16
  // src/config.ts
2
17
  var POSTHOG_PROXY_HOST = "https://ph-relay.networkcanvas.com";
3
18
  var PROXY_MODE_DUMMY_KEY = "phc_proxy_mode_placeholder";
@@ -36,6 +51,7 @@ var defaultConfig = {
36
51
  };
37
52
  function mergeConfig(userConfig) {
38
53
  return {
54
+ app: userConfig.app,
39
55
  apiHost: userConfig.apiHost ?? defaultConfig.apiHost ?? POSTHOG_PROXY_HOST,
40
56
  apiKey: userConfig.apiKey ?? PROXY_MODE_DUMMY_KEY,
41
57
  installationId: userConfig.installationId,
@@ -48,25 +64,10 @@ function mergeConfig(userConfig) {
48
64
  };
49
65
  }
50
66
 
51
- // src/utils.ts
52
- function ensureError(value) {
53
- if (!value) return new Error("No value was thrown");
54
- if (value instanceof Error) return value;
55
- if (Object.prototype.isPrototypeOf.call(value, Error)) return value;
56
- let stringified = "[Unable to stringify the thrown value]";
57
- try {
58
- stringified = JSON.stringify(value);
59
- } catch (e) {
60
- console.error(e);
61
- }
62
- const error = new Error(`This value was thrown as is, not through an Error: ${stringified}`);
63
- return error;
64
- }
65
-
66
67
  export {
68
+ ensureError,
67
69
  isDisabledByEnv,
68
70
  defaultConfig,
69
- mergeConfig,
70
- ensureError
71
+ mergeConfig
71
72
  };
72
- //# sourceMappingURL=chunk-3NEQVIC4.js.map
73
+ //# sourceMappingURL=chunk-TPZBZWEN.js.map