This repository is a Metric Insights custom script created with @metricinsights/cs-helper.
- Install:
npm install - Build:
npm run build(bundles the script for Metric Insights;dist/is the output)
The npm run build script passes --v7 (either nothing or --v7 for webpack). That selects how the helper and polyfills are wired.
- Runtime: PhantomJS (legacy headless browser).
- Language level: Treat the environment as old ES5-era code. The bundle uses Babel with
targets: "ie 11"and webpacktarget: ["web", "es5"]so syntax is transpiled down, but not every modern API is available or polyfilled. - Polyfills from cs-helper (v6 path): the helper pulls in a small set (e.g.
Object.assign,Array.prototype.find,Promise,String.prototype.includesvia the v6 polyfill entry). Anything beyond that is not guaranteed—avoid newer builtins unless you add your own polyfills or verify they compile and run.
- Runtime: Puppeteer with a current Chromium stack (MI tracks updates).
- Language level: Babel
targets: { chrome: "97" }withuseBuiltIns: "entry"and core-js 3.x, plus webpacktarget: ["web", "es2023"]. You can use modern JavaScript much more freely than on v6; still prefer patterns that match a recent Chromium.
Do not use console.log, console.warn, console.error, or other console methods for output you need to see in Metric Insights. The console may exist, but you typically cannot inspect that output in the MI UI or run logs.
Use one of these instead:
cs.log('message')—csis the exportedcustomScriptobject from@metricinsights/cs-helper(see the scaffolded entry file).customScript.log('message')— same global API MI injects at runtime.- Leveled helper:
import { log, setLogLevel, … } from '@metricinsights/cs-helper/utils'— theloghelper forwards tocustomScript.log(with batching and levels); use this when you want log levels and filtering.
For failures, use cs.error(...) (and cs.result(...) / cs.close() as in the template) so behavior and diagnostics stay visible through MI’s channels.
Use cs.runApiRequest(url, settings?) (or customScript.runApiRequest) for all Metric Insights backend HTTP calls. Do not use raw fetch, XMLHttpRequest, or manual AJAX for normal API access unless you have a rare, documented exception.
- Primary docs: https://help.metricinsights.com/m/API_Access
- Coverage is not complete. Some endpoints/fields/edge-case behaviors may be undocumented; confirm with runtime API responses, your MI instance behavior, and release notes/support when needed.
Metric Insights injects API authentication for you. Each request includes an HTTP header:
token: the script API token (same value ascs.apiToken).
Do not set or replace this header yourself for standard backend calls.
The script token lifetime is configured on the Metric Insights server (administration / security policy). There is no fixed TTL in the client—always treat expiry as server-defined.
In practice, lifetimes are often at least several minutes (commonly not shorter than about 5 minutes), but do not rely on a specific number without confirming your environment.
If the script can run longer than the token remains valid (loops, retries, long waits, batch jobs), you should design explicit token refresh logic:
- Call
GET/api/get_tokenagainst the same instance (full URL:cs.homeSite/customScript.homeSite+api/get_token, with the same URL rules as other backend calls). - Parse the JSON body:
{ token: string; expires: string }— use the newtokenfor subsequent API traffic and useexpires(host-defined format, often a timestamp or ISO string) to decide when to refresh before the next call fails with an auth error.
Wire refresh into your runApiRequest / buildRequest flow (e.g. refresh before long phases, or on 401 if your host returns it). If you are unsure how the refreshed token is applied on each request in your MI version, confirm with Metric Insights documentation or support.
runApiRequest is a wrapper around jQuery.ajax:
| MI build | Runtime | jQuery (ajax) |
|---|---|---|
v6 (no --v7 in npm run build) |
PhantomJS | 1.2.x |
v7 (--v7) |
Puppeteer / Chromium | 3.x |
The optional settings argument uses the same shape as jQuery ajax options: success, error, type, data, contentType, etc., depending on what the MI host merges in.
Backend URLs must target the Metric Insights instance. Build the request URL from cs.homeSite or customScript.homeSite (MI base URL, e.g. https://web:<port>/) plus the API path—do not rely on a bare relative path unless you know the host resolves it correctly.
Example:
const url = cs.homeSite.replace(/\/?$/, '/') + 'api/dataset_data?dataset=1';
cs.runApiRequest(url, {
success: function (data) {
cs.log(JSON.stringify(data));
},
error: function (xhr, status, err) {
cs.error(String(err || status));
},
});You can wrap runApiRequest in a Promise and pass paths relative to homeSite (same rules as above: always resolve the MI base URL correctly).
- Prefer a small
joinHomeAndPath(or equivalent) socs.homeSitewith or without a trailing slash does not get concatenated wrongly withpath. RequestParamsmirrors jQuery ajax fields you use (type,headers,data, …). Spreadparamsinto the second argument, then attachsuccess/errorso the Promise resolves / rejects — otherwise the request never completes the Promise.
import { cs } from '@metricinsights/cs-helper';
export type RequestParams = {
type?: 'GET' | 'POST' | 'PUT' | 'DELETE';
headers?: Record<string, string>;
data?: string;
[p: string]: any;
};
function joinHomeAndPath(path: string): string {
const base = cs.homeSite.replace(/\/?$/, '/');
return base + path.replace(/^\//, '');
}
function buildRequest<T extends {} = any>(
path: string,
params: RequestParams = {},
): Promise<T> {
return new Promise<T>((resolve, reject) => {
cs.runApiRequest(joinHomeAndPath(path), {
...params,
success: (data) => resolve(data as T),
error: (_xhr, _status, err) => {
reject(err != null ? err : new Error(String(_status)));
},
});
});
}- The script must end by calling
cs.close()when work is done (success or controlled failure). - Best practice: schedule
cs.close()insidesetTimeout(..., 500)(e.g. a smallscheduleClose()helper) so Metric Insights can flushcs.result/ logs before teardown. - Safety timeout: keep a maximum execution window by passing
scriptTimeoutin milliseconds (ms) from script parameters and using e.g.setTimeout(..., scriptTimeout)so that if the script never finishes normally, youcs.logand then callcs.close()(again after the usual short delay), avoiding stuck runs.
- Package version: 1.0.0 — description: Generate synthetic data.
- cs-helper version at scaffold time: 0.7.1.
- v7-only build when the project was created with
--v7(seepackage.jsonbuildscript:--v7).
Refer to README.md and src/ for API surface; backend HTTP details for assistants live in this file and .cursor/rules/.