@hellpig/anarchy-tracking 1.6.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/NOTICE.md +12 -0
  4. package/README.md +34 -0
  5. package/dist/anarchy-tracking/src/Constants/Masks.d.ts +1 -0
  6. package/dist/anarchy-tracking/src/Constants/index.d.ts +1 -0
  7. package/dist/anarchy-tracking/src/Models/TMetaData.d.ts +2 -0
  8. package/dist/anarchy-tracking/src/Models/TTrackingService.d.ts +6 -0
  9. package/dist/anarchy-tracking/src/Models/index.d.ts +2 -0
  10. package/dist/anarchy-tracking/src/Services/BrowserTrackingService.d.ts +4 -0
  11. package/dist/anarchy-tracking/src/Services/DesktopPreloadTrackingService.d.ts +3 -0
  12. package/dist/anarchy-tracking/src/Services/DesktopTrackingService.d.ts +4 -0
  13. package/dist/anarchy-tracking/src/Utils/DynamicDataUtils.d.ts +2 -0
  14. package/dist/anarchy-tracking/src/Utils/IntegrationsBrowser.d.ts +2 -0
  15. package/dist/anarchy-tracking/src/Utils/IntegrationsNode.d.ts +1 -0
  16. package/dist/anarchy-tracking/src/Utils/ScrubEvent.d.ts +2 -0
  17. package/dist/anarchy-tracking/src/Utils/ScrubsBrowser.d.ts +2 -0
  18. package/dist/anarchy-tracking/src/Utils/ScrubsDesktop.d.ts +2 -0
  19. package/dist/anarchy-tracking/src/Utils/browser.d.ts +2 -0
  20. package/dist/anarchy-tracking/src/Utils/desktop.d.ts +2 -0
  21. package/dist/anarchy-tracking/src/Utils/index.d.ts +2 -0
  22. package/dist/anarchy-tracking/src/browser.d.ts +2 -0
  23. package/dist/anarchy-tracking/src/desktop-preload.d.ts +2 -0
  24. package/dist/anarchy-tracking/src/desktop.d.ts +2 -0
  25. package/dist/anarchy-tracking/src/index.d.ts +3 -0
  26. package/dist/browser/index.es.js +2 -0
  27. package/dist/browser/index.es.js.map +1 -0
  28. package/dist/chunks/TrackingUtils.js +2 -0
  29. package/dist/chunks/TrackingUtils.js.map +1 -0
  30. package/dist/chunks/browser.js +2 -0
  31. package/dist/chunks/browser.js.map +1 -0
  32. package/dist/chunks/index.js +2 -0
  33. package/dist/chunks/index.js.map +1 -0
  34. package/dist/desktop/index.es.js +2 -0
  35. package/dist/desktop/index.es.js.map +1 -0
  36. package/dist/desktop-preload/index.es.js +2 -0
  37. package/dist/desktop-preload/index.es.js.map +1 -0
  38. package/dist/index/index.es.js +2 -0
  39. package/dist/index/index.es.js.map +1 -0
  40. package/legal/DISCLAIMER.md +47 -0
  41. package/legal/EULA.md +18 -0
  42. package/legal/NOTICE.md +1062 -0
  43. package/legal/PRIVACY.md +52 -0
  44. package/legal/SECURITY.md +49 -0
  45. package/legal/THIRD_PARTY_LICENSES.md +9584 -0
  46. package/package.json +100 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ - 1.0.0 Initial
