@brizz/sdk 0.1.2-rc.1 → 0.1.2
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 +97 -90
- package/dist/index.cjs +4 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -3
- package/dist/index.d.ts +1 -3
- package/dist/index.js +4 -75
- package/dist/index.js.map +1 -1
- package/dist/loader.mjs +11 -0
- package/dist/preload.cjs +11 -0
- package/dist/preload.cjs.map +1 -1
- package/dist/preload.js +11 -0
- package/dist/preload.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,32 @@
|
|
|
1
1
|
# Brizz SDK
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@brizz/sdk)
|
|
4
|
-
[](https://opensource.org/licenses/Apache-2.0)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
-
OpenTelemetry-based observability SDK for AI applications. Automatically instruments popular AI
|
|
7
|
+
OpenTelemetry-based observability SDK for AI applications. Automatically instruments popular AI
|
|
8
|
+
libraries including OpenAI, Anthropic, Vercel AI SDK, and more.
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Features](#features)
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Quick Start](#quick-start)
|
|
15
|
+
- [CommonJS Projects](#commonjs-projects)
|
|
16
|
+
- [ESM Projects](#esm-projects)
|
|
17
|
+
- [Module System Support](#module-system-support)
|
|
18
|
+
- [Supported Libraries](#supported-libraries)
|
|
19
|
+
- [PII Protection & Data Masking](#pii-protection--data-masking)
|
|
20
|
+
- [Session Tracking](#session-tracking)
|
|
21
|
+
- [Custom Events & Logging](#custom-events--logging)
|
|
22
|
+
- [Environment Variables](#environment-variables)
|
|
23
|
+
- [Advanced Configuration](#advanced-configuration)
|
|
24
|
+
- [Testing & Development](#testing--development)
|
|
25
|
+
- [Package.json Examples](#packagejson-examples)
|
|
26
|
+
- [Examples](#examples)
|
|
27
|
+
- [Troubleshooting](#troubleshooting)
|
|
28
|
+
- [Contributing](#contributing)
|
|
29
|
+
- [License](#license)
|
|
8
30
|
|
|
9
31
|
## Features
|
|
10
32
|
|
|
@@ -27,11 +49,7 @@ pnpm add @brizz/sdk
|
|
|
27
49
|
|
|
28
50
|
## Quick Start
|
|
29
51
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
The preload method automatically initializes the SDK and instruments libraries at startup using Node.js preload hooks.
|
|
33
|
-
|
|
34
|
-
**Environment Variables:**
|
|
52
|
+
First, set up your environment variables:
|
|
35
53
|
```bash
|
|
36
54
|
BRIZZ_API_KEY=your-api-key
|
|
37
55
|
BRIZZ_BASE_URL=https://telemetry.brizz.dev # Optional
|
|
@@ -39,103 +57,103 @@ BRIZZ_APP_NAME=my-app # Optional
|
|
|
39
57
|
BRIZZ_LOG_LEVEL=info # Optional: debug, info, warn, error, none
|
|
40
58
|
```
|
|
41
59
|
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
# Run with ESM preload
|
|
45
|
-
node --import @brizz/sdk/preload your-app.mjs
|
|
46
|
-
```
|
|
60
|
+
### CommonJS Projects
|
|
47
61
|
|
|
48
|
-
**
|
|
62
|
+
**Option 1: Preload Only (Zero Config)**
|
|
49
63
|
```bash
|
|
50
|
-
# Run with CJS preload
|
|
51
64
|
node --require @brizz/sdk/preload your-app.js
|
|
52
65
|
```
|
|
53
66
|
|
|
54
|
-
|
|
55
|
-
```json
|
|
56
|
-
{
|
|
57
|
-
"scripts": {
|
|
58
|
-
"start": "node --import @brizz/sdk/preload src/index.js",
|
|
59
|
-
"dev": "node --import @brizz/sdk/preload --watch src/index.js"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Your application code remains clean:
|
|
65
|
-
```typescript
|
|
67
|
+
```javascript
|
|
66
68
|
// your-app.js - No SDK setup needed!
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
const { generateText } = require('ai');
|
|
70
|
+
const { openai } = require('@ai-sdk/openai');
|
|
69
71
|
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
+
// Libraries are automatically instrumented
|
|
73
|
+
generateText({
|
|
72
74
|
model: openai('gpt-3.5-turbo'),
|
|
73
75
|
prompt: 'Hello, world!',
|
|
74
|
-
});
|
|
76
|
+
}).then(result => console.log(result.text));
|
|
75
77
|
```
|
|
76
78
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
For ESM projects, you can use the ESM loader for automatic instrumentation by using the `--import` flag:
|
|
80
|
-
|
|
79
|
+
**Option 2: Preload + Initialize (Custom Config)**
|
|
81
80
|
```bash
|
|
82
|
-
node --
|
|
81
|
+
node --require @brizz/sdk/preload your-app.js
|
|
83
82
|
```
|
|
84
83
|
|
|
85
|
-
```
|
|
86
|
-
// your-app.
|
|
87
|
-
|
|
84
|
+
```javascript
|
|
85
|
+
// your-app.js - Custom configuration
|
|
86
|
+
const { Brizz } = require('@brizz/sdk');
|
|
88
87
|
|
|
89
|
-
// Initialize SDK
|
|
90
88
|
Brizz.initialize({
|
|
91
89
|
apiKey: 'your-api-key',
|
|
92
90
|
appName: 'my-app',
|
|
91
|
+
// custom config here
|
|
93
92
|
});
|
|
94
93
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
const { generateText } = require('ai');
|
|
95
|
+
// ... rest of your code
|
|
96
|
+
```
|
|
98
97
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
**Option 3: Manual Import + Initialize**
|
|
99
|
+
```javascript
|
|
100
|
+
// Must be first import
|
|
101
|
+
const { Brizz } = require('@brizz/sdk');
|
|
102
|
+
|
|
103
|
+
Brizz.initialize({
|
|
104
|
+
apiKey: 'your-api-key',
|
|
105
|
+
appName: 'my-app',
|
|
102
106
|
});
|
|
107
|
+
|
|
108
|
+
// Import AI libraries after initialization
|
|
109
|
+
const { generateText } = require('ai');
|
|
110
|
+
const { openai } = require('@ai-sdk/openai');
|
|
103
111
|
```
|
|
104
112
|
|
|
105
|
-
###
|
|
113
|
+
### ESM Projects
|
|
106
114
|
|
|
107
|
-
|
|
115
|
+
> ⚠️ **ESM Requirement**: ESM projects **must** use the `--import @brizz/sdk/loader` flag for instrumentation to work. Manual import without the loader will not instrument AI libraries.
|
|
116
|
+
|
|
117
|
+
**Loader + Initialize (Required for ESM)**
|
|
118
|
+
```bash
|
|
119
|
+
node --import @brizz/sdk/loader your-app.mjs
|
|
120
|
+
```
|
|
108
121
|
|
|
109
122
|
```typescript
|
|
123
|
+
// your-app.mjs
|
|
110
124
|
import { Brizz } from '@brizz/sdk';
|
|
111
125
|
|
|
112
|
-
//
|
|
126
|
+
// Must initialize SDK manually in ESM
|
|
113
127
|
Brizz.initialize({
|
|
114
128
|
apiKey: 'your-api-key',
|
|
115
129
|
appName: 'my-app',
|
|
116
|
-
baseUrl: 'https://telemetry.brizz.dev', // Optional
|
|
117
|
-
logLevel: 'info', // Optional: debug, info, warn, error, none
|
|
118
130
|
});
|
|
119
131
|
|
|
120
132
|
// Import AI libraries after initialization
|
|
121
133
|
import { generateText } from 'ai';
|
|
122
134
|
import { openai } from '@ai-sdk/openai';
|
|
135
|
+
|
|
136
|
+
const result = await generateText({
|
|
137
|
+
model: openai('gpt-3.5-turbo'),
|
|
138
|
+
prompt: 'Hello, world!',
|
|
139
|
+
});
|
|
123
140
|
```
|
|
124
141
|
|
|
125
|
-
> **Important**: Initialize Brizz before importing any libraries you want to instrument. If using
|
|
142
|
+
> **Important**: Initialize Brizz before importing any libraries you want to instrument. If using
|
|
143
|
+
> `dotenv`, use `import "dotenv/config"` before importing `@brizz/sdk`.
|
|
126
144
|
|
|
127
145
|
## Module System Support
|
|
128
146
|
|
|
129
|
-
### ESM (ES Modules)
|
|
130
|
-
- **Preload**: `node --import @brizz/sdk/preload app.mjs` ⭐
|
|
131
|
-
- **Loader**: `node --import @brizz/sdk/loader app.mjs`
|
|
132
|
-
- **Manual**: Import and initialize manually
|
|
133
|
-
|
|
134
147
|
### CommonJS
|
|
135
|
-
- **Preload**: `node --require @brizz/sdk/preload app.js` ⭐
|
|
136
|
-
- **Manual**: Require
|
|
148
|
+
- **Preload**: `node --require @brizz/sdk/preload app.js` ⭐ (with optional `Brizz.initialize()`)
|
|
149
|
+
- **Manual**: Require `@brizz/sdk` first, then `Brizz.initialize()`, then AI libraries
|
|
150
|
+
|
|
151
|
+
### ESM (ES Modules)
|
|
152
|
+
- **Loader**: `node --import @brizz/sdk/loader app.mjs` + `Brizz.initialize()` ⭐
|
|
153
|
+
- **Manual**: Import `@brizz/sdk` first, then `Brizz.initialize()`, then AI libraries
|
|
137
154
|
|
|
138
|
-
For Next.js and Webpack environments that don't support automatic instrumentation, use manual
|
|
155
|
+
For Next.js and Webpack environments that don't support automatic instrumentation, use manual
|
|
156
|
+
instrumentation:
|
|
139
157
|
|
|
140
158
|
```typescript
|
|
141
159
|
// For problematic bundlers
|
|
@@ -193,15 +211,8 @@ Brizz.initialize({
|
|
|
193
211
|
});
|
|
194
212
|
```
|
|
195
213
|
|
|
196
|
-
**Built-in PII patterns** automatically detect and mask
|
|
197
|
-
|
|
198
|
-
- Phone numbers
|
|
199
|
-
- Social Security Numbers
|
|
200
|
-
- Credit card numbers
|
|
201
|
-
- API keys (OpenAI, Anthropic, etc.)
|
|
202
|
-
- Cryptocurrency addresses
|
|
203
|
-
- IP addresses
|
|
204
|
-
- And more...
|
|
214
|
+
**Built-in PII patterns** automatically detect and mask emails, phone numbers, SSNs, credit cards,
|
|
215
|
+
API keys, crypto addresses, IPs, and more.
|
|
205
216
|
|
|
206
217
|
## Session Tracking
|
|
207
218
|
|
|
@@ -236,13 +247,13 @@ import { emitEvent, logger } from '@brizz/sdk';
|
|
|
236
247
|
emitEvent('user.signup', {
|
|
237
248
|
userId: '123',
|
|
238
249
|
plan: 'pro',
|
|
239
|
-
source: 'website'
|
|
250
|
+
source: 'website',
|
|
240
251
|
});
|
|
241
252
|
|
|
242
253
|
emitEvent('ai.request.completed', {
|
|
243
254
|
model: 'gpt-4',
|
|
244
255
|
tokens: 150,
|
|
245
|
-
latency: 1200
|
|
256
|
+
latency: 1200,
|
|
246
257
|
});
|
|
247
258
|
|
|
248
259
|
// Structured logging
|
|
@@ -279,7 +290,7 @@ Brizz.initialize({
|
|
|
279
290
|
// Custom headers for authentication
|
|
280
291
|
headers: {
|
|
281
292
|
'X-API-Version': '2024-01',
|
|
282
|
-
'X-Environment': 'production'
|
|
293
|
+
'X-Environment': 'production',
|
|
283
294
|
},
|
|
284
295
|
|
|
285
296
|
// Disable batching for immediate export (testing)
|
|
@@ -293,7 +304,7 @@ Brizz.initialize({
|
|
|
293
304
|
disableNodeSdk: false,
|
|
294
305
|
|
|
295
306
|
// Log level for SDK diagnostics
|
|
296
|
-
logLevel: 'info' // debug, info, warn, error, none
|
|
307
|
+
logLevel: 'info', // debug, info, warn, error, none
|
|
297
308
|
});
|
|
298
309
|
```
|
|
299
310
|
|
|
@@ -309,7 +320,7 @@ const spanExporter = new InMemorySpanExporter();
|
|
|
309
320
|
Brizz.initialize({
|
|
310
321
|
apiKey: 'test-key',
|
|
311
322
|
customSpanExporter: spanExporter,
|
|
312
|
-
logLevel: 'debug'
|
|
323
|
+
logLevel: 'debug',
|
|
313
324
|
});
|
|
314
325
|
|
|
315
326
|
// Later in tests
|
|
@@ -320,34 +331,26 @@ expect(spans[0].name).toBe('openai.chat');
|
|
|
320
331
|
|
|
321
332
|
## Package.json Examples
|
|
322
333
|
|
|
323
|
-
**
|
|
324
|
-
```json
|
|
325
|
-
{
|
|
326
|
-
"type": "module",
|
|
327
|
-
"scripts": {
|
|
328
|
-
"start": "node --import @brizz/sdk/preload src/index.js",
|
|
329
|
-
"dev": "node --import @brizz/sdk/preload --watch src/index.js",
|
|
330
|
-
"debug": "node --import @brizz/sdk/preload --inspect src/index.js"
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
```
|
|
334
|
+
**CommonJS Projects:**
|
|
334
335
|
|
|
335
|
-
**CommonJS with Preload:**
|
|
336
336
|
```json
|
|
337
337
|
{
|
|
338
338
|
"scripts": {
|
|
339
339
|
"start": "node --require @brizz/sdk/preload src/index.js",
|
|
340
|
-
"dev": "node --require @brizz/sdk/preload --watch src/index.js"
|
|
340
|
+
"dev": "node --require @brizz/sdk/preload --watch src/index.js",
|
|
341
|
+
"debug": "node --require @brizz/sdk/preload --inspect src/index.js"
|
|
341
342
|
}
|
|
342
343
|
}
|
|
343
344
|
```
|
|
344
345
|
|
|
345
|
-
**ESM
|
|
346
|
+
**ESM Projects:**
|
|
347
|
+
|
|
346
348
|
```json
|
|
347
349
|
{
|
|
348
350
|
"type": "module",
|
|
349
351
|
"scripts": {
|
|
350
|
-
"start": "node --import @brizz/sdk/loader src/index.js"
|
|
352
|
+
"start": "node --import @brizz/sdk/loader src/index.js",
|
|
353
|
+
"dev": "node --import @brizz/sdk/loader --watch src/index.js"
|
|
351
354
|
}
|
|
352
355
|
}
|
|
353
356
|
```
|
|
@@ -367,15 +370,19 @@ Check out the [examples](./examples/) directory for complete working examples:
|
|
|
367
370
|
### Common Issues
|
|
368
371
|
|
|
369
372
|
**"Could not find declaration file"**
|
|
373
|
+
|
|
370
374
|
- Make sure to build the SDK: `pnpm build`
|
|
371
375
|
- Check that `dist/` contains `.d.ts` files
|
|
372
376
|
|
|
373
377
|
**Instrumentation not working**
|
|
378
|
+
|
|
374
379
|
- Ensure SDK is initialized before importing AI libraries
|
|
375
|
-
- For ESM, use
|
|
380
|
+
- For ESM, use loader + `Brizz.initialize()`
|
|
381
|
+
- For CommonJS, use preload (with optional `Brizz.initialize()`)
|
|
376
382
|
- Check that `BRIZZ_API_KEY` is set
|
|
377
383
|
|
|
378
384
|
**CJS/ESM compatibility issues**
|
|
385
|
+
|
|
379
386
|
- Use dynamic imports in CommonJS: `const ai = await import('ai')`
|
|
380
387
|
- For bundlers, use manual instrumentation with `instrumentModules`
|
|
381
388
|
|
package/dist/index.cjs
CHANGED
|
@@ -47,7 +47,6 @@ __export(src_exports, {
|
|
|
47
47
|
logger: () => logger,
|
|
48
48
|
maskAttributes: () => maskAttributes,
|
|
49
49
|
maskValue: () => maskValue,
|
|
50
|
-
maybeRegisterESMLoader: () => maybeRegisterESMLoader,
|
|
51
50
|
setLogLevel: () => setLogLevel
|
|
52
51
|
});
|
|
53
52
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -1116,19 +1115,19 @@ var VercelAIInstrumentation = class _VercelAIInstrumentation extends import_inst
|
|
|
1116
1115
|
* Manual instrumentation hook for bundlers/Next.js. Applies in-place wrapping
|
|
1117
1116
|
* on the provided module namespace.
|
|
1118
1117
|
*/
|
|
1119
|
-
manuallyInstrument(
|
|
1118
|
+
manuallyInstrument(module2) {
|
|
1120
1119
|
try {
|
|
1121
|
-
const result = this._patchModuleExports(
|
|
1120
|
+
const result = this._patchModuleExports(module2);
|
|
1122
1121
|
if (result !== null) {
|
|
1123
1122
|
logger.debug("Applied manual Vercel AI instrumentation");
|
|
1124
1123
|
this._vercelAiNamespace = result;
|
|
1125
1124
|
return result;
|
|
1126
1125
|
}
|
|
1127
1126
|
logger.warn("Manual Vercel AI instrumentation received invalid module");
|
|
1128
|
-
return
|
|
1127
|
+
return module2;
|
|
1129
1128
|
} catch (error) {
|
|
1130
1129
|
logger.error(`Failed manual Vercel AI instrumentation: ${String(error)}`);
|
|
1131
|
-
return this._vercelAiNamespace ||
|
|
1130
|
+
return this._vercelAiNamespace || module2;
|
|
1132
1131
|
}
|
|
1133
1132
|
}
|
|
1134
1133
|
/**
|
|
@@ -2839,77 +2838,6 @@ function detectRuntime() {
|
|
|
2839
2838
|
};
|
|
2840
2839
|
}
|
|
2841
2840
|
|
|
2842
|
-
// src/node/loader.ts
|
|
2843
|
-
var import_node_module = __toESM(require("module"), 1);
|
|
2844
|
-
var import_import_in_the_middle = require("import-in-the-middle");
|
|
2845
|
-
var import_meta = {};
|
|
2846
|
-
var loaderDebug = (() => {
|
|
2847
|
-
const isDebug = process.env["BRIZZ_ESM_DEBUG"] === "true" || process.env["BRIZZ_LOG_LEVEL"] === "debug";
|
|
2848
|
-
return {
|
|
2849
|
-
log: (msg, data) => {
|
|
2850
|
-
if (!isDebug) {
|
|
2851
|
-
return;
|
|
2852
|
-
}
|
|
2853
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2854
|
-
const dataStr = data ? ` ${JSON.stringify(data)}` : "";
|
|
2855
|
-
console.log(`[${timestamp}] [ESM-LOADER] ${msg}${dataStr}`);
|
|
2856
|
-
},
|
|
2857
|
-
error: (msg, error) => {
|
|
2858
|
-
if (!isDebug) {
|
|
2859
|
-
return;
|
|
2860
|
-
}
|
|
2861
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2862
|
-
const errorStr = error instanceof Error ? ` ${error.message}` : error ? ` ${JSON.stringify(error)}` : "";
|
|
2863
|
-
console.error(`[${timestamp}] [ESM-LOADER] ERROR: ${msg}${errorStr}`);
|
|
2864
|
-
}
|
|
2865
|
-
};
|
|
2866
|
-
})();
|
|
2867
|
-
var LOADER_REGISTERED_KEY = Symbol.for("__brizz_esm_loader_registered__");
|
|
2868
|
-
function checkLoaderAPISupport() {
|
|
2869
|
-
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
2870
|
-
if (major === void 0 || minor === void 0) {
|
|
2871
|
-
loaderDebug.log("Failed to detect Node version, assuming loader API is supported");
|
|
2872
|
-
return true;
|
|
2873
|
-
}
|
|
2874
|
-
const supported = major >= 21 || major === 20 && minor >= 6 || major === 18 && minor >= 19;
|
|
2875
|
-
loaderDebug.log("Loader API support check:", {
|
|
2876
|
-
nodeVersion: `${major}.${minor}`,
|
|
2877
|
-
supportsLoaderAPI: supported
|
|
2878
|
-
});
|
|
2879
|
-
return supported;
|
|
2880
|
-
}
|
|
2881
|
-
function maybeRegisterESMLoader() {
|
|
2882
|
-
if (globalThis[LOADER_REGISTERED_KEY] === true) {
|
|
2883
|
-
loaderDebug.log("ESM loader already registered, skipping");
|
|
2884
|
-
return false;
|
|
2885
|
-
}
|
|
2886
|
-
globalThis[LOADER_REGISTERED_KEY] = true;
|
|
2887
|
-
loaderDebug.log("Starting ESM loader registration...");
|
|
2888
|
-
if (!checkLoaderAPISupport()) {
|
|
2889
|
-
loaderDebug.log("Node.js version does not support loader API, skipping");
|
|
2890
|
-
return false;
|
|
2891
|
-
}
|
|
2892
|
-
try {
|
|
2893
|
-
loaderDebug.log("Creating MessageChannel for import-in-the-middle...");
|
|
2894
|
-
const { addHookMessagePort } = (0, import_import_in_the_middle.createAddHookMessageChannel)();
|
|
2895
|
-
loaderDebug.log("Registering import-in-the-middle/hook.mjs...");
|
|
2896
|
-
import_node_module.default.register("import-in-the-middle/hook.mjs", import_meta.url, {
|
|
2897
|
-
data: { addHookMessagePort },
|
|
2898
|
-
transferList: [addHookMessagePort]
|
|
2899
|
-
});
|
|
2900
|
-
loaderDebug.log("ESM loader successfully registered!");
|
|
2901
|
-
return true;
|
|
2902
|
-
} catch (error) {
|
|
2903
|
-
loaderDebug.error("Failed to register ESM loader:", error);
|
|
2904
|
-
globalThis[LOADER_REGISTERED_KEY] = false;
|
|
2905
|
-
return false;
|
|
2906
|
-
}
|
|
2907
|
-
}
|
|
2908
|
-
if (globalThis[LOADER_REGISTERED_KEY] !== true) {
|
|
2909
|
-
loaderDebug.log("Loader module imported, attempting to register...");
|
|
2910
|
-
maybeRegisterESMLoader();
|
|
2911
|
-
}
|
|
2912
|
-
|
|
2913
2841
|
// src/init.ts
|
|
2914
2842
|
var init_exports = {};
|
|
2915
2843
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -2931,7 +2859,6 @@ var init_exports = {};
|
|
|
2931
2859
|
logger,
|
|
2932
2860
|
maskAttributes,
|
|
2933
2861
|
maskValue,
|
|
2934
|
-
maybeRegisterESMLoader,
|
|
2935
2862
|
setLogLevel
|
|
2936
2863
|
});
|
|
2937
2864
|
//# sourceMappingURL=index.cjs.map
|