@royaltics/tracker-sails 0.0.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/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # @royaltics/tracker-sails
2
+
3
+ > Sails.js hook for Royaltics Error Tracker
4
+
5
+ ## Features
6
+
7
+ - ✅ **Sails.js Integration**: Native hook implementation
8
+ - ✅ **Automatic Request Tracking**: Capture all HTTP requests
9
+ - ✅ **Error Middleware**: Automatic error capture
10
+ - ✅ **Route Filtering**: Ignore specific routes
11
+ - ✅ **Configurable**: Full control over what gets tracked
12
+ - ✅ **TypeScript Support**: Full type definitions
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pnpm add @royaltics/tracker-sails
18
+ # or
19
+ npm install @royaltics/tracker-sails
20
+ # or
21
+ yarn add @royaltics/tracker-sails
22
+ ```
23
+
24
+ ## Configuration
25
+
26
+ Create or update `config/errorTracker.js`:
27
+
28
+ ```javascript
29
+ module.exports.errorTracker = {
30
+ webhookUrl: process.env.ERROR_TRACKER_WEBHOOK_URL,
31
+ licenseId: process.env.ERROR_TRACKER_LICENSE_ID,
32
+ licenseDevice: process.env.ERROR_TRACKER_DEVICE || 'sails-server',
33
+ licenseName: 'My Company',
34
+ app: 'my-sails-app',
35
+ version: '1.0.0',
36
+
37
+ // Optional: Capture settings
38
+ captureRoutes: true,
39
+ captureQueries: true,
40
+ captureHeaders: false,
41
+
42
+ // Optional: Filtering
43
+ ignoredRoutes: [
44
+ '/health',
45
+ '/metrics',
46
+ '^/api/internal/.*'
47
+ ],
48
+
49
+ ignoredErrors: [
50
+ 'ValidationError',
51
+ 'NotFoundError'
52
+ ],
53
+
54
+ // Optional: Advanced settings
55
+ enabled: true,
56
+ maxRetries: 3,
57
+ timeout: 10000,
58
+ flushInterval: 5000,
59
+ maxQueueSize: 50
60
+ };
61
+ ```
62
+
63
+ ## Usage
64
+
65
+ ### Install the Hook
66
+
67
+ In `config/hooks.js`:
68
+
69
+ ```javascript
70
+ module.exports.hooks = {
71
+ errorTracker: require('@royaltics/tracker-sails').errorTracker
72
+ };
73
+ ```
74
+
75
+ ### Automatic Error Tracking
76
+
77
+ The hook automatically captures:
78
+
79
+ - Uncaught exceptions
80
+ - Unhandled promise rejections
81
+ - Route errors
82
+ - Request errors
83
+
84
+ ### Manual Error Tracking
85
+
86
+ ```javascript
87
+ // In a controller or service
88
+ module.exports = {
89
+ async someAction(req, res) {
90
+ try {
91
+ // Your code
92
+ } catch (error) {
93
+ sails.hooks.errorTracker.client.error(error, 'ERROR', {
94
+ userId: req.session.userId,
95
+ action: 'someAction'
96
+ });
97
+
98
+ return res.serverError(error);
99
+ }
100
+ }
101
+ };
102
+ ```
103
+
104
+ ### Track Custom Events
105
+
106
+ ```javascript
107
+ sails.hooks.errorTracker.client.event('User registered', 'INFO', {
108
+ userId: user.id,
109
+ email: user.email
110
+ });
111
+ ```
112
+
113
+ ## Configuration Options
114
+
115
+ ### Required
116
+
117
+ | Option | Type | Description |
118
+ |--------|------|-------------|
119
+ | `webhookUrl` | `string` | HTTP/HTTPS webhook URL |
120
+ | `licenseId` | `string` | Your license ID |
121
+ | `licenseDevice` | `string` | Device identifier |
122
+
123
+ ### Optional
124
+
125
+ | Option | Type | Default | Description |
126
+ |--------|------|---------|-------------|
127
+ | `licenseName` | `string` | `undefined` | License name |
128
+ | `app` | `string` | `undefined` | Application name |
129
+ | `version` | `string` | `undefined` | Application version |
130
+ | `captureRoutes` | `boolean` | `false` | Capture all route requests |
131
+ | `captureQueries` | `boolean` | `false` | Include query parameters |
132
+ | `captureHeaders` | `boolean` | `false` | Include request headers |
133
+ | `ignoredRoutes` | `string[]` | `[]` | Routes to ignore (regex patterns) |
134
+ | `ignoredErrors` | `string[]` | `[]` | Errors to ignore (regex patterns) |
135
+ | `enabled` | `boolean` | `true` | Enable/disable tracking |
136
+ | `maxRetries` | `number` | `3` | Max retry attempts |
137
+ | `timeout` | `number` | `10000` | Request timeout in ms |
138
+ | `flushInterval` | `number` | `5000` | Batch flush interval in ms |
139
+ | `maxQueueSize` | `number` | `50` | Max events before auto-flush |
140
+
141
+ ## Examples
142
+
143
+ ### Environment Variables
144
+
145
+ ```bash
146
+ ERROR_TRACKER_WEBHOOK_URL=https://api.example.com/webhook
147
+ ERROR_TRACKER_LICENSE_ID=your-license-id
148
+ ERROR_TRACKER_DEVICE=production-server-01
149
+ ```
150
+
151
+ ### Ignore Health Check Routes
152
+
153
+ ```javascript
154
+ module.exports.errorTracker = {
155
+ // ... other config
156
+ ignoredRoutes: [
157
+ '/health',
158
+ '/ping',
159
+ '/metrics',
160
+ '^/api/internal/.*'
161
+ ]
162
+ };
163
+ ```
164
+
165
+ ### Capture Only Errors
166
+
167
+ ```javascript
168
+ module.exports.errorTracker = {
169
+ // ... other config
170
+ captureRoutes: false, // Don't track successful requests
171
+ captureQueries: true, // But include query params in errors
172
+ captureHeaders: false // Don't include headers
173
+ };
174
+ ```
175
+
176
+ ## TypeScript
177
+
178
+ ```typescript
179
+ import { SailsErrorTrackerConfig } from '@royaltics/tracker-sails';
180
+
181
+ const config: SailsErrorTrackerConfig = {
182
+ webhookUrl: 'https://api.example.com/webhook',
183
+ licenseId: 'your-license-id',
184
+ licenseDevice: 'server-01',
185
+ captureRoutes: true
186
+ };
187
+ ```
188
+
189
+ ## License
190
+
191
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";const u=require("@royaltics/tracker");module.exports=function(e){let t;return{defaults:{__configKey__:{enabled:!0,webhookUrl:"N/A",licenseId:"",licenseDevice:"",licenseName:"",app:"sails-app",version:"",platform:"sails",maxRetries:3,timeout:1e4,flushInterval:1e4,maxQueueSize:100,headers:{}}},initialize:function(o){const i=e.config.tracker||{};if(!i.enabled)return e.log.warn("@royaltics/tracker-sails hook deactivated"),o();if(!i.webhookUrl)return e.log.error("DSN for @royaltics/tracker-sails is required in config/tracker.js"),o();try{i.debug&&e.log.info("Initializing @royaltics/tracker-sails..."),t=u.create(i),e.tracker=t,i.debug&&e.log.info("@royaltics/tracker-sails initialized successfully"),process.on("unhandledRejection",function(n){i.debug&&e.log.info("Unhandled rejection:",n),t==null||t.error(n instanceof Error?n:new Error(String(n)))}),i.captureRoutes&&c(e,t,i),i.debug&&e.log.info("@royaltics/tracker-sails initialized successfully")}catch(n){i.debug&&e.log.error("Failed to initialize @royaltics/tracker-sails:",n)}return o()},shutdown:function(o){t&&u.shutdown(),o()}}};function c(r,e,t){r.on&&(r.on("router:request",(o,i)=>{if(a(o.url,["https://sailsjs.com","https://api.royaltics.com"]))return;const n=s(o,t);e.event("Request received","INFO",{request:n})}),r.on("router:request:error",(o,i)=>{if(t.ignoredErrors||l(o,["SailsError","RoyalticsError"]))return;const n=s(i,t);e.error(o,"ERROR",{request:n})}))}function s(r,e){return{method:r.method??"UNKNOWN",url:r.url??"UNKNOWN",ip:r.ip,headers:e.captureHeaders?r.headers:void 0,query:e.captureQueries?r.query:void 0,body:e.captureQueries?r.body:void 0}}function a(r,e){return e?e.some(t=>new RegExp(t).test(r)):!1}function l(r,e){return e?e.some(t=>{const o=new RegExp(t);return o.test(r.name)||o.test(r.message)}):!1}
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,75 @@
1
+ var c = (r, e) => () => (e || r((e = { exports: {} }).exports, e), e.exports);
2
+ import u from "@royaltics/tracker";
3
+ var g = c((y, a) => {
4
+ a.exports = function(e) {
5
+ let t;
6
+ return {
7
+ defaults: {
8
+ __configKey__: {
9
+ enabled: !0,
10
+ webhookUrl: "N/A",
11
+ licenseId: "",
12
+ licenseDevice: "",
13
+ licenseName: "",
14
+ app: "sails-app",
15
+ version: "",
16
+ platform: "sails",
17
+ maxRetries: 3,
18
+ timeout: 1e4,
19
+ flushInterval: 1e4,
20
+ maxQueueSize: 100,
21
+ headers: {}
22
+ }
23
+ },
24
+ initialize: function(o) {
25
+ const i = e.config.tracker || {};
26
+ if (!i.enabled)
27
+ return e.log.warn("@royaltics/tracker-sails hook deactivated"), o();
28
+ if (!i.webhookUrl)
29
+ return e.log.error("DSN for @royaltics/tracker-sails is required in config/tracker.js"), o();
30
+ try {
31
+ i.debug && e.log.info("Initializing @royaltics/tracker-sails..."), t = u.create(i), e.tracker = t, i.debug && e.log.info("@royaltics/tracker-sails initialized successfully"), process.on("unhandledRejection", function(n) {
32
+ i.debug && e.log.info("Unhandled rejection:", n), t == null || t.error(n instanceof Error ? n : new Error(String(n)));
33
+ }), i.captureRoutes && l(e, t, i), i.debug && e.log.info("@royaltics/tracker-sails initialized successfully");
34
+ } catch (n) {
35
+ i.debug && e.log.error("Failed to initialize @royaltics/tracker-sails:", n);
36
+ }
37
+ return o();
38
+ },
39
+ shutdown: function(o) {
40
+ t && u.shutdown(), o();
41
+ }
42
+ };
43
+ };
44
+ function l(r, e, t) {
45
+ r.on && (r.on("router:request", (o, i) => {
46
+ if (d(o.url, ["https://sailsjs.com", "https://api.royaltics.com"])) return;
47
+ const n = s(o, t);
48
+ e.event("Request received", "INFO", { request: n });
49
+ }), r.on("router:request:error", (o, i) => {
50
+ if (t.ignoredErrors || f(o, ["SailsError", "RoyalticsError"])) return;
51
+ const n = s(i, t);
52
+ e.error(o, "ERROR", { request: n });
53
+ }));
54
+ }
55
+ function s(r, e) {
56
+ return {
57
+ method: r.method ?? "UNKNOWN",
58
+ url: r.url ?? "UNKNOWN",
59
+ ip: r.ip,
60
+ headers: e.captureHeaders ? r.headers : void 0,
61
+ query: e.captureQueries ? r.query : void 0,
62
+ body: e.captureQueries ? r.body : void 0
63
+ };
64
+ }
65
+ function d(r, e) {
66
+ return e ? e.some((t) => new RegExp(t).test(r)) : !1;
67
+ }
68
+ function f(r, e) {
69
+ return e ? e.some((t) => {
70
+ const o = new RegExp(t);
71
+ return o.test(r.name) || o.test(r.message);
72
+ }) : !1;
73
+ }
74
+ });
75
+ export default g();
@@ -0,0 +1,30 @@
1
+ import type { ClientConfig, ErrorTrackerClient } from '@royaltics/tracker';
2
+ export interface SailsErrorTrackerConfig extends Omit<ClientConfig, 'platform' | 'app'> {
3
+ readonly captureRoutes?: boolean;
4
+ readonly captureQueries?: boolean;
5
+ readonly captureHeaders?: boolean;
6
+ readonly ignoredRoutes?: readonly string[];
7
+ readonly ignoredErrors?: readonly string[];
8
+ }
9
+ export interface SailsHookContext {
10
+ readonly sails: {
11
+ readonly config: {
12
+ readonly tracker: SailsErrorTrackerConfig;
13
+ };
14
+ readonly log: {
15
+ error: (message: string, ...args: unknown[]) => void;
16
+ warn: (message: string, ...args: unknown[]) => void;
17
+ info: (message: string, ...args: unknown[]) => void;
18
+ };
19
+ on?: (event: string, handler: (...args: any[]) => void) => void;
20
+ tracker?: ErrorTrackerClient;
21
+ };
22
+ }
23
+ export interface RequestContext {
24
+ readonly method: string;
25
+ readonly url: string;
26
+ readonly ip?: string;
27
+ readonly headers?: Record<string, string>;
28
+ readonly query?: Record<string, unknown>;
29
+ readonly body?: Record<string, unknown>;
30
+ }
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@royaltics/tracker-sails",
3
+ "version": "0.0.1",
4
+ "description": "Sails.js hook for Royaltics Error Tracker",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "private": false,
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs",
17
+ "types": "./dist/index.d.ts"
18
+ }
19
+ },
20
+ "scripts": {
21
+ "build": "vite build && tsc --emitDeclarationOnly",
22
+ "test": "vitest",
23
+ "test:coverage": "vitest --coverage",
24
+ "prepublishOnly": "npm run build",
25
+ "publish": "npm publish"
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/royaltics-solutions/royaltics-solutions-tracker"
35
+ },
36
+ "keywords": [
37
+ "sails",
38
+ "sailsjs",
39
+ "tracker",
40
+ "monitoring",
41
+ "logging"
42
+ ],
43
+ "sails": {
44
+ "isHook": true
45
+ },
46
+ "peerDependencies": {
47
+ "sails": "^1.0.0"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20.0.0",
51
+ "@vitest/coverage-v8": "^1.0.0",
52
+ "typescript": "^5.0.0",
53
+ "vite": "^5.0.0",
54
+ "vite-plugin-dts": "^3.0.0",
55
+ "vitest": "^1.0.0"
56
+ },
57
+ "dependencies": {
58
+ "@royaltics/tracker": "^0.0.3"
59
+ }
60
+ }