@vercel/analytics 0.1.6-beta.1 → 0.1.7-beta.1

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/index.cjs CHANGED
@@ -20,7 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/generic.ts
21
21
  var generic_exports = {};
22
22
  __export(generic_exports, {
23
- inject: () => inject
23
+ inject: () => inject,
24
+ track: () => track
24
25
  });
25
26
  module.exports = __toCommonJS(generic_exports);
26
27
 
@@ -37,20 +38,62 @@ var initQueue = () => {
37
38
  function isBrowser() {
38
39
  return typeof window !== "undefined";
39
40
  }
40
- function isDevelopment() {
41
+ function detectEnvironment() {
41
42
  if (typeof process === "undefined")
42
- return false;
43
- return process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test";
43
+ return "production";
44
+ if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test")
45
+ return "development";
46
+ return "production";
47
+ }
48
+ function setMode(mode = "auto") {
49
+ if (mode === "auto") {
50
+ window.vam = detectEnvironment();
51
+ }
52
+ window.vam = mode;
53
+ }
54
+ function getMode() {
55
+ return window.vam || "production";
56
+ }
57
+ function isProduction() {
58
+ return getMode() === "production";
59
+ }
60
+ function isDevelopment() {
61
+ return getMode() === "development";
62
+ }
63
+ var removeKey = (key, { [key]: _, ...rest }) => rest;
64
+ function parseProperties(properties, options) {
65
+ let props = properties;
66
+ const errorProperties = [];
67
+ for (const [key, value] of Object.entries(properties)) {
68
+ if (typeof value === "object" && value !== null) {
69
+ if (options.strip) {
70
+ props = removeKey(key, props);
71
+ } else {
72
+ errorProperties.push(key);
73
+ }
74
+ }
75
+ }
76
+ if (errorProperties.length > 0 && !options.strip) {
77
+ throw Error(
78
+ `The following properties are not valid: ${errorProperties.join(
79
+ ", "
80
+ )}. Only strings, numbers, booleans, and null are allowed.`
81
+ );
82
+ }
83
+ return props;
44
84
  }
45
85
 
46
86
  // src/generic.ts
47
- var inject = ({ beforeSend, debug } = { debug: isDevelopment() }) => {
87
+ var inject = (props = {
88
+ debug: true
89
+ }) => {
48
90
  var _a;
49
91
  if (!isBrowser())
50
92
  return;
93
+ setMode(props.mode);
51
94
  initQueue();
52
- if (beforeSend) {
53
- (_a = window.va) == null ? void 0 : _a.call(window, "beforeSend", beforeSend);
95
+ if (props.beforeSend) {
96
+ (_a = window.va) == null ? void 0 : _a.call(window, "beforeSend", props.beforeSend);
54
97
  }
55
98
  const src = isDevelopment() ? "https://cdn.vercel-insights.com/v1/script.debug.js" : "/_vercel/insights/script.js";
56
99
  if (document.head.querySelector(`script[src*="${src}"]`))
@@ -58,13 +101,34 @@ var inject = ({ beforeSend, debug } = { debug: isDevelopment() }) => {
58
101
  const script = document.createElement("script");
59
102
  script.src = src;
60
103
  script.defer = true;
61
- if (isDevelopment() && debug === false) {
104
+ if (isDevelopment() && props.debug === false) {
62
105
  script.setAttribute("data-debug", "false");
63
106
  }
64
107
  document.head.appendChild(script);
65
108
  };
109
+ var track = (name, properties) => {
110
+ var _a, _b;
111
+ if (!properties) {
112
+ (_a = window.va) == null ? void 0 : _a.call(window, "track", { name });
113
+ return;
114
+ }
115
+ try {
116
+ const props = parseProperties(properties, {
117
+ strip: isProduction()
118
+ });
119
+ (_b = window.va) == null ? void 0 : _b.call(window, "track", {
120
+ name,
121
+ data: props
122
+ });
123
+ } catch (err) {
124
+ if (err instanceof Error && isDevelopment()) {
125
+ console.error(err);
126
+ }
127
+ }
128
+ };
66
129
  // Annotate the CommonJS export names for ESM import in node:
67
130
  0 && (module.exports = {
68
- inject
131
+ inject,
132
+ track
69
133
  });
70
134
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/generic.ts","../src/queue.ts","../src/utils.ts"],"sourcesContent":["import { initQueue } from './queue';\nimport type { AnalyticsProps } from './types';\nimport { isBrowser, isDevelopment } from './utils';\n\nexport const inject = (\n { beforeSend, debug }: AnalyticsProps = { debug: isDevelopment() },\n): void => {\n if (!isBrowser()) return;\n initQueue();\n\n if (beforeSend) {\n window.va?.('beforeSend', beforeSend);\n }\n const src = isDevelopment()\n ? 'https://cdn.vercel-insights.com/v1/script.debug.js'\n : '/_vercel/insights/script.js';\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return;\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n\n if (isDevelopment() && debug === false) {\n script.setAttribute('data-debug', 'false');\n }\n\n document.head.appendChild(script);\n};\n","export const initQueue = (): void => {\n // initialise va until script is loaded\n if (window.va) return;\n\n window.va = function a(...params): void {\n (window.vaq = window.vaq || []).push(params);\n };\n};\n","export function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nexport function isDevelopment(): boolean {\n if (typeof process === 'undefined') return false;\n return (\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,YAAY,MAAY;AAEnC,MAAI,OAAO;AAAI;AAEf,SAAO,KAAK,SAAS,KAAK,QAAc;AACtC,KAAC,OAAO,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM;AAAA,EAC7C;AACF;;;ACPO,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW;AAC3B;AAEO,SAAS,gBAAyB;AACvC,MAAI,OAAO,YAAY;AAAa,WAAO;AAC3C,SACE,QAAQ,IAAI,aAAa,iBAAiB,QAAQ,IAAI,aAAa;AAEvE;;;AFLO,IAAM,SAAS,CACpB,EAAE,YAAY,MAAM,IAAoB,EAAE,OAAO,cAAc,EAAE,MACxD;AANX;AAOE,MAAI,CAAC,UAAU;AAAG;AAClB,YAAU;AAEV,MAAI,YAAY;AACd,iBAAO,OAAP,gCAAY,cAAc;AAAA,EAC5B;AACA,QAAM,MAAM,cAAc,IACtB,uDACA;AAEJ,MAAI,SAAS,KAAK,cAAc,gBAAgB,OAAO;AAAG;AAE1D,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,SAAO,QAAQ;AAEf,MAAI,cAAc,KAAK,UAAU,OAAO;AACtC,WAAO,aAAa,cAAc,OAAO;AAAA,EAC3C;AAEA,WAAS,KAAK,YAAY,MAAM;AAClC;","names":[]}
1
+ {"version":3,"sources":["../src/generic.ts","../src/queue.ts","../src/utils.ts"],"sourcesContent":["import { initQueue } from './queue';\nimport type { AllowedPropertyValues, AnalyticsProps } from './types';\nimport {\n isBrowser,\n parseProperties,\n setMode,\n isDevelopment,\n isProduction,\n} from './utils';\n\nexport const inject = (\n props: AnalyticsProps = {\n debug: true,\n },\n): void => {\n if (!isBrowser()) return;\n\n setMode(props.mode);\n\n initQueue();\n\n if (props.beforeSend) {\n window.va?.('beforeSend', props.beforeSend);\n }\n\n const src = isDevelopment()\n ? 'https://cdn.vercel-insights.com/v1/script.debug.js'\n : '/_vercel/insights/script.js';\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return;\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n\n if (isDevelopment() && props.debug === false) {\n script.setAttribute('data-debug', 'false');\n }\n\n document.head.appendChild(script);\n};\n\nexport const track = (\n name: string,\n properties?: Record<string, AllowedPropertyValues>,\n): void => {\n if (!properties) {\n window.va?.('track', { name });\n return;\n }\n\n try {\n const props = parseProperties(properties, {\n strip: isProduction(),\n });\n\n window.va?.('track', {\n name,\n data: props,\n });\n } catch (err) {\n if (err instanceof Error && isDevelopment()) {\n // eslint-disable-next-line no-console\n console.error(err);\n }\n }\n};\n","export const initQueue = (): void => {\n // initialize va until script is loaded\n if (window.va) return;\n\n window.va = function a(...params): void {\n (window.vaq = window.vaq || []).push(params);\n };\n};\n","import type { AllowedPropertyValues, Mode } from './types';\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nfunction detectEnvironment(): 'development' | 'production' {\n if (typeof process === 'undefined') return 'production';\n\n if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test')\n return 'development';\n\n return 'production';\n}\n\nexport function setMode(mode: Mode = 'auto'): void {\n if (mode === 'auto') {\n window.vam = detectEnvironment();\n }\n\n window.vam = mode;\n}\n\nexport function getMode(): Mode {\n return window.vam || 'production';\n}\n\nexport function isProduction(): boolean {\n return getMode() === 'production';\n}\n\nexport function isDevelopment(): boolean {\n return getMode() === 'development';\n}\n\nconst removeKey = (key: string, { [key]: _, ...rest }): Record<string, any> =>\n rest;\n\nexport function parseProperties(\n properties: Record<string, unknown>,\n options: {\n strip?: boolean;\n },\n): Error | Record<string, AllowedPropertyValues> | undefined {\n let props = properties;\n const errorProperties: string[] = [];\n for (const [key, value] of Object.entries(properties)) {\n if (typeof value === 'object' && value !== null) {\n if (options.strip) {\n props = removeKey(key, props);\n } else {\n errorProperties.push(key);\n }\n }\n }\n\n if (errorProperties.length > 0 && !options.strip) {\n throw Error(\n `The following properties are not valid: ${errorProperties.join(\n ', ',\n )}. Only strings, numbers, booleans, and null are allowed.`,\n );\n }\n return props as Record<string, AllowedPropertyValues>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,YAAY,MAAY;AAEnC,MAAI,OAAO;AAAI;AAEf,SAAO,KAAK,SAAS,KAAK,QAAc;AACtC,KAAC,OAAO,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM;AAAA,EAC7C;AACF;;;ACLO,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW;AAC3B;AAEA,SAAS,oBAAkD;AACzD,MAAI,OAAO,YAAY;AAAa,WAAO;AAE3C,MAAI,QAAQ,IAAI,aAAa,iBAAiB,QAAQ,IAAI,aAAa;AACrE,WAAO;AAET,SAAO;AACT;AAEO,SAAS,QAAQ,OAAa,QAAc;AACjD,MAAI,SAAS,QAAQ;AACnB,WAAO,MAAM,kBAAkB;AAAA,EACjC;AAEA,SAAO,MAAM;AACf;AAEO,SAAS,UAAgB;AAC9B,SAAO,OAAO,OAAO;AACvB;AAEO,SAAS,eAAwB;AACtC,SAAO,QAAQ,MAAM;AACvB;AAEO,SAAS,gBAAyB;AACvC,SAAO,QAAQ,MAAM;AACvB;AAEA,IAAM,YAAY,CAAC,KAAa,GAAG,MAAM,MAAM,KAAK,MAClD;AAEK,SAAS,gBACd,YACA,SAG2D;AAC3D,MAAI,QAAQ;AACZ,QAAM,kBAA4B,CAAC;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,QAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAI,QAAQ,OAAO;AACjB,gBAAQ,UAAU,KAAK,KAAK;AAAA,MAC9B,OAAO;AACL,wBAAgB,KAAK,GAAG;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,gBAAgB,SAAS,KAAK,CAAC,QAAQ,OAAO;AAChD,UAAM;AAAA,MACJ,2CAA2C,gBAAgB;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;AFtDO,IAAM,SAAS,CACpB,QAAwB;AAAA,EACtB,OAAO;AACT,MACS;AAdX;AAeE,MAAI,CAAC,UAAU;AAAG;AAElB,UAAQ,MAAM,IAAI;AAElB,YAAU;AAEV,MAAI,MAAM,YAAY;AACpB,iBAAO,OAAP,gCAAY,cAAc,MAAM;AAAA,EAClC;AAEA,QAAM,MAAM,cAAc,IACtB,uDACA;AAEJ,MAAI,SAAS,KAAK,cAAc,gBAAgB,OAAO;AAAG;AAE1D,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,SAAO,QAAQ;AAEf,MAAI,cAAc,KAAK,MAAM,UAAU,OAAO;AAC5C,WAAO,aAAa,cAAc,OAAO;AAAA,EAC3C;AAEA,WAAS,KAAK,YAAY,MAAM;AAClC;AAEO,IAAM,QAAQ,CACnB,MACA,eACS;AA7CX;AA8CE,MAAI,CAAC,YAAY;AACf,iBAAO,OAAP,gCAAY,SAAS,EAAE,KAAK;AAC5B;AAAA,EACF;AAEA,MAAI;AACF,UAAM,QAAQ,gBAAgB,YAAY;AAAA,MACxC,OAAO,aAAa;AAAA,IACtB,CAAC;AAED,iBAAO,OAAP,gCAAY,SAAS;AAAA,MACnB;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF,SAAS,KAAP;AACA,QAAI,eAAe,SAAS,cAAc,GAAG;AAE3C,cAAQ,MAAM,GAAG;AAAA,IACnB;AAAA,EACF;AACF;","names":[]}
package/dist/index.d.ts CHANGED
@@ -2,20 +2,25 @@ interface PageViewEvent {
2
2
  type: 'pageview';
3
3
  url: string;
4
4
  }
5
- declare type IEvent = PageViewEvent;
6
- declare type BeforeSend = (event: IEvent) => IEvent | null;
5
+ declare type Event = PageViewEvent;
6
+ declare type Mode = 'auto' | 'development' | 'production';
7
+ declare type AllowedPropertyValues = string | number | boolean | null;
8
+ declare type BeforeSend = (event: Event) => Event | null;
7
9
  interface AnalyticsProps {
8
10
  beforeSend?: BeforeSend;
9
11
  debug?: boolean;
12
+ mode?: Mode;
10
13
  }
11
14
  declare global {
12
15
  interface Window {
13
16
  va?: (event: string, properties?: unknown) => void;
14
17
  vaq?: [string, unknown?][];
15
18
  vai?: boolean;
19
+ vam?: Mode;
16
20
  }
17
21
  }
18
22
 
19
- declare const inject: ({ beforeSend, debug }?: AnalyticsProps) => void;
23
+ declare const inject: (props?: AnalyticsProps) => void;
24
+ declare const track: (name: string, properties?: Record<string, AllowedPropertyValues>) => void;
20
25
 
21
- export { inject };
26
+ export { inject, track };
package/dist/index.js CHANGED
@@ -11,20 +11,62 @@ var initQueue = () => {
11
11
  function isBrowser() {
12
12
  return typeof window !== "undefined";
13
13
  }
14
- function isDevelopment() {
14
+ function detectEnvironment() {
15
15
  if (typeof process === "undefined")
16
- return false;
17
- return process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test";
16
+ return "production";
17
+ if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test")
18
+ return "development";
19
+ return "production";
20
+ }
21
+ function setMode(mode = "auto") {
22
+ if (mode === "auto") {
23
+ window.vam = detectEnvironment();
24
+ }
25
+ window.vam = mode;
26
+ }
27
+ function getMode() {
28
+ return window.vam || "production";
29
+ }
30
+ function isProduction() {
31
+ return getMode() === "production";
32
+ }
33
+ function isDevelopment() {
34
+ return getMode() === "development";
35
+ }
36
+ var removeKey = (key, { [key]: _, ...rest }) => rest;
37
+ function parseProperties(properties, options) {
38
+ let props = properties;
39
+ const errorProperties = [];
40
+ for (const [key, value] of Object.entries(properties)) {
41
+ if (typeof value === "object" && value !== null) {
42
+ if (options.strip) {
43
+ props = removeKey(key, props);
44
+ } else {
45
+ errorProperties.push(key);
46
+ }
47
+ }
48
+ }
49
+ if (errorProperties.length > 0 && !options.strip) {
50
+ throw Error(
51
+ `The following properties are not valid: ${errorProperties.join(
52
+ ", "
53
+ )}. Only strings, numbers, booleans, and null are allowed.`
54
+ );
55
+ }
56
+ return props;
18
57
  }
19
58
 
20
59
  // src/generic.ts
21
- var inject = ({ beforeSend, debug } = { debug: isDevelopment() }) => {
60
+ var inject = (props = {
61
+ debug: true
62
+ }) => {
22
63
  var _a;
23
64
  if (!isBrowser())
24
65
  return;
66
+ setMode(props.mode);
25
67
  initQueue();
26
- if (beforeSend) {
27
- (_a = window.va) == null ? void 0 : _a.call(window, "beforeSend", beforeSend);
68
+ if (props.beforeSend) {
69
+ (_a = window.va) == null ? void 0 : _a.call(window, "beforeSend", props.beforeSend);
28
70
  }
29
71
  const src = isDevelopment() ? "https://cdn.vercel-insights.com/v1/script.debug.js" : "/_vercel/insights/script.js";
30
72
  if (document.head.querySelector(`script[src*="${src}"]`))
@@ -32,12 +74,33 @@ var inject = ({ beforeSend, debug } = { debug: isDevelopment() }) => {
32
74
  const script = document.createElement("script");
33
75
  script.src = src;
34
76
  script.defer = true;
35
- if (isDevelopment() && debug === false) {
77
+ if (isDevelopment() && props.debug === false) {
36
78
  script.setAttribute("data-debug", "false");
37
79
  }
38
80
  document.head.appendChild(script);
39
81
  };
82
+ var track = (name, properties) => {
83
+ var _a, _b;
84
+ if (!properties) {
85
+ (_a = window.va) == null ? void 0 : _a.call(window, "track", { name });
86
+ return;
87
+ }
88
+ try {
89
+ const props = parseProperties(properties, {
90
+ strip: isProduction()
91
+ });
92
+ (_b = window.va) == null ? void 0 : _b.call(window, "track", {
93
+ name,
94
+ data: props
95
+ });
96
+ } catch (err) {
97
+ if (err instanceof Error && isDevelopment()) {
98
+ console.error(err);
99
+ }
100
+ }
101
+ };
40
102
  export {
41
- inject
103
+ inject,
104
+ track
42
105
  };
43
106
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/queue.ts","../src/utils.ts","../src/generic.ts"],"sourcesContent":["export const initQueue = (): void => {\n // initialise va until script is loaded\n if (window.va) return;\n\n window.va = function a(...params): void {\n (window.vaq = window.vaq || []).push(params);\n };\n};\n","export function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nexport function isDevelopment(): boolean {\n if (typeof process === 'undefined') return false;\n return (\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'\n );\n}\n","import { initQueue } from './queue';\nimport type { AnalyticsProps } from './types';\nimport { isBrowser, isDevelopment } from './utils';\n\nexport const inject = (\n { beforeSend, debug }: AnalyticsProps = { debug: isDevelopment() },\n): void => {\n if (!isBrowser()) return;\n initQueue();\n\n if (beforeSend) {\n window.va?.('beforeSend', beforeSend);\n }\n const src = isDevelopment()\n ? 'https://cdn.vercel-insights.com/v1/script.debug.js'\n : '/_vercel/insights/script.js';\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return;\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n\n if (isDevelopment() && debug === false) {\n script.setAttribute('data-debug', 'false');\n }\n\n document.head.appendChild(script);\n};\n"],"mappings":";AAAO,IAAM,YAAY,MAAY;AAEnC,MAAI,OAAO;AAAI;AAEf,SAAO,KAAK,SAAS,KAAK,QAAc;AACtC,KAAC,OAAO,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM;AAAA,EAC7C;AACF;;;ACPO,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW;AAC3B;AAEO,SAAS,gBAAyB;AACvC,MAAI,OAAO,YAAY;AAAa,WAAO;AAC3C,SACE,QAAQ,IAAI,aAAa,iBAAiB,QAAQ,IAAI,aAAa;AAEvE;;;ACLO,IAAM,SAAS,CACpB,EAAE,YAAY,MAAM,IAAoB,EAAE,OAAO,cAAc,EAAE,MACxD;AANX;AAOE,MAAI,CAAC,UAAU;AAAG;AAClB,YAAU;AAEV,MAAI,YAAY;AACd,iBAAO,OAAP,gCAAY,cAAc;AAAA,EAC5B;AACA,QAAM,MAAM,cAAc,IACtB,uDACA;AAEJ,MAAI,SAAS,KAAK,cAAc,gBAAgB,OAAO;AAAG;AAE1D,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,SAAO,QAAQ;AAEf,MAAI,cAAc,KAAK,UAAU,OAAO;AACtC,WAAO,aAAa,cAAc,OAAO;AAAA,EAC3C;AAEA,WAAS,KAAK,YAAY,MAAM;AAClC;","names":[]}
1
+ {"version":3,"sources":["../src/queue.ts","../src/utils.ts","../src/generic.ts"],"sourcesContent":["export const initQueue = (): void => {\n // initialize va until script is loaded\n if (window.va) return;\n\n window.va = function a(...params): void {\n (window.vaq = window.vaq || []).push(params);\n };\n};\n","import type { AllowedPropertyValues, Mode } from './types';\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nfunction detectEnvironment(): 'development' | 'production' {\n if (typeof process === 'undefined') return 'production';\n\n if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test')\n return 'development';\n\n return 'production';\n}\n\nexport function setMode(mode: Mode = 'auto'): void {\n if (mode === 'auto') {\n window.vam = detectEnvironment();\n }\n\n window.vam = mode;\n}\n\nexport function getMode(): Mode {\n return window.vam || 'production';\n}\n\nexport function isProduction(): boolean {\n return getMode() === 'production';\n}\n\nexport function isDevelopment(): boolean {\n return getMode() === 'development';\n}\n\nconst removeKey = (key: string, { [key]: _, ...rest }): Record<string, any> =>\n rest;\n\nexport function parseProperties(\n properties: Record<string, unknown>,\n options: {\n strip?: boolean;\n },\n): Error | Record<string, AllowedPropertyValues> | undefined {\n let props = properties;\n const errorProperties: string[] = [];\n for (const [key, value] of Object.entries(properties)) {\n if (typeof value === 'object' && value !== null) {\n if (options.strip) {\n props = removeKey(key, props);\n } else {\n errorProperties.push(key);\n }\n }\n }\n\n if (errorProperties.length > 0 && !options.strip) {\n throw Error(\n `The following properties are not valid: ${errorProperties.join(\n ', ',\n )}. Only strings, numbers, booleans, and null are allowed.`,\n );\n }\n return props as Record<string, AllowedPropertyValues>;\n}\n","import { initQueue } from './queue';\nimport type { AllowedPropertyValues, AnalyticsProps } from './types';\nimport {\n isBrowser,\n parseProperties,\n setMode,\n isDevelopment,\n isProduction,\n} from './utils';\n\nexport const inject = (\n props: AnalyticsProps = {\n debug: true,\n },\n): void => {\n if (!isBrowser()) return;\n\n setMode(props.mode);\n\n initQueue();\n\n if (props.beforeSend) {\n window.va?.('beforeSend', props.beforeSend);\n }\n\n const src = isDevelopment()\n ? 'https://cdn.vercel-insights.com/v1/script.debug.js'\n : '/_vercel/insights/script.js';\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return;\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n\n if (isDevelopment() && props.debug === false) {\n script.setAttribute('data-debug', 'false');\n }\n\n document.head.appendChild(script);\n};\n\nexport const track = (\n name: string,\n properties?: Record<string, AllowedPropertyValues>,\n): void => {\n if (!properties) {\n window.va?.('track', { name });\n return;\n }\n\n try {\n const props = parseProperties(properties, {\n strip: isProduction(),\n });\n\n window.va?.('track', {\n name,\n data: props,\n });\n } catch (err) {\n if (err instanceof Error && isDevelopment()) {\n // eslint-disable-next-line no-console\n console.error(err);\n }\n }\n};\n"],"mappings":";AAAO,IAAM,YAAY,MAAY;AAEnC,MAAI,OAAO;AAAI;AAEf,SAAO,KAAK,SAAS,KAAK,QAAc;AACtC,KAAC,OAAO,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM;AAAA,EAC7C;AACF;;;ACLO,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW;AAC3B;AAEA,SAAS,oBAAkD;AACzD,MAAI,OAAO,YAAY;AAAa,WAAO;AAE3C,MAAI,QAAQ,IAAI,aAAa,iBAAiB,QAAQ,IAAI,aAAa;AACrE,WAAO;AAET,SAAO;AACT;AAEO,SAAS,QAAQ,OAAa,QAAc;AACjD,MAAI,SAAS,QAAQ;AACnB,WAAO,MAAM,kBAAkB;AAAA,EACjC;AAEA,SAAO,MAAM;AACf;AAEO,SAAS,UAAgB;AAC9B,SAAO,OAAO,OAAO;AACvB;AAEO,SAAS,eAAwB;AACtC,SAAO,QAAQ,MAAM;AACvB;AAEO,SAAS,gBAAyB;AACvC,SAAO,QAAQ,MAAM;AACvB;AAEA,IAAM,YAAY,CAAC,KAAa,GAAG,MAAM,MAAM,KAAK,MAClD;AAEK,SAAS,gBACd,YACA,SAG2D;AAC3D,MAAI,QAAQ;AACZ,QAAM,kBAA4B,CAAC;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,QAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAI,QAAQ,OAAO;AACjB,gBAAQ,UAAU,KAAK,KAAK;AAAA,MAC9B,OAAO;AACL,wBAAgB,KAAK,GAAG;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,gBAAgB,SAAS,KAAK,CAAC,QAAQ,OAAO;AAChD,UAAM;AAAA,MACJ,2CAA2C,gBAAgB;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACtDO,IAAM,SAAS,CACpB,QAAwB;AAAA,EACtB,OAAO;AACT,MACS;AAdX;AAeE,MAAI,CAAC,UAAU;AAAG;AAElB,UAAQ,MAAM,IAAI;AAElB,YAAU;AAEV,MAAI,MAAM,YAAY;AACpB,iBAAO,OAAP,gCAAY,cAAc,MAAM;AAAA,EAClC;AAEA,QAAM,MAAM,cAAc,IACtB,uDACA;AAEJ,MAAI,SAAS,KAAK,cAAc,gBAAgB,OAAO;AAAG;AAE1D,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,SAAO,QAAQ;AAEf,MAAI,cAAc,KAAK,MAAM,UAAU,OAAO;AAC5C,WAAO,aAAa,cAAc,OAAO;AAAA,EAC3C;AAEA,WAAS,KAAK,YAAY,MAAM;AAClC;AAEO,IAAM,QAAQ,CACnB,MACA,eACS;AA7CX;AA8CE,MAAI,CAAC,YAAY;AACf,iBAAO,OAAP,gCAAY,SAAS,EAAE,KAAK;AAC5B;AAAA,EACF;AAEA,MAAI;AACF,UAAM,QAAQ,gBAAgB,YAAY;AAAA,MACxC,OAAO,aAAa;AAAA,IACtB,CAAC;AAED,iBAAO,OAAP,gCAAY,SAAS;AAAA,MACnB;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF,SAAS,KAAP;AACA,QAAI,eAAe,SAAS,cAAc,GAAG;AAE3C,cAAQ,MAAM,GAAG;AAAA,IACnB;AAAA,EACF;AACF;","names":[]}
@@ -20,7 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/react.tsx
21
21
  var react_exports = {};
22
22
  __export(react_exports, {
23
- Analytics: () => Analytics
23
+ Analytics: () => Analytics,
24
+ track: () => track
24
25
  });
25
26
  module.exports = __toCommonJS(react_exports);
26
27
  var import_react = require("react");
@@ -38,20 +39,62 @@ var initQueue = () => {
38
39
  function isBrowser() {
39
40
  return typeof window !== "undefined";
40
41
  }
41
- function isDevelopment() {
42
+ function detectEnvironment() {
42
43
  if (typeof process === "undefined")
43
- return false;
44
- return process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test";
44
+ return "production";
45
+ if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test")
46
+ return "development";
47
+ return "production";
48
+ }
49
+ function setMode(mode = "auto") {
50
+ if (mode === "auto") {
51
+ window.vam = detectEnvironment();
52
+ }
53
+ window.vam = mode;
54
+ }
55
+ function getMode() {
56
+ return window.vam || "production";
57
+ }
58
+ function isProduction() {
59
+ return getMode() === "production";
60
+ }
61
+ function isDevelopment() {
62
+ return getMode() === "development";
63
+ }
64
+ var removeKey = (key, { [key]: _, ...rest }) => rest;
65
+ function parseProperties(properties, options) {
66
+ let props = properties;
67
+ const errorProperties = [];
68
+ for (const [key, value] of Object.entries(properties)) {
69
+ if (typeof value === "object" && value !== null) {
70
+ if (options.strip) {
71
+ props = removeKey(key, props);
72
+ } else {
73
+ errorProperties.push(key);
74
+ }
75
+ }
76
+ }
77
+ if (errorProperties.length > 0 && !options.strip) {
78
+ throw Error(
79
+ `The following properties are not valid: ${errorProperties.join(
80
+ ", "
81
+ )}. Only strings, numbers, booleans, and null are allowed.`
82
+ );
83
+ }
84
+ return props;
45
85
  }
46
86
 
47
87
  // src/generic.ts
48
- var inject = ({ beforeSend, debug } = { debug: isDevelopment() }) => {
88
+ var inject = (props = {
89
+ debug: true
90
+ }) => {
49
91
  var _a;
50
92
  if (!isBrowser())
51
93
  return;
94
+ setMode(props.mode);
52
95
  initQueue();
53
- if (beforeSend) {
54
- (_a = window.va) == null ? void 0 : _a.call(window, "beforeSend", beforeSend);
96
+ if (props.beforeSend) {
97
+ (_a = window.va) == null ? void 0 : _a.call(window, "beforeSend", props.beforeSend);
55
98
  }
56
99
  const src = isDevelopment() ? "https://cdn.vercel-insights.com/v1/script.debug.js" : "/_vercel/insights/script.js";
57
100
  if (document.head.querySelector(`script[src*="${src}"]`))
@@ -59,24 +102,46 @@ var inject = ({ beforeSend, debug } = { debug: isDevelopment() }) => {
59
102
  const script = document.createElement("script");
60
103
  script.src = src;
61
104
  script.defer = true;
62
- if (isDevelopment() && debug === false) {
105
+ if (isDevelopment() && props.debug === false) {
63
106
  script.setAttribute("data-debug", "false");
64
107
  }
65
108
  document.head.appendChild(script);
66
109
  };
110
+ var track = (name, properties) => {
111
+ var _a, _b;
112
+ if (!properties) {
113
+ (_a = window.va) == null ? void 0 : _a.call(window, "track", { name });
114
+ return;
115
+ }
116
+ try {
117
+ const props = parseProperties(properties, {
118
+ strip: isProduction()
119
+ });
120
+ (_b = window.va) == null ? void 0 : _b.call(window, "track", {
121
+ name,
122
+ data: props
123
+ });
124
+ } catch (err) {
125
+ if (err instanceof Error && isDevelopment()) {
126
+ console.error(err);
127
+ }
128
+ }
129
+ };
67
130
 
68
131
  // src/react.tsx
69
132
  function Analytics({
70
133
  beforeSend,
71
- debug = isDevelopment()
134
+ debug = true,
135
+ mode = "auto"
72
136
  }) {
73
137
  (0, import_react.useEffect)(() => {
74
- inject({ beforeSend, debug });
75
- }, [beforeSend, debug]);
138
+ inject({ beforeSend, debug, mode });
139
+ }, [beforeSend, debug, mode]);
76
140
  return null;
77
141
  }
78
142
  // Annotate the CommonJS export names for ESM import in node:
79
143
  0 && (module.exports = {
80
- Analytics
144
+ Analytics,
145
+ track
81
146
  });
82
147
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react.tsx","../../src/queue.ts","../../src/utils.ts","../../src/generic.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { inject } from './generic';\nimport type { AnalyticsProps } from './types';\nimport { isDevelopment } from './utils';\n\nexport function Analytics({\n beforeSend,\n debug = isDevelopment(),\n}: AnalyticsProps): null {\n useEffect(() => {\n inject({ beforeSend, debug });\n }, [beforeSend, debug]);\n\n return null;\n}\n","export const initQueue = (): void => {\n // initialise va until script is loaded\n if (window.va) return;\n\n window.va = function a(...params): void {\n (window.vaq = window.vaq || []).push(params);\n };\n};\n","export function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nexport function isDevelopment(): boolean {\n if (typeof process === 'undefined') return false;\n return (\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'\n );\n}\n","import { initQueue } from './queue';\nimport type { AnalyticsProps } from './types';\nimport { isBrowser, isDevelopment } from './utils';\n\nexport const inject = (\n { beforeSend, debug }: AnalyticsProps = { debug: isDevelopment() },\n): void => {\n if (!isBrowser()) return;\n initQueue();\n\n if (beforeSend) {\n window.va?.('beforeSend', beforeSend);\n }\n const src = isDevelopment()\n ? 'https://cdn.vercel-insights.com/v1/script.debug.js'\n : '/_vercel/insights/script.js';\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return;\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n\n if (isDevelopment() && debug === false) {\n script.setAttribute('data-debug', 'false');\n }\n\n document.head.appendChild(script);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0B;;;ACAnB,IAAM,YAAY,MAAY;AAEnC,MAAI,OAAO;AAAI;AAEf,SAAO,KAAK,SAAS,KAAK,QAAc;AACtC,KAAC,OAAO,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM;AAAA,EAC7C;AACF;;;ACPO,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW;AAC3B;AAEO,SAAS,gBAAyB;AACvC,MAAI,OAAO,YAAY;AAAa,WAAO;AAC3C,SACE,QAAQ,IAAI,aAAa,iBAAiB,QAAQ,IAAI,aAAa;AAEvE;;;ACLO,IAAM,SAAS,CACpB,EAAE,YAAY,MAAM,IAAoB,EAAE,OAAO,cAAc,EAAE,MACxD;AANX;AAOE,MAAI,CAAC,UAAU;AAAG;AAClB,YAAU;AAEV,MAAI,YAAY;AACd,iBAAO,OAAP,gCAAY,cAAc;AAAA,EAC5B;AACA,QAAM,MAAM,cAAc,IACtB,uDACA;AAEJ,MAAI,SAAS,KAAK,cAAc,gBAAgB,OAAO;AAAG;AAE1D,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,SAAO,QAAQ;AAEf,MAAI,cAAc,KAAK,UAAU,OAAO;AACtC,WAAO,aAAa,cAAc,OAAO;AAAA,EAC3C;AAEA,WAAS,KAAK,YAAY,MAAM;AAClC;;;AHvBO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,QAAQ,cAAc;AACxB,GAAyB;AACvB,8BAAU,MAAM;AACd,WAAO,EAAE,YAAY,MAAM,CAAC;AAAA,EAC9B,GAAG,CAAC,YAAY,KAAK,CAAC;AAEtB,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/react.tsx","../../src/queue.ts","../../src/utils.ts","../../src/generic.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { inject } from './generic';\nimport type { AnalyticsProps } from './types';\n\nexport type { AnalyticsProps } from './types';\n\nexport function Analytics({\n beforeSend,\n debug = true,\n mode = 'auto',\n}: AnalyticsProps): null {\n useEffect(() => {\n inject({ beforeSend, debug, mode });\n }, [beforeSend, debug, mode]);\n\n return null;\n}\n\nexport { track } from './generic';\n","export const initQueue = (): void => {\n // initialize va until script is loaded\n if (window.va) return;\n\n window.va = function a(...params): void {\n (window.vaq = window.vaq || []).push(params);\n };\n};\n","import type { AllowedPropertyValues, Mode } from './types';\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nfunction detectEnvironment(): 'development' | 'production' {\n if (typeof process === 'undefined') return 'production';\n\n if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test')\n return 'development';\n\n return 'production';\n}\n\nexport function setMode(mode: Mode = 'auto'): void {\n if (mode === 'auto') {\n window.vam = detectEnvironment();\n }\n\n window.vam = mode;\n}\n\nexport function getMode(): Mode {\n return window.vam || 'production';\n}\n\nexport function isProduction(): boolean {\n return getMode() === 'production';\n}\n\nexport function isDevelopment(): boolean {\n return getMode() === 'development';\n}\n\nconst removeKey = (key: string, { [key]: _, ...rest }): Record<string, any> =>\n rest;\n\nexport function parseProperties(\n properties: Record<string, unknown>,\n options: {\n strip?: boolean;\n },\n): Error | Record<string, AllowedPropertyValues> | undefined {\n let props = properties;\n const errorProperties: string[] = [];\n for (const [key, value] of Object.entries(properties)) {\n if (typeof value === 'object' && value !== null) {\n if (options.strip) {\n props = removeKey(key, props);\n } else {\n errorProperties.push(key);\n }\n }\n }\n\n if (errorProperties.length > 0 && !options.strip) {\n throw Error(\n `The following properties are not valid: ${errorProperties.join(\n ', ',\n )}. Only strings, numbers, booleans, and null are allowed.`,\n );\n }\n return props as Record<string, AllowedPropertyValues>;\n}\n","import { initQueue } from './queue';\nimport type { AllowedPropertyValues, AnalyticsProps } from './types';\nimport {\n isBrowser,\n parseProperties,\n setMode,\n isDevelopment,\n isProduction,\n} from './utils';\n\nexport const inject = (\n props: AnalyticsProps = {\n debug: true,\n },\n): void => {\n if (!isBrowser()) return;\n\n setMode(props.mode);\n\n initQueue();\n\n if (props.beforeSend) {\n window.va?.('beforeSend', props.beforeSend);\n }\n\n const src = isDevelopment()\n ? 'https://cdn.vercel-insights.com/v1/script.debug.js'\n : '/_vercel/insights/script.js';\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return;\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n\n if (isDevelopment() && props.debug === false) {\n script.setAttribute('data-debug', 'false');\n }\n\n document.head.appendChild(script);\n};\n\nexport const track = (\n name: string,\n properties?: Record<string, AllowedPropertyValues>,\n): void => {\n if (!properties) {\n window.va?.('track', { name });\n return;\n }\n\n try {\n const props = parseProperties(properties, {\n strip: isProduction(),\n });\n\n window.va?.('track', {\n name,\n data: props,\n });\n } catch (err) {\n if (err instanceof Error && isDevelopment()) {\n // eslint-disable-next-line no-console\n console.error(err);\n }\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0B;;;ACAnB,IAAM,YAAY,MAAY;AAEnC,MAAI,OAAO;AAAI;AAEf,SAAO,KAAK,SAAS,KAAK,QAAc;AACtC,KAAC,OAAO,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM;AAAA,EAC7C;AACF;;;ACLO,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW;AAC3B;AAEA,SAAS,oBAAkD;AACzD,MAAI,OAAO,YAAY;AAAa,WAAO;AAE3C,MAAI,QAAQ,IAAI,aAAa,iBAAiB,QAAQ,IAAI,aAAa;AACrE,WAAO;AAET,SAAO;AACT;AAEO,SAAS,QAAQ,OAAa,QAAc;AACjD,MAAI,SAAS,QAAQ;AACnB,WAAO,MAAM,kBAAkB;AAAA,EACjC;AAEA,SAAO,MAAM;AACf;AAEO,SAAS,UAAgB;AAC9B,SAAO,OAAO,OAAO;AACvB;AAEO,SAAS,eAAwB;AACtC,SAAO,QAAQ,MAAM;AACvB;AAEO,SAAS,gBAAyB;AACvC,SAAO,QAAQ,MAAM;AACvB;AAEA,IAAM,YAAY,CAAC,KAAa,GAAG,MAAM,MAAM,KAAK,MAClD;AAEK,SAAS,gBACd,YACA,SAG2D;AAC3D,MAAI,QAAQ;AACZ,QAAM,kBAA4B,CAAC;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,QAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAI,QAAQ,OAAO;AACjB,gBAAQ,UAAU,KAAK,KAAK;AAAA,MAC9B,OAAO;AACL,wBAAgB,KAAK,GAAG;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,gBAAgB,SAAS,KAAK,CAAC,QAAQ,OAAO;AAChD,UAAM;AAAA,MACJ,2CAA2C,gBAAgB;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACtDO,IAAM,SAAS,CACpB,QAAwB;AAAA,EACtB,OAAO;AACT,MACS;AAdX;AAeE,MAAI,CAAC,UAAU;AAAG;AAElB,UAAQ,MAAM,IAAI;AAElB,YAAU;AAEV,MAAI,MAAM,YAAY;AACpB,iBAAO,OAAP,gCAAY,cAAc,MAAM;AAAA,EAClC;AAEA,QAAM,MAAM,cAAc,IACtB,uDACA;AAEJ,MAAI,SAAS,KAAK,cAAc,gBAAgB,OAAO;AAAG;AAE1D,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,SAAO,QAAQ;AAEf,MAAI,cAAc,KAAK,MAAM,UAAU,OAAO;AAC5C,WAAO,aAAa,cAAc,OAAO;AAAA,EAC3C;AAEA,WAAS,KAAK,YAAY,MAAM;AAClC;AAEO,IAAM,QAAQ,CACnB,MACA,eACS;AA7CX;AA8CE,MAAI,CAAC,YAAY;AACf,iBAAO,OAAP,gCAAY,SAAS,EAAE,KAAK;AAC5B;AAAA,EACF;AAEA,MAAI;AACF,UAAM,QAAQ,gBAAgB,YAAY;AAAA,MACxC,OAAO,aAAa;AAAA,IACtB,CAAC;AAED,iBAAO,OAAP,gCAAY,SAAS;AAAA,MACnB;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF,SAAS,KAAP;AACA,QAAI,eAAe,SAAS,cAAc,GAAG;AAE3C,cAAQ,MAAM,GAAG;AAAA,IACnB;AAAA,EACF;AACF;;;AH5DO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AACT,GAAyB;AACvB,8BAAU,MAAM;AACd,WAAO,EAAE,YAAY,OAAO,KAAK,CAAC;AAAA,EACpC,GAAG,CAAC,YAAY,OAAO,IAAI,CAAC;AAE5B,SAAO;AACT;","names":[]}
@@ -2,20 +2,26 @@ interface PageViewEvent {
2
2
  type: 'pageview';
3
3
  url: string;
4
4
  }
5
- declare type IEvent = PageViewEvent;
6
- declare type BeforeSend = (event: IEvent) => IEvent | null;
5
+ declare type Event = PageViewEvent;
6
+ declare type Mode = 'auto' | 'development' | 'production';
7
+ declare type AllowedPropertyValues = string | number | boolean | null;
8
+ declare type BeforeSend = (event: Event) => Event | null;
7
9
  interface AnalyticsProps {
8
10
  beforeSend?: BeforeSend;
9
11
  debug?: boolean;
12
+ mode?: Mode;
10
13
  }
11
14
  declare global {
12
15
  interface Window {
13
16
  va?: (event: string, properties?: unknown) => void;
14
17
  vaq?: [string, unknown?][];
15
18
  vai?: boolean;
19
+ vam?: Mode;
16
20
  }
17
21
  }
18
22
 
19
- declare function Analytics({ beforeSend, debug, }: AnalyticsProps): null;
23
+ declare const track: (name: string, properties?: Record<string, AllowedPropertyValues>) => void;
20
24
 
21
- export { Analytics };
25
+ declare function Analytics({ beforeSend, debug, mode, }: AnalyticsProps): null;
26
+
27
+ export { Analytics, AnalyticsProps, track };
@@ -14,20 +14,62 @@ var initQueue = () => {
14
14
  function isBrowser() {
15
15
  return typeof window !== "undefined";
16
16
  }
17
- function isDevelopment() {
17
+ function detectEnvironment() {
18
18
  if (typeof process === "undefined")
19
- return false;
20
- return process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test";
19
+ return "production";
20
+ if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test")
21
+ return "development";
22
+ return "production";
23
+ }
24
+ function setMode(mode = "auto") {
25
+ if (mode === "auto") {
26
+ window.vam = detectEnvironment();
27
+ }
28
+ window.vam = mode;
29
+ }
30
+ function getMode() {
31
+ return window.vam || "production";
32
+ }
33
+ function isProduction() {
34
+ return getMode() === "production";
35
+ }
36
+ function isDevelopment() {
37
+ return getMode() === "development";
38
+ }
39
+ var removeKey = (key, { [key]: _, ...rest }) => rest;
40
+ function parseProperties(properties, options) {
41
+ let props = properties;
42
+ const errorProperties = [];
43
+ for (const [key, value] of Object.entries(properties)) {
44
+ if (typeof value === "object" && value !== null) {
45
+ if (options.strip) {
46
+ props = removeKey(key, props);
47
+ } else {
48
+ errorProperties.push(key);
49
+ }
50
+ }
51
+ }
52
+ if (errorProperties.length > 0 && !options.strip) {
53
+ throw Error(
54
+ `The following properties are not valid: ${errorProperties.join(
55
+ ", "
56
+ )}. Only strings, numbers, booleans, and null are allowed.`
57
+ );
58
+ }
59
+ return props;
21
60
  }
22
61
 
23
62
  // src/generic.ts
24
- var inject = ({ beforeSend, debug } = { debug: isDevelopment() }) => {
63
+ var inject = (props = {
64
+ debug: true
65
+ }) => {
25
66
  var _a;
26
67
  if (!isBrowser())
27
68
  return;
69
+ setMode(props.mode);
28
70
  initQueue();
29
- if (beforeSend) {
30
- (_a = window.va) == null ? void 0 : _a.call(window, "beforeSend", beforeSend);
71
+ if (props.beforeSend) {
72
+ (_a = window.va) == null ? void 0 : _a.call(window, "beforeSend", props.beforeSend);
31
73
  }
32
74
  const src = isDevelopment() ? "https://cdn.vercel-insights.com/v1/script.debug.js" : "/_vercel/insights/script.js";
33
75
  if (document.head.querySelector(`script[src*="${src}"]`))
@@ -35,23 +77,45 @@ var inject = ({ beforeSend, debug } = { debug: isDevelopment() }) => {
35
77
  const script = document.createElement("script");
36
78
  script.src = src;
37
79
  script.defer = true;
38
- if (isDevelopment() && debug === false) {
80
+ if (isDevelopment() && props.debug === false) {
39
81
  script.setAttribute("data-debug", "false");
40
82
  }
41
83
  document.head.appendChild(script);
42
84
  };
85
+ var track = (name, properties) => {
86
+ var _a, _b;
87
+ if (!properties) {
88
+ (_a = window.va) == null ? void 0 : _a.call(window, "track", { name });
89
+ return;
90
+ }
91
+ try {
92
+ const props = parseProperties(properties, {
93
+ strip: isProduction()
94
+ });
95
+ (_b = window.va) == null ? void 0 : _b.call(window, "track", {
96
+ name,
97
+ data: props
98
+ });
99
+ } catch (err) {
100
+ if (err instanceof Error && isDevelopment()) {
101
+ console.error(err);
102
+ }
103
+ }
104
+ };
43
105
 
44
106
  // src/react.tsx
45
107
  function Analytics({
46
108
  beforeSend,
47
- debug = isDevelopment()
109
+ debug = true,
110
+ mode = "auto"
48
111
  }) {
49
112
  useEffect(() => {
50
- inject({ beforeSend, debug });
51
- }, [beforeSend, debug]);
113
+ inject({ beforeSend, debug, mode });
114
+ }, [beforeSend, debug, mode]);
52
115
  return null;
53
116
  }
54
117
  export {
55
- Analytics
118
+ Analytics,
119
+ track
56
120
  };
57
121
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react.tsx","../../src/queue.ts","../../src/utils.ts","../../src/generic.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { inject } from './generic';\nimport type { AnalyticsProps } from './types';\nimport { isDevelopment } from './utils';\n\nexport function Analytics({\n beforeSend,\n debug = isDevelopment(),\n}: AnalyticsProps): null {\n useEffect(() => {\n inject({ beforeSend, debug });\n }, [beforeSend, debug]);\n\n return null;\n}\n","export const initQueue = (): void => {\n // initialise va until script is loaded\n if (window.va) return;\n\n window.va = function a(...params): void {\n (window.vaq = window.vaq || []).push(params);\n };\n};\n","export function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nexport function isDevelopment(): boolean {\n if (typeof process === 'undefined') return false;\n return (\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'\n );\n}\n","import { initQueue } from './queue';\nimport type { AnalyticsProps } from './types';\nimport { isBrowser, isDevelopment } from './utils';\n\nexport const inject = (\n { beforeSend, debug }: AnalyticsProps = { debug: isDevelopment() },\n): void => {\n if (!isBrowser()) return;\n initQueue();\n\n if (beforeSend) {\n window.va?.('beforeSend', beforeSend);\n }\n const src = isDevelopment()\n ? 'https://cdn.vercel-insights.com/v1/script.debug.js'\n : '/_vercel/insights/script.js';\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return;\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n\n if (isDevelopment() && debug === false) {\n script.setAttribute('data-debug', 'false');\n }\n\n document.head.appendChild(script);\n};\n"],"mappings":";AAAA,SAAS,iBAAiB;;;ACAnB,IAAM,YAAY,MAAY;AAEnC,MAAI,OAAO;AAAI;AAEf,SAAO,KAAK,SAAS,KAAK,QAAc;AACtC,KAAC,OAAO,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM;AAAA,EAC7C;AACF;;;ACPO,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW;AAC3B;AAEO,SAAS,gBAAyB;AACvC,MAAI,OAAO,YAAY;AAAa,WAAO;AAC3C,SACE,QAAQ,IAAI,aAAa,iBAAiB,QAAQ,IAAI,aAAa;AAEvE;;;ACLO,IAAM,SAAS,CACpB,EAAE,YAAY,MAAM,IAAoB,EAAE,OAAO,cAAc,EAAE,MACxD;AANX;AAOE,MAAI,CAAC,UAAU;AAAG;AAClB,YAAU;AAEV,MAAI,YAAY;AACd,iBAAO,OAAP,gCAAY,cAAc;AAAA,EAC5B;AACA,QAAM,MAAM,cAAc,IACtB,uDACA;AAEJ,MAAI,SAAS,KAAK,cAAc,gBAAgB,OAAO;AAAG;AAE1D,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,SAAO,QAAQ;AAEf,MAAI,cAAc,KAAK,UAAU,OAAO;AACtC,WAAO,aAAa,cAAc,OAAO;AAAA,EAC3C;AAEA,WAAS,KAAK,YAAY,MAAM;AAClC;;;AHvBO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,QAAQ,cAAc;AACxB,GAAyB;AACvB,YAAU,MAAM;AACd,WAAO,EAAE,YAAY,MAAM,CAAC;AAAA,EAC9B,GAAG,CAAC,YAAY,KAAK,CAAC;AAEtB,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/react.tsx","../../src/queue.ts","../../src/utils.ts","../../src/generic.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { inject } from './generic';\nimport type { AnalyticsProps } from './types';\n\nexport type { AnalyticsProps } from './types';\n\nexport function Analytics({\n beforeSend,\n debug = true,\n mode = 'auto',\n}: AnalyticsProps): null {\n useEffect(() => {\n inject({ beforeSend, debug, mode });\n }, [beforeSend, debug, mode]);\n\n return null;\n}\n\nexport { track } from './generic';\n","export const initQueue = (): void => {\n // initialize va until script is loaded\n if (window.va) return;\n\n window.va = function a(...params): void {\n (window.vaq = window.vaq || []).push(params);\n };\n};\n","import type { AllowedPropertyValues, Mode } from './types';\n\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined';\n}\n\nfunction detectEnvironment(): 'development' | 'production' {\n if (typeof process === 'undefined') return 'production';\n\n if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test')\n return 'development';\n\n return 'production';\n}\n\nexport function setMode(mode: Mode = 'auto'): void {\n if (mode === 'auto') {\n window.vam = detectEnvironment();\n }\n\n window.vam = mode;\n}\n\nexport function getMode(): Mode {\n return window.vam || 'production';\n}\n\nexport function isProduction(): boolean {\n return getMode() === 'production';\n}\n\nexport function isDevelopment(): boolean {\n return getMode() === 'development';\n}\n\nconst removeKey = (key: string, { [key]: _, ...rest }): Record<string, any> =>\n rest;\n\nexport function parseProperties(\n properties: Record<string, unknown>,\n options: {\n strip?: boolean;\n },\n): Error | Record<string, AllowedPropertyValues> | undefined {\n let props = properties;\n const errorProperties: string[] = [];\n for (const [key, value] of Object.entries(properties)) {\n if (typeof value === 'object' && value !== null) {\n if (options.strip) {\n props = removeKey(key, props);\n } else {\n errorProperties.push(key);\n }\n }\n }\n\n if (errorProperties.length > 0 && !options.strip) {\n throw Error(\n `The following properties are not valid: ${errorProperties.join(\n ', ',\n )}. Only strings, numbers, booleans, and null are allowed.`,\n );\n }\n return props as Record<string, AllowedPropertyValues>;\n}\n","import { initQueue } from './queue';\nimport type { AllowedPropertyValues, AnalyticsProps } from './types';\nimport {\n isBrowser,\n parseProperties,\n setMode,\n isDevelopment,\n isProduction,\n} from './utils';\n\nexport const inject = (\n props: AnalyticsProps = {\n debug: true,\n },\n): void => {\n if (!isBrowser()) return;\n\n setMode(props.mode);\n\n initQueue();\n\n if (props.beforeSend) {\n window.va?.('beforeSend', props.beforeSend);\n }\n\n const src = isDevelopment()\n ? 'https://cdn.vercel-insights.com/v1/script.debug.js'\n : '/_vercel/insights/script.js';\n\n if (document.head.querySelector(`script[src*=\"${src}\"]`)) return;\n\n const script = document.createElement('script');\n script.src = src;\n script.defer = true;\n\n if (isDevelopment() && props.debug === false) {\n script.setAttribute('data-debug', 'false');\n }\n\n document.head.appendChild(script);\n};\n\nexport const track = (\n name: string,\n properties?: Record<string, AllowedPropertyValues>,\n): void => {\n if (!properties) {\n window.va?.('track', { name });\n return;\n }\n\n try {\n const props = parseProperties(properties, {\n strip: isProduction(),\n });\n\n window.va?.('track', {\n name,\n data: props,\n });\n } catch (err) {\n if (err instanceof Error && isDevelopment()) {\n // eslint-disable-next-line no-console\n console.error(err);\n }\n }\n};\n"],"mappings":";AAAA,SAAS,iBAAiB;;;ACAnB,IAAM,YAAY,MAAY;AAEnC,MAAI,OAAO;AAAI;AAEf,SAAO,KAAK,SAAS,KAAK,QAAc;AACtC,KAAC,OAAO,MAAM,OAAO,OAAO,CAAC,GAAG,KAAK,MAAM;AAAA,EAC7C;AACF;;;ACLO,SAAS,YAAqB;AACnC,SAAO,OAAO,WAAW;AAC3B;AAEA,SAAS,oBAAkD;AACzD,MAAI,OAAO,YAAY;AAAa,WAAO;AAE3C,MAAI,QAAQ,IAAI,aAAa,iBAAiB,QAAQ,IAAI,aAAa;AACrE,WAAO;AAET,SAAO;AACT;AAEO,SAAS,QAAQ,OAAa,QAAc;AACjD,MAAI,SAAS,QAAQ;AACnB,WAAO,MAAM,kBAAkB;AAAA,EACjC;AAEA,SAAO,MAAM;AACf;AAEO,SAAS,UAAgB;AAC9B,SAAO,OAAO,OAAO;AACvB;AAEO,SAAS,eAAwB;AACtC,SAAO,QAAQ,MAAM;AACvB;AAEO,SAAS,gBAAyB;AACvC,SAAO,QAAQ,MAAM;AACvB;AAEA,IAAM,YAAY,CAAC,KAAa,GAAG,MAAM,MAAM,KAAK,MAClD;AAEK,SAAS,gBACd,YACA,SAG2D;AAC3D,MAAI,QAAQ;AACZ,QAAM,kBAA4B,CAAC;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,QAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAI,QAAQ,OAAO;AACjB,gBAAQ,UAAU,KAAK,KAAK;AAAA,MAC9B,OAAO;AACL,wBAAgB,KAAK,GAAG;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,gBAAgB,SAAS,KAAK,CAAC,QAAQ,OAAO;AAChD,UAAM;AAAA,MACJ,2CAA2C,gBAAgB;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACtDO,IAAM,SAAS,CACpB,QAAwB;AAAA,EACtB,OAAO;AACT,MACS;AAdX;AAeE,MAAI,CAAC,UAAU;AAAG;AAElB,UAAQ,MAAM,IAAI;AAElB,YAAU;AAEV,MAAI,MAAM,YAAY;AACpB,iBAAO,OAAP,gCAAY,cAAc,MAAM;AAAA,EAClC;AAEA,QAAM,MAAM,cAAc,IACtB,uDACA;AAEJ,MAAI,SAAS,KAAK,cAAc,gBAAgB,OAAO;AAAG;AAE1D,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,SAAO,QAAQ;AAEf,MAAI,cAAc,KAAK,MAAM,UAAU,OAAO;AAC5C,WAAO,aAAa,cAAc,OAAO;AAAA,EAC3C;AAEA,WAAS,KAAK,YAAY,MAAM;AAClC;AAEO,IAAM,QAAQ,CACnB,MACA,eACS;AA7CX;AA8CE,MAAI,CAAC,YAAY;AACf,iBAAO,OAAP,gCAAY,SAAS,EAAE,KAAK;AAC5B;AAAA,EACF;AAEA,MAAI;AACF,UAAM,QAAQ,gBAAgB,YAAY;AAAA,MACxC,OAAO,aAAa;AAAA,IACtB,CAAC;AAED,iBAAO,OAAP,gCAAY,SAAS;AAAA,MACnB;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF,SAAS,KAAP;AACA,QAAI,eAAe,SAAS,cAAc,GAAG;AAE3C,cAAQ,MAAM,GAAG;AAAA,IACnB;AAAA,EACF;AACF;;;AH5DO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AACT,GAAyB;AACvB,YAAU,MAAM;AACd,WAAO,EAAE,YAAY,OAAO,KAAK,CAAC;AAAA,EACpC,GAAG,CAAC,YAAY,OAAO,IAAI,CAAC;AAE5B,SAAO;AACT;","names":[]}
package/jest.config.js ADDED
@@ -0,0 +1,9 @@
1
+ export default {
2
+ testEnvironment: 'jsdom',
3
+ transform: {
4
+ '^.+\\.(t|j)sx?$': '@swc/jest',
5
+ },
6
+ coverageReporters: ['text', 'html'],
7
+ setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
8
+ reporters: ['default', 'github-actions'],
9
+ };
package/jest.setup.ts ADDED
@@ -0,0 +1,9 @@
1
+ import '@testing-library/jest-dom';
2
+
3
+ // Adds helpers like `.toHaveAttribute`
4
+ import '@testing-library/jest-dom/extend-expect';
5
+
6
+ beforeEach(() => {
7
+ // reset dom before each test
8
+ document.getElementsByTagName('html')[0].innerHTML = '';
9
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/analytics",
3
- "version": "0.1.6-beta.1",
3
+ "version": "0.1.7-beta.1",
4
4
  "keywords": [
5
5
  "analytics",
6
6
  "vercel"
@@ -33,12 +33,25 @@
33
33
  "eslintConfig": {
34
34
  "extends": [
35
35
  "@vercel/eslint-config"
36
+ ],
37
+ "ignorePatterns": [
38
+ "jest.setup.ts"
36
39
  ]
37
40
  },
38
41
  "devDependencies": {
42
+ "@swc/core": "^1.3.20",
43
+ "@swc/jest": "^0.2.23",
44
+ "@testing-library/jest-dom": "^5.16.5",
45
+ "@testing-library/react": "^13.4.0",
46
+ "@types/jest": "^29.2.3",
39
47
  "@types/node": "^18.11.2",
40
48
  "@types/react": "^16.8||^17||^18",
49
+ "@types/testing-library__jest-dom": "^5.14.5",
41
50
  "@vercel/eslint-config": "0.0.0",
51
+ "jest": "^29.3.1",
52
+ "jest-environment-jsdom": "^29.3.1",
53
+ "react": "^18.2.0",
54
+ "react-dom": "^18.2.0",
42
55
  "tsup": "^6.3.0"
43
56
  },
44
57
  "peerDependencies": {
@@ -49,6 +62,7 @@
49
62
  "dev": "tsup --watch",
50
63
  "lint": "eslint .",
51
64
  "lint-fix": "eslint . --fix",
65
+ "test": "jest",
52
66
  "type-check": "tsc --noEmit"
53
67
  }
54
68
  }