2
+ - 1.1.0 Upload sourcemaps to Sentry
3
+ - 1.2.0 Support of Electron-desktop apps (main and preload)
4
+ - 1.3.0 Sentry integrations for sourcemaps and better anonymous user tracking
5
+ - 1.4.0 Sentry release+dist tagging for better sourcemap handling
6
+ - 1.5.0 Added optional dynamic context (and tags) to data (beforeSend)
7
+ - 1.6.0 Added proper building and npm packaging
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sergei Panfilov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/NOTICE.md ADDED
@@ -0,0 +1,12 @@
1
+ # Third-Party Notices (Pointer)
2
+
3
+ This distribution of **@hellpig/anarchy-tracking** may include **third-party components**.
4
+
5
+ Full attributions and license texts are provided **offline** at:
6
+
7
+ - `./legal/NOTICE`: canonical third-party notices
8
+ - `./legal/THIRD_PARTY_LICENSES`: bundled license texts
9
+
10
+ Nothing in this pointer modifies third-party licenses. If there is any conflict between this note and a third-party license, the third-party license controls.
11
+
12
+ Questions: TBD until market release
package/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # Anarchy engine anarchy-tracking package
2
+
3
+ Error tracking utils for Anarchy apps.
4
+
5
+ ## License
6
+
7
+ MIT License
8
+
9
+ Copyright (c) 2025 Sergei Panfilov
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ ## Legal
30
+
31
+ See local files `LICENSE`, `CHANGELOG`, `NOTICE` (pointer), and files in `./legal`:
32
+ `DISCLAIMER`, `EULA`, `PRIVACY`, `SECURITY`, `NOTICE` (full), `THIRD_PARTY_LICENSES`.
33
+
34
+ Contacts — Privacy: {{PRIVACY_EMAIL}}, Security: {{SECURITY_EMAIL}}.
@@ -0,0 +1 @@
1
+ export declare const HiddenField: "hidden";
@@ -0,0 +1 @@
1
+ export * from './Masks';
@@ -0,0 +1,2 @@
1
+ import { Primitive } from '@sentry/core';
2
+ export type TMetaData = Record<string, Primitive>;
@@ -0,0 +1,6 @@
1
+ export type TTrackingService = Readonly<{
2
+ captureException: (exception: unknown, hint?: any) => string;
3
+ start: (onErrorHandler?: (ev: any) => void, onRejectionHandler?: (ev: PromiseRejectionEvent) => void) => void;
4
+ stop: (onErrorHandler?: (ev: any) => void, onRejectionHandler?: (ev: PromiseRejectionEvent) => void) => void;
5
+ isStarted: () => boolean;
6
+ }>;
@@ -0,0 +1,2 @@
1
+ export type * from './TMetaData';
2
+ export type * from './TTrackingService';
@@ -0,0 +1,4 @@
1
+ import { TMetaData, TTrackingService } from '../Models';
2
+ import { BrowserOptions } from '@sentry/browser';
3
+ import { Primitive } from '@sentry/core';
4
+ export declare function BrowserTrackingService(options?: BrowserOptions, metaData?: TMetaData, dynamicContextFn?: () => Record<string, any>, dynamicTagsFn?: () => Record<string, Primitive>): TTrackingService;
@@ -0,0 +1,3 @@
1
+ import { TMetaData, TTrackingService } from '../Models';
2
+ import { Primitive } from '@sentry/core';
3
+ export declare function DesktopPreloadTrackingService(options?: Record<string, any>, metaData?: TMetaData, dynamicContextFn?: () => Record<string, any>, dynamicTagsFn?: () => Record<string, Primitive>): TTrackingService;
@@ -0,0 +1,4 @@
1
+ import { TMetaData, TTrackingService } from '../Models';
2
+ import { Primitive } from '@sentry/core';
3
+ import { ElectronMainOptions } from '@sentry/electron/esm/main';
4
+ export declare function DesktopTrackingService(options?: ElectronMainOptions, metaData?: TMetaData, dynamicContextFn?: () => Record<string, any>, dynamicTagsFn?: () => Record<string, Primitive>): TTrackingService;
@@ -0,0 +1,2 @@
1
+ import { ErrorEvent, Primitive } from '@sentry/core';
2
+ export declare function mutateEventWithDynamicData(result: ErrorEvent, dynamicContextFn?: () => Record<string, any>, dynamicTagsFn?: () => Record<string, Primitive>): void;
@@ -0,0 +1,2 @@
1
+ import { Integration } from '@sentry/core';
2
+ export declare const rewriteFramesIntegrationBrowser: () => Integration;
@@ -0,0 +1 @@
1
+ export declare const rewriteFramesIntegrationNode: (options?: any) => any;
@@ -0,0 +1,2 @@
1
+ import { ErrorEvent } from '@sentry/core';
2
+ export declare function scrubEvent(event: ErrorEvent): ErrorEvent;
@@ -0,0 +1,2 @@
1
+ import { ErrorEvent } from '@sentry/browser';
2
+ export declare function scrubUserPathsBrowser(event: ErrorEvent): ErrorEvent;
@@ -0,0 +1,2 @@
1
+ import { ErrorEvent } from '@sentry/electron/main';
2
+ export declare function scrubUserPathsDesktop(event: ErrorEvent): ErrorEvent;
@@ -0,0 +1,2 @@
1
+ export * from './IntegrationsBrowser';
2
+ export * from './ScrubsBrowser';
@@ -0,0 +1,2 @@
1
+ export * from './IntegrationsNode';
2
+ export * from './ScrubsDesktop';
@@ -0,0 +1,2 @@
1
+ export * from './DynamicDataUtils';
2
+ export * from './ScrubEvent';
@@ -0,0 +1,2 @@
1
+ export { BrowserTrackingService } from './Services/BrowserTrackingService';
2
+ export * as Utils from './Utils/browser';
@@ -0,0 +1,2 @@
1
+ export { DesktopPreloadTrackingService } from './Services/DesktopPreloadTrackingService';
2
+ export * as Utils from './Utils/browser';
@@ -0,0 +1,2 @@
1
+ export { DesktopTrackingService } from './Services/DesktopTrackingService';
2
+ export * as Utils from './Utils/desktop';
@@ -0,0 +1,3 @@
1
+ export * from './Constants';
2
+ export type * from './Models';
3
+ export * from './Utils';
@@ -0,0 +1,2 @@
1
+ import{i as isDefined,s as scrubEvent,m as mutateEventWithDynamicData}from"../chunks/index.js";import{p as parseDistName}from"../chunks/TrackingUtils.js";import{r as rewriteFramesIntegrationBrowser,s as scrubUserPathsBrowser}from"../chunks/browser.js";export{b as Utils}from"../chunks/browser.js";import{init,setTags,captureException}from"@sentry/browser";function BrowserTrackingService(options,metaData,dynamicContextFn,dynamicTagsFn){let isStarted=!1;const defaultOptions={beforeSend(event,_hint){const result=scrubUserPathsBrowser(scrubEvent(event));return mutateEventWithDynamicData(result,dynamicContextFn,dynamicTagsFn),result},integrations:[rewriteFramesIntegrationBrowser()],tracesSampleRate:0,sendDefaultPii:!1},client=init({...defaultOptions,...options});isDefined(metaData)&&setTags(metaData);const{platform:platform,arch:arch}=parseDistName(options?.dist);setTags({layer:"web",errorTracker:"BrowserTrackingService",os:platform,arch:arch});const onError=ev=>{captureException(ev?.error??ev)},onRejection=ev=>{captureException(ev?.reason??ev)};function start(onErrorHandler=onError,onRejectionHandler=onRejection){isStarted||(isStarted=!0,window.addEventListener("error",onErrorHandler),window.addEventListener("unhandledrejection",onRejectionHandler))}return isDefined(client)&&start(),{captureException:captureException,start:start,stop:function(onErrorHandler=onError,onRejectionHandler=onRejection){isStarted=!1,window.removeEventListener("error",onErrorHandler),window.removeEventListener("unhandledrejection",onRejectionHandler)},isStarted:()=>isStarted}}export{BrowserTrackingService};
2
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":["../../src/Services/BrowserTrackingService.ts"],"sourcesContent":["import { isDefined, parseDistName } from '@Anarchy/Shared/Utils';\nimport type { TMetaData, TTrackingService } from '@Anarchy/Tracking/Models';\nimport { mutateEventWithDynamicData } from '@Anarchy/Tracking/Utils/DynamicDataUtils';\nimport { rewriteFramesIntegrationBrowser } from '@Anarchy/Tracking/Utils/IntegrationsBrowser';\nimport { scrubEvent } from '@Anarchy/Tracking/Utils/ScrubEvent';\nimport { scrubUserPathsBrowser } from '@Anarchy/Tracking/Utils/ScrubsBrowser';\nimport type { BrowserOptions, EventHint } from '@sentry/browser';\nimport { captureException, init, setTags } from '@sentry/browser';\nimport type { Client, ErrorEvent, Primitive } from '@sentry/core';\n\nexport function BrowserTrackingService(\n options?: BrowserOptions,\n metaData?: TMetaData,\n dynamicContextFn?: () => Record<string, any>,\n dynamicTagsFn?: () => Record<string, Primitive>\n): TTrackingService {\n let isStarted: boolean = false;\n\n const defaultOptions: BrowserOptions = {\n beforeSend(event: ErrorEvent, _hint: EventHint): PromiseLike<ErrorEvent | null> | ErrorEvent | null {\n const result: ErrorEvent = scrubUserPathsBrowser(scrubEvent(event));\n mutateEventWithDynamicData(result, dynamicContextFn, dynamicTagsFn);\n return result;\n },\n integrations: [rewriteFramesIntegrationBrowser()],\n tracesSampleRate: 0,\n //Important: make sure this is false if you want anonymous reports (no IPs, etc. for GDPR and similar acts).\n sendDefaultPii: false\n };\n\n const client: Client | undefined = init({\n ...defaultOptions,\n ...options\n });\n\n if (isDefined(metaData)) setTags(metaData);\n const { platform, arch } = parseDistName(options?.dist);\n setTags({\n layer: 'web',\n errorTracker: 'BrowserTrackingService',\n os: platform,\n arch\n });\n\n const onError = (ev: any): void => void captureException(ev?.error ?? ev);\n const onRejection = (ev: PromiseRejectionEvent): void => void captureException((ev as PromiseRejectionEvent)?.reason ?? ev);\n\n function start(onErrorHandler: (ev: any) => void = onError, onRejectionHandler: (ev: PromiseRejectionEvent) => void = onRejection): void {\n if (isStarted) return;\n isStarted = true;\n window.addEventListener('error', onErrorHandler);\n window.addEventListener('unhandledrejection', onRejectionHandler);\n }\n\n function stop(onErrorHandler: (ev: any) => void = onError, onRejectionHandler: (ev: PromiseRejectionEvent) => void = onRejection): void {\n isStarted = false;\n window.removeEventListener('error', onErrorHandler);\n window.removeEventListener('unhandledrejection', onRejectionHandler);\n }\n\n if (isDefined(client)) start();\n\n return {\n captureException,\n start,\n stop,\n isStarted: () => isStarted\n };\n}\n"],"names":["BrowserTrackingService","options","metaData","dynamicContextFn","dynamicTagsFn","isStarted","defaultOptions","beforeSend","event","_hint","result","scrubUserPathsBrowser","scrubEvent","mutateEventWithDynamicData","integrations","rewriteFramesIntegrationBrowser","tracesSampleRate","sendDefaultPii","client","init","isDefined","setTags","platform","arch","parseDistName","dist","layer","errorTracker","os","onError","ev","captureException","error","onRejection","reason","start","onErrorHandler","onRejectionHandler","window","addEventListener","stop","removeEventListener"],"mappings":"oWAUO,SAASA,uBACdC,QACAC,SACAC,iBACAC,eAEA,IAAIC,WAAqB,EAEzB,MAAMC,eAAiC,CACrC,UAAAC,CAAWC,MAAmBC,OAC5B,MAAMC,OAAqBC,sBAAsBC,WAAWJ,QAE5D,OADAK,2BAA2BH,OAAQP,iBAAkBC,eAC9CM,MACT,EACAI,aAAc,CAACC,mCACfC,iBAAkB,EAElBC,gBAAgB,GAGZC,OAA6BC,KAAK,IACnCb,kBACAL,UAGDmB,UAAUlB,WAAWmB,QAAQnB,UACjC,MAAMoB,SAAEA,SAAAC,KAAUA,MAASC,cAAcvB,SAASwB,MAClDJ,QAAQ,CACNK,MAAO,MACPC,aAAc,yBACdC,GAAIN,SACJC,YAGF,MAAMM,QAAWC,KAAuBC,iBAAiBD,IAAIE,OAASF,KAChEG,YAAeH,KAAyCC,iBAAkBD,IAA8BI,QAAUJ,KAExH,SAASK,MAAMC,eAAoCP,QAASQ,mBAA0DJ,aAChH5B,YACJA,WAAY,EACZiC,OAAOC,iBAAiB,QAASH,gBACjCE,OAAOC,iBAAiB,qBAAsBF,oBAChD,CAUA,OAFIjB,UAAUF,SAASiB,QAEhB,CACLJ,kCACAI,YACAK,KAXF,SAAcJ,eAAoCP,QAASQ,mBAA0DJ,aACnH5B,WAAY,EACZiC,OAAOG,oBAAoB,QAASL,gBACpCE,OAAOG,oBAAoB,qBAAsBJ,mBACnD,EAQEhC,UAAW,IAAMA,UAErB"}
@@ -0,0 +1,2 @@
1
+ function parseDistName(distName){if(!distName)return{platform:"unknown",arch:"unknown"};const parts=distName.toLowerCase().trim().split("-"),[platform,arch]=parts;return{platform:platform||"unknown",arch:arch||"unknown"}}export{parseDistName as p};
2
+ //# sourceMappingURL=TrackingUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrackingUtils.js","sources":["../../../anarchy-shared/src/Utils/TrackingUtils.ts"],"sourcesContent":["export function parseDistName(distName: string | undefined | null): Readonly<{ platform: string; arch: string }> {\n if (!distName) return { platform: 'unknown', arch: 'unknown' };\n\n const parts: ReadonlyArray<string> = distName.toLowerCase().trim().split('-');\n const [platform, arch] = parts;\n return { platform: platform || 'unknown', arch: arch || 'unknown' };\n}\n"],"names":["parseDistName","distName","platform","arch","parts","toLowerCase","trim","split"],"mappings":"AAAO,SAASA,cAAcC,UAC5B,IAAKA,SAAU,MAAO,CAAEC,SAAU,UAAWC,KAAM,WAEnD,MAAMC,MAA+BH,SAASI,cAAcC,OAAOC,MAAM,MAClEL,SAAUC,MAAQC,MACzB,MAAO,CAAEF,SAAUA,UAAY,UAAWC,KAAMA,MAAQ,UAC1D"}
@@ -0,0 +1,2 @@
1
+ import{rewriteFramesIntegration}from"@sentry/browser";import{H as HiddenField}from"./index.js";const rewriteFramesIntegrationBrowser=()=>rewriteFramesIntegration({iteratee:frame=>{const f={...frame};if(!f.filename)return f;const name=String(f.filename).replace(/\\/g,"/");if(name.startsWith("app:///"))return f;const cutToLastDist=p=>{const idx=p.lastIndexOf("/dist/");return idx<0?null:p.slice(idx).replace(/^\/+/,"")},relFromLast=cutToLastDist(name);if(relFromLast){if(f.filename=`app:///${relFromLast}`,f.abs_path){const absRel=cutToLastDist(String(f.abs_path).replace(/\\/g,"/"));absRel&&(f.abs_path=`app:///${absRel}`)}return f}return f}}),pathRegexps=[[/(\/Users)\/[^/]+/g,"$1/<home>"],[/(\/home)\/[^/]+/g,"$1/<home>"],[/(\/var\/home)\/[^/]+/g,"$1/<home>"],[/([A-Za-z]:\\Users)\\[^\\]+/g,"$1\\<home>"],[/([A-Za-z]:\\Documents and Settings)\\[^\\]+/g,"$1\\<home>"],[/(file:\/\/\/Users)\/[^/]+/g,"$1/<home>"],[/(file:\/\/\/home)\/[^/]+/g,"$1/<home>"],[/(file:\/\/\/var\/home)\/[^/]+/g,"$1/<home>"],[/(file:\/\/[A-Za-z]:\/Users)\/[^/]+/g,"$1/<home>"]];function replaceUserPaths(s,replacement="<home>"){return"string"!=typeof s?s:pathRegexps.reduce((acc,[re,tpl])=>acc.replace(re,tpl.replace("<home>",replacement)),s)}function scrubUserPathsBrowser(event){const replacement=HiddenField,message=event.message?replaceUserPaths(event.message,replacement):event.message,valuesIn=event.exception?.values,valuesOut=valuesIn?.map(v=>{const framesIn=v?.stacktrace?.frames,framesOut=framesIn?.map(f=>({...f,...f?.filename?{filename:replaceUserPaths(f.filename,replacement)}:{},...f?.abs_path?{abs_path:replaceUserPaths(f.abs_path,replacement)}:{},...f?.module?{module:replaceUserPaths(f.module,replacement)}:{},...f?.function?{function:replaceUserPaths(f.function,replacement)}:{}})),stacktraceOut=v?.stacktrace?{...v.stacktrace,...framesOut?{frames:framesOut}:{}}:v?.stacktrace;return{...v,...v?.value?{value:replaceUserPaths(v.value,replacement)}:{},...v?.type?{type:replaceUserPaths(v.type,replacement)}:{},...v?.stacktrace?{stacktrace:stacktraceOut}:{}}}),exceptionOut=event.exception?{...event.exception,...valuesOut?{values:valuesOut}:{}}:event.exception,requestOut=event.request?{...event.request,...event.request.url?{url:replaceUserPaths(event.request.url,replacement)}:{}}:event.request,extraIn=event.extra,extraOut=extraIn?Object.fromEntries(Object.entries(extraIn).map(([k,v])=>[k,"string"==typeof v?replaceUserPaths(v,replacement):v])):extraIn,breadcrumbsIn=event.breadcrumbs,breadcrumbsOut=breadcrumbsIn?.map(b=>{const dataIn=b?.data,dataOut=dataIn?Object.fromEntries(Object.entries(dataIn).map(([key,val])=>[key,"string"==typeof val?replaceUserPaths(val,replacement):val])):dataIn;return{...b,...b?.message?{message:replaceUserPaths(b.message,replacement)}:{},...b?.data&&"object"==typeof b.data?{data:dataOut}:{}}});return{...event,...message?{message:message}:{},...exceptionOut?{exception:exceptionOut}:{},...requestOut?{request:requestOut}:{},...void 0!==extraOut?{extra:extraOut}:{},...breadcrumbsOut?{breadcrumbs:breadcrumbsOut}:{}}}const browser=Object.freeze(Object.defineProperty({__proto__:null,rewriteFramesIntegrationBrowser:rewriteFramesIntegrationBrowser,scrubUserPathsBrowser:scrubUserPathsBrowser},Symbol.toStringTag,{value:"Module"}));export{browser as b,rewriteFramesIntegrationBrowser as r,scrubUserPathsBrowser as s};
2
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sources":["../../src/Utils/IntegrationsBrowser.ts","../../src/Utils/ScrubsBrowser.ts"],"sourcesContent":["import type { StackFrame } from '@sentry/browser';\nimport { rewriteFramesIntegration } from '@sentry/browser';\nimport type { Integration } from '@sentry/core';\n\nexport const rewriteFramesIntegrationBrowser = (): Integration =>\n rewriteFramesIntegration({\n // eslint-disable-next-line spellcheck/spell-checker\n iteratee: (frame: StackFrame): StackFrame => {\n const f: StackFrame = { ...(frame as any) } as any;\n if (!f.filename) return f;\n\n const name: string = String(f.filename).replace(/\\\\/g, '/');\n // already normalized\n if (name.startsWith('app:///')) return f;\n\n // Prefer the LAST \"/dist/\" occurrence so nested paths like\n // \".../dist/mac-arm64/.../app.asar/dist/dist-desktop/...\" map to\n // \"app:///dist/dist-desktop/...\" which matches uploaded urlPrefix/app paths.\n const cutToLastDist = (p: string): string | null => {\n const idx: number = p.lastIndexOf('/dist/');\n if (idx < 0) return null;\n return p.slice(idx).replace(/^\\/+/, '');\n };\n\n const relFromLast = cutToLastDist(name);\n if (relFromLast) {\n // eslint-disable-next-line functional/immutable-data\n (f as any).filename = `app:///${relFromLast}`;\n if (f.abs_path) {\n const abs: string = String(f.abs_path).replace(/\\\\/g, '/');\n const absRel: string | null = cutToLastDist(abs);\n if (absRel) {\n // eslint-disable-next-line functional/immutable-data\n (f as any).abs_path = `app:///${absRel}`;\n }\n }\n return f;\n }\n\n return f;\n }\n });\n","import { HiddenField } from '@Anarchy/Tracking/Constants';\nimport type { ErrorEvent } from '@sentry/browser';\n\nconst pathRegexps: ReadonlyArray<[RegExp, string]> = [\n // macOS: /Users/<name>/...\n [/(\\/Users)\\/[^/]+/g, '$1/<home>'],\n\n // Linux: /home/<name>/... and /var/home/<name>/...\n [/(\\/home)\\/[^/]+/g, '$1/<home>'],\n [/(\\/var\\/home)\\/[^/]+/g, '$1/<home>'],\n\n // Windows: C:\\\\Users\\\\<name>\\\\... (any drive letter)\n [/([A-Za-z]:\\\\Users)\\\\[^\\\\]+/g, '$1\\\\<home>'],\n\n // Old Windows: C:\\\\Documents and Settings\\\\<name>\\\\...\n [/([A-Za-z]:\\\\Documents and Settings)\\\\[^\\\\]+/g, '$1\\\\<home>'],\n\n // file:// URLs: file:///Users/<name>/..., file:///home/<name>/..., file://C:/Users/<name>/...\n [/(file:\\/\\/\\/Users)\\/[^/]+/g, '$1/<home>'],\n [/(file:\\/\\/\\/home)\\/[^/]+/g, '$1/<home>'],\n [/(file:\\/\\/\\/var\\/home)\\/[^/]+/g, '$1/<home>'],\n [/(file:\\/\\/[A-Za-z]:\\/Users)\\/[^/]+/g, '$1/<home>']\n];\n\nfunction replaceUserPaths(s?: unknown, replacement: string = '<home>'): string | unknown {\n if (typeof s !== 'string') return s;\n return pathRegexps.reduce((acc: string, [re, tpl]) => acc.replace(re, tpl.replace('<home>', replacement)), s);\n}\n\nexport function scrubUserPathsBrowser(event: ErrorEvent): ErrorEvent {\n const replacement = HiddenField;\n\n const message = event.message ? (replaceUserPaths(event.message, replacement) as string) : event.message;\n\n const valuesIn = event.exception?.values as ReadonlyArray<any> | undefined;\n const valuesOut = valuesIn?.map((v: any) => {\n const framesIn: ReadonlyArray<any> | undefined = v?.stacktrace?.frames;\n const framesOut = (framesIn as any[] | undefined)?.map((f: any) => ({\n ...f,\n ...(f?.filename ? { filename: replaceUserPaths(f.filename, replacement) } : {}),\n ...(f?.abs_path ? { abs_path: replaceUserPaths(f.abs_path, replacement) } : {}),\n ...(f?.module ? { module: replaceUserPaths(f.module, replacement) } : {}),\n ...(f?.function ? { function: replaceUserPaths(f.function, replacement) } : {})\n }));\n\n const stacktraceOut = v?.stacktrace ? { ...v.stacktrace, ...(framesOut ? { frames: framesOut } : {}) } : v?.stacktrace;\n\n return {\n ...v,\n ...(v?.value ? { value: replaceUserPaths(v.value, replacement) } : {}),\n ...(v?.type ? { type: replaceUserPaths(v.type, replacement) } : {}),\n ...(v?.stacktrace ? { stacktrace: stacktraceOut } : {})\n };\n });\n\n const exceptionOut = event.exception ? { ...event.exception, ...(valuesOut ? { values: valuesOut } : {}) } : event.exception;\n\n const requestOut = event.request\n ? {\n ...event.request,\n ...(event.request.url ? { url: replaceUserPaths(event.request.url, replacement) as string } : {})\n }\n : event.request;\n\n const extraIn = event.extra as Record<string, unknown> | undefined;\n const extraOut = extraIn ? Object.fromEntries(Object.entries(extraIn).map(([k, v]) => [k, typeof v === 'string' ? replaceUserPaths(v, replacement) : v])) : extraIn;\n\n const breadcrumbsIn = event.breadcrumbs as any[] | undefined;\n const breadcrumbsOut = breadcrumbsIn?.map((b: any) => {\n const dataIn = b?.data as Record<string, unknown> | undefined;\n const dataOut = dataIn ? Object.fromEntries(Object.entries(dataIn).map(([key, val]) => [key, typeof val === 'string' ? replaceUserPaths(val as string, replacement) : val])) : dataIn;\n\n return {\n ...b,\n ...(b?.message ? { message: replaceUserPaths(b.message, replacement) } : {}),\n ...(b?.data && typeof b.data === 'object' ? { data: dataOut } : {})\n };\n });\n\n return {\n ...event,\n ...(message ? { message } : {}),\n ...(exceptionOut ? { exception: exceptionOut as any } : {}),\n ...(requestOut ? { request: requestOut as any } : {}),\n ...(extraOut !== undefined ? { extra: extraOut as any } : {}),\n ...(breadcrumbsOut ? { breadcrumbs: breadcrumbsOut as any } : {})\n };\n}\n"],"names":["rewriteFramesIntegrationBrowser","rewriteFramesIntegration","iteratee","frame","f","filename","name","String","replace","startsWith","cutToLastDist","p","idx","lastIndexOf","slice","relFromLast","abs_path","absRel","pathRegexps","replaceUserPaths","s","replacement","reduce","acc","re","tpl","scrubUserPathsBrowser","event","HiddenField","message","valuesIn","exception","values","valuesOut","map","v","framesIn","stacktrace","frames","framesOut","module","function","stacktraceOut","value","type","exceptionOut","requestOut","request","url","extraIn","extra","extraOut","Object","fromEntries","entries","k","breadcrumbsIn","breadcrumbs","breadcrumbsOut","b","dataIn","data","dataOut","key","val"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const HiddenField="hidden",isDefined=value=>null!=value,isString=value=>"string"==typeof value;function mutateEventWithDynamicData(result,dynamicContextFn,dynamicTagsFn){if(isDefined(dynamicContextFn)&&(result.contexts={...result.contexts??{},extra:dynamicContextFn()}),isDefined(dynamicTagsFn)){const dynamicTags=dynamicTagsFn();Object.keys(dynamicTags).forEach(key=>{result.tags={...result.tags??{},[key]:dynamicTags[key]}})}}function scrubEvent(event){return event.user||(event.user=null),event.request&&(event.request={...event.request,url:"hidden",headers:{...event.request?.headers,url:"hidden",Referer:"hidden",referer:"hidden"}},delete event.request.headers?.Cookie,delete event.request.headers?.cookie),event.contexts?.geo&&delete event.contexts.geo,event.contexts?.Geography&&delete event.contexts.Geography,event.contexts?.geography&&delete event.contexts.geography,event.breadcrumbs||(event.breadcrumbs=void 0),event}export{HiddenField as H,isString as a,isDefined as i,mutateEventWithDynamicData as m,scrubEvent as s};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/Constants/Masks.ts","../../../anarchy-shared/src/Utils/CheckUtils.ts","../../src/Utils/DynamicDataUtils.ts","../../src/Utils/ScrubEvent.ts"],"sourcesContent":["export const HiddenField = 'hidden' as const;\n","export const isDefined = <T>(value: T | undefined | null): value is T => <T>value !== undefined && <T>value !== null;\n\nexport const isAllDefined = <T>(values: ReadonlyArray<T | undefined | null>): values is ReadonlyArray<T> => !values.some(isNotDefined);\n\nexport const isNotDefined = <T>(value: T | undefined | null): value is undefined | null => !isDefined<T>(value);\n\nexport const isAllNotDefined = <T>(values: ReadonlyArray<T | undefined | null>): values is ReadonlyArray<undefined | null> => values.every(isNotDefined);\n\nexport const isString = (value: unknown): value is string => typeof value === 'string';\n\nexport const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean';\n","import { isDefined } from '@Anarchy/Shared/Utils';\nimport type { ErrorEvent, Primitive } from '@sentry/core';\n\nexport function mutateEventWithDynamicData(result: ErrorEvent, dynamicContextFn?: () => Record<string, any>, dynamicTagsFn?: () => Record<string, Primitive>): void {\n // eslint-disable-next-line functional/immutable-data\n if (isDefined(dynamicContextFn)) result.contexts = { ...(result.contexts ?? {}), extra: dynamicContextFn() };\n if (isDefined(dynamicTagsFn)) {\n const dynamicTags = dynamicTagsFn();\n // eslint-disable-next-line functional/immutable-data\n Object.keys(dynamicTags).forEach((key: string): void => void (result.tags = { ...(result.tags ?? {}), [key]: dynamicTags[key] }));\n }\n}\n","import { HiddenField } from '@Anarchy/Tracking/Constants';\nimport type { ErrorEvent } from '@sentry/core';\n\nexport function scrubEvent(event: ErrorEvent): ErrorEvent {\n // eslint-disable-next-line functional/immutable-data\n if (!event.user) event.user = null as any;\n\n if (event.request) {\n // eslint-disable-next-line functional/immutable-data\n event.request = {\n ...event.request,\n url: HiddenField,\n headers: {\n ...event.request?.headers,\n url: HiddenField,\n Referer: HiddenField,\n referer: HiddenField\n }\n };\n\n delete (event.request.headers as any)?.Cookie;\n delete (event.request.headers as any)?.cookie;\n }\n\n // eslint-disable-next-line functional/immutable-data\n if ((event as any).contexts?.geo) delete (event as any).contexts.geo;\n // eslint-disable-next-line functional/immutable-data\n if ((event as any).contexts?.Geography) delete (event as any).contexts.Geography;\n // eslint-disable-next-line functional/immutable-data\n if ((event as any).contexts?.geography) delete (event as any).contexts.geography;\n\n // eslint-disable-next-line functional/immutable-data\n if (!event.breadcrumbs) event.breadcrumbs = undefined;\n\n return event;\n}\n"],"names":["HiddenField","isDefined","value","isString","mutateEventWithDynamicData","result","dynamicContextFn","dynamicTagsFn","contexts","extra","dynamicTags","Object","keys","forEach","key","tags","scrubEvent","event","user","request","url","headers","Referer","referer","Cookie","cookie","geo","Geography","geography","breadcrumbs"],"mappings":"AAAO,MAAMA,YAAc,SCAdC,UAAgBC,OAA+CA,YAQ/DC,SAAYD,OAAqD,iBAAVA,MCL7D,SAASE,2BAA2BC,OAAoBC,iBAA8CC,eAG3G,GADIN,UAAUK,oBAAmBD,OAAOG,SAAW,IAAMH,OAAOG,UAAY,CAAA,EAAKC,MAAOH,qBACpFL,UAAUM,eAAgB,CAC5B,MAAMG,YAAcH,gBAEpBI,OAAOC,KAAKF,aAAaG,QAASC,MAA4BT,OAAOU,KAAO,IAAMV,OAAOU,MAAQ,GAAKD,CAACA,KAAMJ,YAAYI,OAC3H,CACF,CCRO,SAASE,WAAWC,OA+BzB,OA7BKA,MAAMC,OAAMD,MAAMC,KAAO,MAE1BD,MAAME,UAERF,MAAME,QAAU,IACXF,MAAME,QACTC,IHXqB,SGYrBC,QAAS,IACJJ,MAAME,SAASE,QAClBD,IHdmB,SGenBE,QHfmB,SGgBnBC,QHhBmB,kBGoBfN,MAAME,QAAQE,SAAiBG,cAC/BP,MAAME,QAAQE,SAAiBI,QAIpCR,MAAcT,UAAUkB,YAAaT,MAAcT,SAASkB,IAE5DT,MAAcT,UAAUmB,kBAAmBV,MAAcT,SAASmB,UAElEV,MAAcT,UAAUoB,kBAAmBX,MAAcT,SAASoB,UAGlEX,MAAMY,cAAaZ,MAAMY,iBAAc,GAErCZ,KACT"}
@@ -0,0 +1,2 @@
1
+ import{i as isDefined,a as isString,H as HiddenField,s as scrubEvent,m as mutateEventWithDynamicData}from"../chunks/index.js";import{p as parseDistName}from"../chunks/TrackingUtils.js";import{rewriteFramesIntegration}from"@sentry/core";import os from"node:os";import{init,setTags,captureException}from"@sentry/electron/main";const toPosix=s=>s.replace(/\\/g,"/"),rewriteFramesIntegrationNode=options=>{let root=options?.root;try{!root&&"undefined"!=typeof process&&process.resourcesPath&&(root=process.resourcesPath),root||(root=__dirname)}catch{}const rootPosix=root?toPosix(root):void 0;return rewriteFramesIntegration({root:rootPosix,iteratee:frame=>{if(!frame||!frame.filename)return frame;const name=toPosix(frame.filename);if(name.startsWith("app:///"))return frame;if(rootPosix&&name.startsWith(rootPosix))return frame.filename="app:///"+name.slice(rootPosix.length).replace(/^\/+/,""),frame;const asarIdx=name.indexOf("/app.asar/");return asarIdx>=0?(frame.filename="app:///"+name.slice(asarIdx+10),frame):name.startsWith("file://")?(frame.filename="app:///"+name.replace(/^file:\/+/,""),frame):frame}})},homedir=os.homedir(),homeDirRegexp=new RegExp(homedir.replace(/\\/g,"/").replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g"),replaceInString=s=>"string"==typeof s?s.replace(/\\/g,"/").replace(homeDirRegexp,HiddenField):s;function scrubUserPathsDesktop(event){return event.message&&(event.message=replaceInString(event.message)),event.exception?.values?.forEach(value=>{value?.stacktrace?.frames?.forEach(f=>{f.filename=replaceInString(f.filename),f.abs_path=replaceInString(f.abs_path),f.module=replaceInString(f.module)}),value.value&&(value.value=replaceInString(value.value)),value.type&&(value.type=replaceInString(value.type))}),isDefined(event.extra)&&Object.entries(event.extra).forEach(([key,value])=>{isDefined(event.extra)&&isString(value)&&(event.extra[key]=replaceInString(value))}),event}function DesktopTrackingService(options,metaData,dynamicContextFn,dynamicTagsFn){let isStarted=!1;const defaultOptions={beforeSend(event,_hint){const result=scrubUserPathsDesktop(scrubEvent(event));return mutateEventWithDynamicData(result,dynamicContextFn,dynamicTagsFn),result},integrations:[rewriteFramesIntegrationNode()],tracesSampleRate:0,sendDefaultPii:!1};init({...defaultOptions,...options}),isDefined(metaData)&&setTags(metaData);const{platform:platform,arch:arch}=parseDistName(options?.dist);setTags({layer:"electron-main",errorTracker:"DesktopTrackingService",os:platform,arch:arch});const onError=ev=>{captureException(ev?.error??ev)},onRejection=ev=>{captureException(ev?.reason??ev)};function start(onErrorHandler=onError,onRejectionHandler=onRejection){isStarted||(isStarted=!0,process.on("uncaughtException",onErrorHandler),process.on("unhandledRejection",onRejectionHandler))}return start(),{captureException:captureException,start:start,stop:function(onErrorHandler=onError,onRejectionHandler=onRejection){isStarted=!1,process.off("uncaughtException",onErrorHandler),process.off("unhandledRejection",onRejectionHandler)},isStarted:()=>isStarted}}const desktop=Object.freeze(Object.defineProperty({__proto__:null,rewriteFramesIntegrationNode:rewriteFramesIntegrationNode,scrubUserPathsDesktop:scrubUserPathsDesktop},Symbol.toStringTag,{value:"Module"}));export{DesktopTrackingService,desktop as Utils};
2
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":["../../../anarchy-shared/src/Utils/FileUtils.ts","../../src/Utils/IntegrationsNode.ts","../../src/Utils/ScrubsDesktop.ts","../../src/Services/DesktopTrackingService.ts"],"sourcesContent":["import { FileSizes } from '@Anarchy/Shared/Constants';\n\nimport { isDefined } from './CheckUtils';\n\nexport function getHumanReadableMemorySize(bytes: number, decimals: number = 2): string {\n if (!+bytes) return '0 Bytes';\n const k: number = 1024;\n const dm: number = decimals < 0 ? 0 : decimals;\n\n const i: number = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${Object.values(FileSizes)[i]}`;\n}\n\nexport function getFileExtension(name: string): string | undefined {\n const extension: RegExpExecArray | null = /^.+\\.([^.]+)$/.exec(name);\n return isDefined(extension) ? extension[1] : undefined;\n}\n\nexport const toPosix = (s: string): string => s.replace(/\\\\/g, '/');\n","import { toPosix } from '@Anarchy/Shared/Utils';\nimport type { StackFrame } from '@sentry/core';\nimport { rewriteFramesIntegration } from '@sentry/core';\n\n//Important: if you use this, then upload source maps with --url-prefix \"app:///\"\nexport const rewriteFramesIntegrationNode = (options?: any): any => {\n let root = options?.root;\n\n try {\n if (!root && typeof process !== 'undefined' && (process as any).resourcesPath) {\n root = (process as any).resourcesPath as string;\n }\n if (!root) root = __dirname;\n } catch {\n // ignore\n }\n\n const rootPosix: string | undefined = root ? toPosix(root) : undefined;\n\n return rewriteFramesIntegration({\n root: rootPosix,\n // eslint-disable-next-line spellcheck/spell-checker\n iteratee: (frame: StackFrame): StackFrame => {\n if (!frame || !frame.filename) return frame;\n const name = toPosix(frame.filename);\n\n // Transform any absolute/file paths related to the app into app:///\n // 1) If SDK already made app:/// — leave it\n if (name.startsWith('app:///')) return frame;\n\n // 2) If the path is under root/resourcesPath - replace the prefix with app:///\n if (rootPosix && name.startsWith(rootPosix)) {\n // eslint-disable-next-line functional/immutable-data\n frame.filename = 'app:///' + name.slice(rootPosix.length).replace(/^\\/+/, '');\n return frame;\n }\n\n // 3) The path is inside asar\n const asarIdx: number = name.indexOf('/app.asar/');\n if (asarIdx >= 0) {\n // eslint-disable-next-line functional/immutable-data\n frame.filename = 'app:///' + name.slice(asarIdx + '/app.asar/'.length);\n return frame;\n }\n\n // 4) file:// URLs → app:///\n if (name.startsWith('file://')) {\n // eslint-disable-next-line functional/immutable-data\n frame.filename = 'app:///' + name.replace(/^file:\\/+/, '');\n return frame;\n }\n\n return frame;\n }\n });\n};\n","import os from 'node:os';\n\nimport { isDefined, isString } from '@Anarchy/Shared/Utils';\nimport { HiddenField } from '@Anarchy/Tracking/Constants';\nimport type { ErrorEvent } from '@sentry/electron/main';\n\nconst escape = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n// eslint-disable-next-line spellcheck/spell-checker\nconst homedir: string = os.homedir();\n// eslint-disable-next-line spellcheck/spell-checker\nconst homeDirRegexp: RegExp = new RegExp(escape(homedir.replace(/\\\\/g, '/')), 'g');\nconst replaceInString = (s?: string): string | undefined => (typeof s === 'string' ? s.replace(/\\\\/g, '/').replace(homeDirRegexp, HiddenField) : s);\n\nexport function scrubUserPathsDesktop(event: ErrorEvent): ErrorEvent {\n // eslint-disable-next-line functional/immutable-data\n if (event.message) event.message = replaceInString(event.message);\n\n event.exception?.values?.forEach((value: any): void => {\n value?.stacktrace?.frames?.forEach((f: any): void => {\n // eslint-disable-next-line functional/immutable-data\n f.filename = replaceInString(f.filename);\n // eslint-disable-next-line functional/immutable-data\n f.abs_path = replaceInString(f.abs_path);\n // eslint-disable-next-line functional/immutable-data\n f.module = replaceInString(f.module);\n });\n\n // eslint-disable-next-line functional/immutable-data\n if (value.value) value.value = replaceInString(value.value);\n // eslint-disable-next-line functional/immutable-data\n if (value.type) value.type = replaceInString(value.type);\n });\n\n if (isDefined(event.extra)) {\n Object.entries(event.extra).forEach(([key, value]): void => {\n // eslint-disable-next-line functional/immutable-data\n if (isDefined(event.extra) && isString(value)) event.extra[key] = replaceInString(value);\n });\n }\n\n return event;\n}\n","import { isDefined, parseDistName } from '@Anarchy/Shared/Utils';\nimport type { TMetaData, TTrackingService } from '@Anarchy/Tracking/Models';\nimport { mutateEventWithDynamicData } from '@Anarchy/Tracking/Utils/DynamicDataUtils';\nimport { rewriteFramesIntegrationNode } from '@Anarchy/Tracking/Utils/IntegrationsNode';\nimport { scrubEvent } from '@Anarchy/Tracking/Utils/ScrubEvent';\nimport { scrubUserPathsDesktop } from '@Anarchy/Tracking/Utils/ScrubsDesktop';\nimport type { Primitive } from '@sentry/core';\nimport type { ElectronMainOptions } from '@sentry/electron/esm/main';\nimport type { ErrorEvent, EventHint } from '@sentry/electron/main';\nimport { captureException, init, setTags } from '@sentry/electron/main';\n\nexport function DesktopTrackingService(\n options?: ElectronMainOptions,\n metaData?: TMetaData,\n dynamicContextFn?: () => Record<string, any>,\n dynamicTagsFn?: () => Record<string, Primitive>\n): TTrackingService {\n let isStarted: boolean = false;\n\n const defaultOptions: ElectronMainOptions = {\n beforeSend(event: ErrorEvent, _hint: EventHint): PromiseLike<ErrorEvent | null> | ErrorEvent | null {\n const result: ErrorEvent = scrubUserPathsDesktop(scrubEvent(event as any) as ErrorEvent);\n mutateEventWithDynamicData(result as any, dynamicContextFn, dynamicTagsFn);\n return result;\n },\n integrations: [rewriteFramesIntegrationNode()],\n tracesSampleRate: 0,\n //Important: make sure this is false if you want anonymous reports (no IPs, etc. for GDPR and similar acts).\n sendDefaultPii: false\n };\n\n init({\n ...defaultOptions,\n ...options\n });\n\n if (isDefined(metaData)) setTags(metaData);\n const { platform, arch } = parseDistName(options?.dist);\n setTags({\n layer: 'electron-main',\n errorTracker: 'DesktopTrackingService',\n os: platform,\n arch\n });\n\n const onError = (ev: any): void => void captureException(ev?.error ?? ev);\n const onRejection = (ev: PromiseRejectionEvent): void => void captureException((ev as PromiseRejectionEvent)?.reason ?? ev);\n\n function start(onErrorHandler: (ev: any) => void = onError, onRejectionHandler: (ev: PromiseRejectionEvent) => void = onRejection): void {\n if (isStarted) return;\n isStarted = true;\n process.on('uncaughtException', onErrorHandler);\n process.on('unhandledRejection', onRejectionHandler);\n }\n\n function stop(onErrorHandler: (ev: any) => void = onError, onRejectionHandler: (ev: PromiseRejectionEvent) => void = onRejection): void {\n isStarted = false;\n process.off('uncaughtException', onErrorHandler);\n process.off('unhandledRejection', onRejectionHandler);\n }\n\n start();\n\n return {\n captureException,\n start,\n stop,\n isStarted: () => isStarted\n };\n}\n"],"names":["toPosix","s","replace","rewriteFramesIntegrationNode","options","root","process","resourcesPath","__dirname","rootPosix","rewriteFramesIntegration","iteratee","frame","filename","name","startsWith","slice","length","asarIdx","indexOf","homedir","os","homeDirRegexp","RegExp","replaceInString","HiddenField","scrubUserPathsDesktop","event","message","exception","values","forEach","value","stacktrace","frames","f","abs_path","module","type","isDefined","extra","Object","entries","key","isString","DesktopTrackingService","metaData","dynamicContextFn","dynamicTagsFn","isStarted","defaultOptions","beforeSend","_hint","result","scrubEvent","mutateEventWithDynamicData","integrations","tracesSampleRate","sendDefaultPii","init","setTags","platform","arch","parseDistName","dist","layer","errorTracker","onError","ev","captureException","error","onRejection","reason","start","onErrorHandler","onRejectionHandler","on","stop","off"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{i as isDefined,s as scrubEvent,m as mutateEventWithDynamicData}from"../chunks/index.js";import{p as parseDistName}from"../chunks/TrackingUtils.js";import{r as rewriteFramesIntegrationBrowser,s as scrubUserPathsBrowser}from"../chunks/browser.js";export{b as Utils}from"../chunks/browser.js";import{init,setTags,captureException}from"@sentry/electron/renderer";function DesktopPreloadTrackingService(options,metaData,dynamicContextFn,dynamicTagsFn){let isStarted=!1;const defaultOptions={beforeSend(event,_hint){const result=scrubUserPathsBrowser(scrubEvent(event));return mutateEventWithDynamicData(result,dynamicContextFn,dynamicTagsFn),result},integrations:[rewriteFramesIntegrationBrowser()],tracesSampleRate:0,sendDefaultPii:!1};init({...defaultOptions,...options}),isDefined(metaData)&&setTags(metaData);const{platform:platform,arch:arch}=parseDistName(options?.dist);setTags({layer:"electron-preload",initLayer:"electron-preload",errorTracker:"DesktopPreloadTrackingService",errorTrackerInitializer:"DesktopPreloadTrackingService",os:platform,arch:arch});const onError=ev=>{captureException(ev?.error??ev)},onRejection=ev=>{captureException(ev?.reason??ev)};function start(onErrorHandler=onError,onRejectionHandler=onRejection){isStarted||(isStarted=!0,globalThis.window?.addEventListener?.("error",onErrorHandler),globalThis.window?.addEventListener?.("unhandledrejection",onRejectionHandler),globalThis.process?.on?.("uncaughtException",onErrorHandler),globalThis.process?.on?.("unhandledRejection",onRejectionHandler))}return start(),{captureException:captureException,start:start,stop:function(onErrorHandler=onError,onRejectionHandler=onRejection){isStarted=!1,globalThis.window?.removeEventListener?.("error",onErrorHandler),globalThis.window?.removeEventListener?.("unhandledrejection",onRejectionHandler),globalThis.process?.off?.("uncaughtException",onErrorHandler),globalThis.process?.off?.("unhandledRejection",onRejectionHandler)},isStarted:()=>isStarted}}export{DesktopPreloadTrackingService};
2
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":["../../src/Services/DesktopPreloadTrackingService.ts"],"sourcesContent":["import { isDefined, parseDistName } from '@Anarchy/Shared/Utils';\nimport type { TMetaData, TTrackingService } from '@Anarchy/Tracking/Models';\nimport { mutateEventWithDynamicData } from '@Anarchy/Tracking/Utils/DynamicDataUtils';\nimport { rewriteFramesIntegrationBrowser } from '@Anarchy/Tracking/Utils/IntegrationsBrowser';\nimport { scrubEvent } from '@Anarchy/Tracking/Utils/ScrubEvent';\nimport { scrubUserPathsBrowser } from '@Anarchy/Tracking/Utils/ScrubsBrowser';\nimport type { Integration, Primitive } from '@sentry/core';\nimport type { ErrorEvent, EventHint } from '@sentry/electron/renderer';\nimport { captureException, init, setTags } from '@sentry/electron/renderer';\n\nexport function DesktopPreloadTrackingService(\n options?: Record<string, any>,\n metaData?: TMetaData,\n dynamicContextFn?: () => Record<string, any>,\n dynamicTagsFn?: () => Record<string, Primitive>\n): TTrackingService {\n let isStarted: boolean = false;\n\n const defaultOptions = {\n beforeSend(event: ErrorEvent, _hint: EventHint): PromiseLike<ErrorEvent | null> | ErrorEvent | null {\n const result: ErrorEvent = scrubUserPathsBrowser(scrubEvent(event as any)) as ErrorEvent;\n mutateEventWithDynamicData(result as any, dynamicContextFn, dynamicTagsFn);\n return result;\n },\n integrations: [rewriteFramesIntegrationBrowser() as () => Integration],\n tracesSampleRate: 0,\n //Important: make sure this is false if you want anonymous reports (no IPs, etc. for GDPR and similar acts).\n sendDefaultPii: false\n };\n\n init({\n ...defaultOptions,\n ...options\n });\n\n if (isDefined(metaData)) setTags(metaData);\n const { platform, arch } = parseDistName(options?.dist);\n setTags({\n layer: 'electron-preload',\n initLayer: 'electron-preload',\n errorTracker: 'DesktopPreloadTrackingService',\n errorTrackerInitializer: 'DesktopPreloadTrackingService',\n os: platform,\n arch\n });\n\n const onError = (ev: any): void => void captureException(ev?.error ?? ev);\n const onRejection = (ev: PromiseRejectionEvent): void => void captureException((ev as PromiseRejectionEvent)?.reason ?? ev);\n\n function start(onErrorHandler: (ev: any) => void = onError, onRejectionHandler: (ev: PromiseRejectionEvent) => void = onRejection): void {\n if (isStarted) return;\n isStarted = true;\n\n globalThis.window?.addEventListener?.('error', onErrorHandler);\n globalThis.window?.addEventListener?.('unhandledrejection', onRejectionHandler);\n globalThis.process?.on?.('uncaughtException', onErrorHandler);\n globalThis.process?.on?.('unhandledRejection', onRejectionHandler);\n }\n\n function stop(onErrorHandler: (ev: any) => void = onError, onRejectionHandler: (ev: PromiseRejectionEvent) => void = onRejection): void {\n isStarted = false;\n globalThis.window?.removeEventListener?.('error', onErrorHandler);\n globalThis.window?.removeEventListener?.('unhandledrejection', onRejectionHandler);\n globalThis.process?.off?.('uncaughtException', onErrorHandler);\n globalThis.process?.off?.('unhandledRejection', onRejectionHandler);\n }\n\n start();\n\n return {\n captureException,\n start,\n stop,\n isStarted: () => isStarted\n };\n}\n"],"names":["DesktopPreloadTrackingService","options","metaData","dynamicContextFn","dynamicTagsFn","isStarted","defaultOptions","beforeSend","event","_hint","result","scrubUserPathsBrowser","scrubEvent","mutateEventWithDynamicData","integrations","rewriteFramesIntegrationBrowser","tracesSampleRate","sendDefaultPii","init","isDefined","setTags","platform","arch","parseDistName","dist","layer","initLayer","errorTracker","errorTrackerInitializer","os","onError","ev","captureException","error","onRejection","reason","start","onErrorHandler","onRejectionHandler","globalThis","window","addEventListener","process","on","stop","removeEventListener","off"],"mappings":"8WAUO,SAASA,8BACdC,QACAC,SACAC,iBACAC,eAEA,IAAIC,WAAqB,EAEzB,MAAMC,eAAiB,CACrB,UAAAC,CAAWC,MAAmBC,OAC5B,MAAMC,OAAqBC,sBAAsBC,WAAWJ,QAE5D,OADAK,2BAA2BH,OAAeP,iBAAkBC,eACrDM,MACT,EACAI,aAAc,CAACC,mCACfC,iBAAkB,EAElBC,gBAAgB,GAGlBC,KAAK,IACAZ,kBACAL,UAGDkB,UAAUjB,WAAWkB,QAAQlB,UACjC,MAAMmB,SAAEA,SAAAC,KAAUA,MAASC,cAActB,SAASuB,MAClDJ,QAAQ,CACNK,MAAO,mBACPC,UAAW,mBACXC,aAAc,gCACdC,wBAAyB,gCACzBC,GAAIR,SACJC,YAGF,MAAMQ,QAAWC,KAAuBC,iBAAiBD,IAAIE,OAASF,KAChEG,YAAeH,KAAyCC,iBAAkBD,IAA8BI,QAAUJ,KAExH,SAASK,MAAMC,eAAoCP,QAASQ,mBAA0DJ,aAChH7B,YACJA,WAAY,EAEZkC,WAAWC,QAAQC,mBAAmB,QAASJ,gBAC/CE,WAAWC,QAAQC,mBAAmB,qBAAsBH,oBAC5DC,WAAWG,SAASC,KAAK,oBAAqBN,gBAC9CE,WAAWG,SAASC,KAAK,qBAAsBL,oBACjD,CAYA,OAFAF,QAEO,CACLJ,kCACAI,YACAQ,KAbF,SAAcP,eAAoCP,QAASQ,mBAA0DJ,aACnH7B,WAAY,EACZkC,WAAWC,QAAQK,sBAAsB,QAASR,gBAClDE,WAAWC,QAAQK,sBAAsB,qBAAsBP,oBAC/DC,WAAWG,SAASI,MAAM,oBAAqBT,gBAC/CE,WAAWG,SAASI,MAAM,qBAAsBR,mBAClD,EAQEjC,UAAW,IAAMA,UAErB"}
@@ -0,0 +1,2 @@
1
+ export{H as HiddenField,m as mutateEventWithDynamicData,s as scrubEvent}from"../chunks/index.js";
2
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,47 @@
1
+ # Disclaimer of Warranty and Liability — @hellpig/anarchy-tracking
2
+
3
+ **Scope.** “Project” means the software, source code, binaries, documentation, and other materials in this repository or distribution package.
4
+
5
+ **No Legal Advice.** This document is **not** legal or regulatory advice. Applicability of laws depends on **your** specific product, market, and distribution model.
6
+
7
+ **No Warranty.** The Project is provided **“AS IS,” without warranty of any kind**, express or implied, including but not limited to **merchantability, fitness for a particular purpose, and non-infringement**, **to the maximum extent permitted by applicable law**.
8
+
9
+ **Limitation of Liability.** To the fullest extent permitted by law, Sergei Panfilov and contributors shall **not** be liable for any damages (including direct, indirect, incidental, special, exemplary, or consequential) arising from the use of, inability to use, or performance of the Project, even if advised of the possibility of such damages.
10
+
11
+ **Statutory consumer rights are not affected.** Nothing in this disclaimer excludes or limits liability where such exclusion or limitation is unlawful (including for **death or personal injury**, **fraud**, or **wilful misconduct**).
12
+
13
+ ## Regulatory Compliance Notice
14
+
15
+ This repository is a **project** and **is not, by itself, a product placed on any market**. Publishing this repository does **not** make Sergei Panfilov a “manufacturer” under product-safety or cybersecurity regimes.
16
+
17
+ If **you** place a product on the market using the Project, **you** are responsible for compliance (e.g., product safety/cybersecurity such as the EU **CRA**, privacy/data protection such as **GDPR/UK-GDPR, CPRA, LGPD, PIPEDA, Australia Privacy Act, PIPL**, consumer protection, export/sanctions).
18
+
19
+ Where Sergei Panfilov distributes **commercial binaries**, obligations (including security support and vulnerability handling) are addressed in the accompanying documents: see `SECURITY` and `SUPPORT`.
20
+
21
+ ## Export Controls and Sanctions
22
+
23
+ The Project may be subject to **export control, re-export, and sanctions** laws and regulations (including those of the **EU**, **US**, **UK**, and other jurisdictions). You are responsible for complying with all applicable restrictions and for **not** using, exporting, re-exporting, or transferring the Project **(i)** to any **sanctioned or restricted** person, entity, or destination, or **(ii)** for any prohibited end use under applicable law.
24
+
25
+ ## Not for Safety-Critical Use
26
+
27
+ **High-Risk Use Prohibition.** The Project **must not** be used in safety-critical contexts (including medical, aviation, nuclear, military, or critical infrastructure) where failure could lead to death, personal injury, or severe environmental or property damage. Any such use is **strictly prohibited**.
28
+
29
+ ## Third-Party Components (License Precedence)
30
+
31
+ The Project may include or interface with **third-party open-source components**. Such components are licensed under their **own** terms. **If there is a conflict between this disclaimer/EULA and an OSS license for a specific component, the OSS license controls for that component.** See `NOTICE` / `THIRD_PARTY_LICENSES`.
32
+
33
+ ## Accessibility (EAA and similar)
34
+
35
+ Where required by applicable law (e.g., the **EU Accessibility Act**), we aim to address **accessibility feedback** for distributed binaries **within reasonable and proportionate limits**. Contact: **TBD until market release**. This section **does not** create service levels or guarantees.
36
+
37
+ ## Security and Support
38
+
39
+ This project is maintained **without any commitment** to provide support, maintenance, updates, or security fixes.
40
+
41
+ For distributed binaries (if any), see `SECURITY` for the **coordinated vulnerability disclosure** process.
42
+
43
+ ## Modifications
44
+
45
+ We may update this disclaimer by committing changes to this repository or shipping updates with the product. Continued use after changes are posted constitutes acceptance of the revised terms.
46
+
47
+ **Governing Law.** Subject to mandatory consumer protection laws, this disclaimer is governed by the laws of **The Netherlands** with venue in **Amsterdam**.
package/legal/EULA.md ADDED
@@ -0,0 +1,18 @@
1
+ # End User License Terms — @hellpig/anarchy-tracking
2
+
3
+ **Effective date:** TBD until market release
4
+ This repository is provided under **MIT** (see `LICENSE`).
5
+
6
+ 1. **License & Ownership.** The code is licensed, not sold. Copyrights remain with the authors.
7
+ 2. **Not a Market Placement by Maintainers.** This repository is **not** a product “placed on the market.” If **you** incorporate it into a **product**, **you** are responsible for compliance with product-safety, cybersecurity (e.g., EU CRA), privacy/data-protection, consumer, and export/sanctions laws.
8
+ 3. **No Support Obligation.** The maintainers provide the project **without support commitments or SLAs**. See `SECURITY` for reporting.
9
+ 4. **Third-Party Components (License Precedence).** Dependencies retain their own licenses and notices. **If this text ever conflicts with a third-party license for a specific component, that third-party license governs for that component.** See `NOTICE` / `THIRD_PARTY_LICENSES`.
10
+ 5. **No Warranty / Liability.** Provided **“AS IS”**, **to the extent permitted by law**, without warranties; **statutory consumer rights (if any) are not affected**.
11
+
12
+ **Accessibility.** Where required by law, we aim to address **accessibility feedback** for officially published artifacts **within reasonable and proportionate limits**. Contact: **TBD until market release**. This section does **not** create service levels or guarantees.
13
+
14
+ ## Governing Language
15
+
16
+ This agreement is drafted in English. Translations may be provided for convenience. In consumer markets where local-language versions are required by law for clarity and fairness, the local-language version controls to the extent required by applicable law; otherwise, the English version controls.
17
+
18
+ For license terms, see `LICENSE`.