
Security News
Crates.io Users Targeted by Phishing Emails
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
@grafana/faro-cli
Advanced tools
A command-line interface for uploading source maps to the Faro source map API using cURL.
npm install --save-dev @grafana/faro-cli
or
yarn add --dev @grafana/faro-cli
The CLI uses cURL under the hood to upload source maps to the Faro API:
npx faro-cli upload \
--endpoint "https://faro-collector-prod-us-east-0.grafana.net" \
--app-id "your-app-id" \
--api-key "your-api-key" \
--stack-id "your-stack-id" \
--bundle-id "your-bundle-id" \
--output-path "./dist" \
--verbose
The CLI will automatically find and upload all .map
files in the specified output directory and its subdirectories. It recursively searches through all folders to find any source map files, so you don't need to specify patterns or worry about nested directory structures.
The Faro API has a 30MB limit for individual file uploads by default. This limit applies to the uncompressed size of the files, regardless of whether compression is used during transmission. The CLI automatically handles this by:
This streaming approach is the same method used by the bundler plugins, ensuring consistent behavior across all upload methods. The CLI intelligently processes files one by one, uploading batches as they reach the size limit, which optimizes the upload process while staying within the API's size limits.
While the --gzip-payload
option can significantly reduce the network transfer size, the original uncompressed file size must still be under the configured size limit to be accepted by the API.
You can customize the maximum upload size using the --max-upload-size
option, which allows you to specify a different size limit in bytes.
The CLI provides two different gzipping options to optimize uploads:
Gzip Contents (-g, --gzip-contents
): Compresses multiple source map files into a tarball before uploading. Files are processed in a streaming fashion, accumulating until reaching the 30MB limit before creating and uploading each tarball. This is useful when uploading multiple files at once.
Gzip Payload (-z, --gzip-payload
): Compresses the HTTP payload itself using gzip content encoding. This can significantly reduce upload size and is especially useful for large source map files.
Example with gzip payload:
npx faro-cli upload \
--endpoint "https://faro-collector-prod-us-east-0.grafana.net" \
--app-id "your-app-id" \
--api-key "your-api-key" \
--stack-id "your-stack-id" \
--bundle-id "your-bundle-id" \
--output-path "./dist" \
--patterns "*.map" \
--gzip-payload \
--verbose
You can use both options together for maximum compression:
npx faro-cli upload \
--endpoint "https://faro-collector-prod-us-east-0.grafana.net" \
--app-id "your-app-id" \
--api-key "your-api-key" \
--stack-id "your-stack-id" \
--bundle-id "your-bundle-id" \
--output-path "./dist" \
--patterns "*.map" \
--gzip-contents \
--gzip-payload \
--verbose
For applications that don't use Webpack or Rollup, or in cases where you need to add the bundle ID to already built JavaScript files, you can use the inject-bundle-id
command:
npx faro-cli inject-bundle-id \
--bundle-id "your-bundle-id" \
--app-name "your-app-name" \
--files "dist/**/*.js" \
--verbose
This command will:
--bundle-id, -b
: The bundle ID to inject (leave blank to generate a random ID)--app-name, -n
: Application name used in the bundle ID snippet--files, -f
: File patterns to match (multiple patterns can be specified)--verbose, -v
: Enable verbose logging--dry-run, -d
: Only print which files would be modified without making changesGenerate a random bundle ID and inject it into all JS files:
npx faro-cli inject-bundle-id \
--app-name "my-app" \
--files "dist/**/*.js" \
--verbose
Do a dry run first to see which files would be modified:
npx faro-cli inject-bundle-id \
--bundle-id "your-bundle-id" \
--app-name "my-app" \
--files "dist/**/*.js" \
--dry-run \
--verbose
When using with the Faro bundler plugins, you can set the skipUpload
option to true
in the plugin configuration to skip uploading source maps during the build process and instead use the CLI to upload them later.
// rollup.config.js
import faroUploader from '@grafana/faro-rollup-plugin';
export default {
// ... other rollup config
plugins: [
// ... other plugins
faroUploader({
// this URL is different from the Faro Collector URL - find this value in the Frontend Observability plugin under "Settings" -> "Source Maps" -> "Configure source map uploads"
endpoint: 'https://faro-api-prod-us-east-0.grafana.net/faro/api/v1',
appName: 'my-app',
appId: 'your-app-id',
apiKey: 'your-api-key',
stackId: 'your-stack-id',
skipUpload: true, // Skip uploading during build
verbose: true,
}),
],
};
Then, after the build, you can upload the source maps using the CLI:
npx faro-cli upload \
--endpoint "https://faro-collector-prod-us-east-0.grafana.net" \
--app-id "your-app-id" \
--api-key "your-api-key" \
--stack-id "your-stack-id" \
--bundle-id env \
--app-name "my-app" \
--output-path "./dist" \
--verbose
Note the use of --bundle-id env
and --app-name "my-app"
to read the bundle ID from the environment variable set by the bundler plugin.
// webpack.config.js
const FaroSourceMapUploaderPlugin = require('@grafana/faro-webpack-plugin');
module.exports = {
// ... other webpack config
plugins: [
// ... other plugins
new FaroSourceMapUploaderPlugin({
endpoint: 'https://faro-api-prod-us-east-0.grafana.net/faro/api/v1',
appName: 'my-app',
appId: 'your-app-id',
apiKey: 'your-api-key',
stackId: 'your-stack-id',
skipUpload: true, // Skip uploading during build
verbose: true,
}),
],
};
If you prefer to use curl directly, you can generate a curl command:
npx faro-cli curl \
--endpoint "https://faro-collector-prod-us-east-0.grafana.net" \
--app-id "your-app-id" \
--api-key "your-api-key" \
--stack-id "your-stack-id" \
--bundle-id "your-bundle-id" \
--file "./dist/main.js.map"
You can also generate a curl command that uses gzip compression:
npx faro-cli curl \
--endpoint "https://faro-collector-prod-us-east-0.grafana.net" \
--app-id "your-app-id" \
--api-key "your-api-key" \
--stack-id "your-stack-id" \
--bundle-id "your-bundle-id" \
--file "./dist/main.js.map" \
--gzip-payload
This will output a curl command that you can copy and run manually.
-e, --endpoint <url>
: Faro API endpoint URL (required) - find this value in the Frontend Observability plugin under Settings -> Source Maps -> Configure source map uploads-a, --app-id <id>
: Faro application ID (required)-k, --api-key <key>
: Faro API key (required)-s, --stack-id <id>
: Faro stack ID (required) - find this value in the Frontend Observability plugin under Settings -> Source Maps -> Configure source map uploads-b, --bundle-id <id>
: Bundle ID (required, can be set to "env" to read from environment variable)-o, --output-path <path>
: Path to the directory containing source maps (required)-n, --app-name <name>
: Application name (used to find bundleId in environment variables)-k, --keep-sourcemaps
: Keep source maps after uploading (default: false)-g, --gzip-contents
: Compress source maps as a tarball before uploading; files are processed in a streaming fashion, accumulating until the size limit (default: false)-z, --gzip-payload
: Gzip the HTTP payload for smaller uploads (default: false)-v, --verbose
: Enable verbose logging (default: false)-r, --recursive
: Recursively search subdirectories for source maps (default: false)-x, --max-upload-size <size>
: Maximum upload size in bytes, default is 30MB. The Faro API has a 30MB limit for individual file uploads by default. In special circumstances, this limit may be changed by contacting Grafana Cloud support.-e, --endpoint <url>
: Faro API endpoint URL (required) - find this value in the Frontend Observability plugin under Settings -> Source Maps -> Configure source map uploads-a, --app-id <id>
: Faro application ID (required)-k, --api-key <key>
: Faro API key (required)-s, --stack-id <id>
: Faro stack ID (required) - find this value in the Frontend Observability plugin under Settings -> Source Maps -> Configure source map uploads-b, --bundle-id <id>
: Bundle ID (required, can be set to "env" to read from environment variable)-f, --file <path>
: Path to the source map file (required)-n, --app-name <name>
: Application name (used to find bundleId in environment variables)-t, --content-type <type>
: Content type for the upload (default: "application/json")-z, --gzip-payload
: Generate a command that gzips the payload (default: false)Apache-2.0
FAQs
CLI for uploading sourcemaps to the Faro source map API
The npm package @grafana/faro-cli receives a total of 253 weekly downloads. As such, @grafana/faro-cli popularity was classified as not popular.
We found that @grafana/faro-cli demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 22 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
Product
Socket now lets you customize pull request alert headers, helping security teams share clear guidance right in PRs to speed reviews and reduce back-and-forth.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.