securenow 7.7.14 → 7.7.16

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/nextjs.js CHANGED
@@ -35,8 +35,6 @@ const appConfig = require('./app-config');
35
35
  const { resolveClientIpWithDetails } = require('./resolve-ip');
36
36
  const otelResources = require('@opentelemetry/resources');
37
37
 
38
- const env = appConfig.env;
39
-
40
38
  let isRegistered = false;
41
39
 
42
40
  function requireRuntimeModule(name) {
@@ -126,7 +124,7 @@ function redactGraphQLQuery(query, sensitiveFields = DEFAULT_SENSITIVE_FIELDS) {
126
124
  * Register SecureNow OpenTelemetry for Next.js using @vercel/otel
127
125
  * @param {Object} options - Optional configuration
128
126
  * @param {string} options.serviceName - Service name (defaults to .securenow/credentials.json app.key/app.name)
129
- * @param {string} options.endpoint - Traces endpoint (defaults to .securenow/credentials.json app.instance)
127
+ * @param {string} options.endpoint - Advanced OTLP endpoint override (defaults to the SecureNow ingest gateway)
130
128
  * @param {string} options.environment - deployment.environment override (defaults to config.runtime.deploymentEnvironment)
131
129
  * @param {boolean} options.noUuid - Don't append UUID to service name
132
130
  */
@@ -144,24 +142,26 @@ function registerSecureNow(options = {}) {
144
142
  }
145
143
 
146
144
  // Detect environment outside try block for error handling
147
- const isVercel = !!(env('VERCEL') || env('VERCEL_ENV') || env('VERCEL_URL'));
145
+ const isVercel = !!(process.env.VERCEL || process.env.VERCEL_ENV || process.env.VERCEL_URL);
148
146
  let deploymentEnvironment = appConfig.resolveDeploymentEnvironment();
149
147
 
150
148
  try {
151
149
  console.log('[securenow] Next.js integration loading (pid=%d)', process.pid);
152
150
 
153
151
  // -------- Configuration --------
154
- // Resolution order: explicit options -> .securenow/credentials.json -> legacy env fallback -> package.json#name
152
+ // Resolution order: explicit options -> .securenow/credentials.json -> package.json#name.
153
+ // Telemetry goes to the stable ingest gateway by default; the API gateway
154
+ // routes by app.key to the dashboard-selected instance.
155
155
  const resolvedApp = appConfig.resolveAll();
156
156
 
157
157
  const rawBase = (options.serviceName || resolvedApp.appId || '').trim().replace(/^['"]|['"]$/g, '');
158
158
  const baseName = rawBase || null;
159
159
  // Default: auto-disable suffix when logged in (appId is the routing UUID
160
- // and the dashboard does exact match). opts.noUuid or SECURENOW_NO_UUID
161
- // override.
160
+ // and the dashboard does exact match). opts.noUuid or config.runtime.noUuid
161
+ // can still override.
162
162
  const noUuid = appConfig.resolveNoUuid({ noUuid: options.noUuid });
163
163
  deploymentEnvironment = appConfig.normalizeDeploymentEnvironment(
164
- options.environment || resolvedApp.deploymentEnvironment || env('VERCEL_ENV')
164
+ options.environment || resolvedApp.deploymentEnvironment
165
165
  );
166
166
 
167
167
  // service.name
@@ -170,7 +170,7 @@ function registerSecureNow(options = {}) {
170
170
  serviceName = noUuid ? baseName : `${baseName}-${randomUUID()}`;
171
171
  } else {
172
172
  serviceName = `nextjs-app-${randomUUID()}`;
173
- console.warn('[securenow] ⚠️ No app identity resolved. Using fallback: %s', serviceName);
173
+ console.warn('[securenow] No app identity resolved. Using fallback: %s', serviceName);
174
174
  console.warn('[securenow] Run `npx securenow login` and `npx securenow init` to write .securenow/credentials.json');
175
175
  }
176
176
 
@@ -180,24 +180,32 @@ function registerSecureNow(options = {}) {
180
180
  const tracesUrl = resolvedEndpoints.tracesUrl;
181
181
  const logsUrl = resolvedEndpoints.logsUrl;
182
182
  const headers = resolvedEndpoints.headers;
183
+ const otelLogLevel = String(appConfig.configValue('otel.logLevel', '') || '').toLowerCase();
184
+ const isDevelopmentRuntime = process.env.NODE_ENV === 'development';
183
185
 
184
- if (!process.env.OTEL_SERVICE_NAME) process.env.OTEL_SERVICE_NAME = serviceName;
185
- if (!process.env.OTEL_EXPORTER_OTLP_ENDPOINT) process.env.OTEL_EXPORTER_OTLP_ENDPOINT = endpointBase;
186
- if (!process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = tracesUrl;
186
+ // @vercel/otel still reads OTel process variables internally. These are
187
+ // derived from credentials JSON; customers do not set them.
188
+ if (isVercel) {
189
+ if (!process.env.OTEL_SERVICE_NAME) process.env.OTEL_SERVICE_NAME = serviceName;
190
+ if (!process.env.OTEL_EXPORTER_OTLP_ENDPOINT) process.env.OTEL_EXPORTER_OTLP_ENDPOINT = endpointBase;
191
+ if (!process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = tracesUrl;
192
+ const headerString = appConfig.headersToString(headers);
193
+ if (headerString && !process.env.OTEL_EXPORTER_OTLP_HEADERS) process.env.OTEL_EXPORTER_OTLP_HEADERS = headerString;
194
+ }
187
195
 
188
196
  console.log('[securenow] Next.js App -> service.name=%s', serviceName);
189
197
  console.log('[securenow] Environment: %s', deploymentEnvironment);
190
198
 
191
199
  // -------- Body Capture Configuration --------
192
200
  // Opt-out default: set config.capture.body=false (or options.captureBody=false) to disable.
193
- const captureBody = options.captureBody ?? !/^(0|false)$/i.test(String(env('SECURENOW_CAPTURE_BODY') ?? ''));
194
- const maxBodySize = Math.max(1024, parseInt(env('SECURENOW_MAX_BODY_SIZE'), 10) || 10240);
195
- const customSensitiveFields = (env('SECURENOW_SENSITIVE_FIELDS') || '').split(',').map(s => s.trim()).filter(Boolean);
201
+ const captureBody = options.captureBody ?? appConfig.boolConfig('capture.body', true);
202
+ const maxBodySize = appConfig.numberConfig('capture.maxBodySize', 10240, 1024);
203
+ const customSensitiveFields = appConfig.listConfig('capture.sensitiveFields');
196
204
  const allSensitiveFields = [...DEFAULT_SENSITIVE_FIELDS, ...customSensitiveFields];
197
205
 
198
206
  // -------- Log environment detection --------
199
207
  if (!isVercel) {
200
- console.log('[securenow] 🖥️ Self-hosted environment detected (EC2/PM2) - using vanilla SDK');
208
+ console.log('[securenow] Self-hosted environment detected (EC2/PM2) - using vanilla SDK');
201
209
  }
202
210
 
203
211
  // -------- Use different initialization based on environment --------
@@ -331,8 +339,8 @@ function registerSecureNow(options = {}) {
331
339
  }
332
340
 
333
341
  // Debug log in development
334
- if (env('NODE_ENV') === 'development' || env('OTEL_LOG_LEVEL') === 'debug') {
335
- console.log('[securenow] 📡 Captured IP: %s (from: %s)',
342
+ if (isDevelopmentRuntime || otelLogLevel === 'debug') {
343
+ console.log('[securenow] Captured IP: %s (from: %s)',
336
344
  primaryIp,
337
345
  ipDetails.source || 'unknown'
338
346
  );
@@ -345,8 +353,8 @@ function registerSecureNow(options = {}) {
345
353
 
346
354
  } catch (error) {
347
355
  // Silently fail to not break the request
348
- if (env('OTEL_LOG_LEVEL') === 'debug') {
349
- console.error('[securenow] ⚠️ Error in requestHook:', error.message);
356
+ if (otelLogLevel === 'debug') {
357
+ console.error('[securenow] Error in requestHook:', error.message);
350
358
  }
351
359
  }
352
360
  },
@@ -370,11 +378,11 @@ function registerSecureNow(options = {}) {
370
378
  // the remote end (ECONNRESET / "socket hang up"). These transient errors
371
379
  // sometimes escape as unhandled exceptions or rejections. We catch them
372
380
  // here and log at debug level instead of crashing the host app.
373
- const _TRANSIENT_CODES = new Set(['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'EPIPE', 'EAI_AGAIN']);
381
+ const _TRANSIENT_CODES = new Set(['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'EPIPE', 'EAI_AGAIN', 'ENOTFOUND']);
374
382
  function _isOtlpTransientError(err) {
375
383
  if (!err) return false;
376
384
  if (_TRANSIENT_CODES.has(err.code)) return true;
377
- if (typeof err.message === 'string' && /socket hang up|ECONNRESET/.test(err.message)) return true;
385
+ if (typeof err.message === 'string' && /socket hang up|ECONNRESET|ECONNREFUSED|ENOTFOUND|EAI_AGAIN|timed out/i.test(err.message)) return true;
378
386
  return false;
379
387
  }
380
388
  function _looksLikeOtlpStack(err) {
@@ -383,21 +391,53 @@ function registerSecureNow(options = {}) {
383
391
  return /OTLPTraceExporter|OTLPLogExporter|otlp|exporter.*http|BatchSpanProcessor|BatchLogRecordProcessor/i.test(s)
384
392
  || /node:_http_client|ClientRequest|TLSSocket/i.test(s);
385
393
  }
386
- const _diagDebug = (env('OTEL_LOG_LEVEL') || '').toLowerCase() === 'debug';
394
+ function _looksLikeConfiguredOtlpEndpoint(err) {
395
+ const text = `${err && err.hostname || ''} ${err && err.host || ''} ${err && err.message || ''}`;
396
+ try {
397
+ const hosts = [new URL(tracesUrl).hostname, new URL(logsUrl).hostname].filter(Boolean);
398
+ return hosts.some((host) => host && text.includes(host));
399
+ } catch (_) {
400
+ return false;
401
+ }
402
+ }
403
+ const _diagDebug = otelLogLevel === 'debug';
404
+ let _lastSuppressedOtlpErrorLogAt = 0;
405
+ function _originalConsole(method) {
406
+ const originals = console.__securenow_original || console.__securenowOriginalConsole;
407
+ return (originals && originals[method]) || console[method] || console.log;
408
+ }
409
+ function _formatOtlpError(err) {
410
+ if (!err) return 'unknown error';
411
+ const parts = [err.message || String(err)];
412
+ if (err.code && !parts[0].includes(err.code)) parts.push(`code=${err.code}`);
413
+ if (err.syscall) parts.push(`syscall=${err.syscall}`);
414
+ if (err.hostname) parts.push(`host=${err.hostname}`);
415
+ return parts.join(' ');
416
+ }
417
+ function _reportSuppressedOtlpError(kind, err, origin) {
418
+ if (otelLogLevel === 'none') return;
419
+ const now = Date.now();
420
+ if (!_diagDebug && now - _lastSuppressedOtlpErrorLogAt < 60_000) return;
421
+ _lastSuppressedOtlpErrorLogAt = now;
422
+ const method = _diagDebug ? 'debug' : 'error';
423
+ _originalConsole(method).call(
424
+ console,
425
+ '[securenow] OTLP exporter %s suppressed (%s). Telemetry may be missing until the ingest endpoint is reachable: %s',
426
+ kind,
427
+ origin || 'async',
428
+ _formatOtlpError(err)
429
+ );
430
+ }
387
431
  process.on('uncaughtException', (err, origin) => {
388
- if (_isOtlpTransientError(err) && _looksLikeOtlpStack(err)) {
389
- if (_diagDebug) {
390
- console.debug('[securenow] Suppressed transient OTLP exporter error (%s): %s', origin, err.message);
391
- }
432
+ if (_isOtlpTransientError(err) && (_looksLikeOtlpStack(err) || _looksLikeConfiguredOtlpEndpoint(err))) {
433
+ _reportSuppressedOtlpError('error', err, origin);
392
434
  return;
393
435
  }
394
436
  throw err;
395
437
  });
396
438
  process.on('unhandledRejection', (reason) => {
397
- if (_isOtlpTransientError(reason) && _looksLikeOtlpStack(reason)) {
398
- if (_diagDebug) {
399
- console.debug('[securenow] Suppressed transient OTLP exporter rejection: %s', reason && reason.message);
400
- }
439
+ if (_isOtlpTransientError(reason) && (_looksLikeOtlpStack(reason) || _looksLikeConfiguredOtlpEndpoint(reason))) {
440
+ _reportSuppressedOtlpError('rejection', reason, 'unhandledRejection');
401
441
  return;
402
442
  }
403
443
  throw reason;
@@ -455,11 +495,11 @@ function registerSecureNow(options = {}) {
455
495
  });
456
496
 
457
497
  sdk.start();
458
- console.log('[securenow] 🎯 Vanilla SDK initialized for self-hosted environment');
498
+ console.log('[securenow] Vanilla SDK initialized for self-hosted environment');
459
499
 
460
500
  // -------- Logging (self-hosted only) --------
461
501
  // Opt-out default: set config.logging.enabled=false to disable.
462
- const loggingEnabled = !/^(0|false)$/i.test(String(env('SECURENOW_LOGGING_ENABLED') ?? ''));
502
+ const loggingEnabled = appConfig.boolConfig('logging.enabled', true);
463
503
  if (loggingEnabled) {
464
504
  try {
465
505
  const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
@@ -511,7 +551,7 @@ function registerSecureNow(options = {}) {
511
551
  _emitLog(SeverityNumber.ERROR, 'ERROR', args);
512
552
  };
513
553
 
514
- console.log('[securenow] 📋 Logging: ENABLED %s', logsUrl);
554
+ console.log('[securenow] Logging: ENABLED -> %s', logsUrl);
515
555
 
516
556
  // Auto-log every incoming HTTP request/response
517
557
  try {
@@ -559,51 +599,51 @@ function registerSecureNow(options = {}) {
559
599
  }
560
600
  return originalEmit.apply(this, arguments);
561
601
  };
562
- console.log('[securenow] 📋 HTTP request logging: ENABLED');
602
+ console.log('[securenow] HTTP request logging: ENABLED');
563
603
  } catch (_) {}
564
604
 
565
605
  // Graceful shutdown for logs
566
606
  process.on('SIGTERM', async () => { try { await loggerProvider.shutdown(); } catch (_) {} try { requireRuntimeModule('./firewall').shutdown(); } catch (_) {} });
567
607
  process.on('SIGINT', async () => { try { await loggerProvider.shutdown(); } catch (_) {} try { requireRuntimeModule('./firewall').shutdown(); } catch (_) {} });
568
608
  } catch (e) {
569
- console.warn('[securenow] ⚠️ Logging setup failed (missing @opentelemetry/exporter-logs-otlp-http or @opentelemetry/sdk-logs):', e.message);
609
+ console.warn('[securenow] Logging setup failed (missing @opentelemetry/exporter-logs-otlp-http or @opentelemetry/sdk-logs):', e.message);
570
610
  }
571
611
  } else {
572
- console.log('[securenow] 📋 Logging: DISABLED (SECURENOW_LOGGING_ENABLED=0)');
612
+ console.log('[securenow] Logging: DISABLED (config.logging.enabled=false)');
573
613
  }
574
614
  }
575
615
 
576
616
  isRegistered = true;
577
617
 
578
- // Free trial banner (optional may not be bundled in standalone builds)
618
+ // Free trial banner (optional - may not be bundled in standalone builds)
579
619
  try {
580
620
  const { isFreeTrial, patchHttpForBanner } = requireRuntimeModule('./free-trial-banner');
581
- if (isFreeTrial(endpointBase) && String(env('SECURENOW_HIDE_BANNER')) !== '1') {
621
+ if (isFreeTrial(endpointBase) && !appConfig.boolConfig('runtime.hideBanner', false)) {
582
622
  patchHttpForBanner();
583
623
  }
584
624
  } catch (_) {}
585
625
 
586
- console.log('[securenow] OpenTelemetry started for Next.js %s', tracesUrl);
587
- console.log('[securenow] 📊 Auto-capturing comprehensive request metadata:');
588
- console.log('[securenow] IP addresses (x-forwarded-for, x-real-ip, socket)');
589
- console.log('[securenow] User-Agent, Referer, Origin, Accept headers');
590
- console.log('[securenow] Protocol, Host, Port (proxy-aware)');
591
- console.log('[securenow] Geographic data (Vercel/Cloudflare)');
592
- console.log('[securenow] Request IDs, CSRF tokens, Auth presence');
593
- console.log('[securenow] Response status, content-type, content-length');
594
- console.log('[securenow] ⚠️ Body capture DISABLED at HTTP instrumentation level (prevents Next.js conflicts)');
626
+ console.log('[securenow] OpenTelemetry started for Next.js -> %s', tracesUrl);
627
+ console.log('[securenow] Auto-capturing comprehensive request metadata:');
628
+ console.log('[securenow] - IP addresses (x-forwarded-for, x-real-ip, socket)');
629
+ console.log('[securenow] - User-Agent, Referer, Origin, Accept headers');
630
+ console.log('[securenow] - Protocol, Host, Port (proxy-aware)');
631
+ console.log('[securenow] - Geographic data (Vercel/Cloudflare)');
632
+ console.log('[securenow] - Request IDs, CSRF tokens, Auth presence');
633
+ console.log('[securenow] - Response status, content-type, content-length');
634
+ console.log('[securenow] Body capture DISABLED at HTTP instrumentation level (prevents Next.js conflicts)');
595
635
  if (captureBody) {
596
- console.log('[securenow] 💡 For body capture in Next.js, use: import "securenow/nextjs-auto-capture"');
636
+ console.log('[securenow] For body capture in Next.js, use: import "securenow/nextjs-auto-capture"');
597
637
  }
598
638
 
599
639
  // Optional test span
600
- if (String(env('SECURENOW_TEST_SPAN')) === '1') {
640
+ if (appConfig.boolConfig('runtime.testSpan', false)) {
601
641
  const api = require('@opentelemetry/api');
602
642
  const tracer = api.trace.getTracer('securenow-nextjs');
603
643
  const span = tracer.startSpan('securenow.nextjs.startup');
604
644
  span.setAttribute('next.runtime', process.env.NEXT_RUNTIME || 'nodejs');
605
645
  span.end();
606
- console.log('[securenow] 🧪 Test span created');
646
+ console.log('[securenow] Test span created');
607
647
  }
608
648
 
609
649
  } catch (error) {
@@ -615,7 +655,7 @@ function registerSecureNow(options = {}) {
615
655
  }
616
656
  }
617
657
 
618
- // Firewall runs independently from OTel so it works even if tracing fails.
658
+ // Firewall - runs independently from OTel so it works even if tracing fails.
619
659
  // Key and environment come from .securenow/credentials.json (written by
620
660
  // login/init or credentials runtime), so no .env entry is needed.
621
661
  const firewallOptions = appConfig.resolveFirewallOptions();
@@ -626,6 +666,7 @@ function registerSecureNow(options = {}) {
626
666
  appKey: firewallOptions.appKey,
627
667
  environment: deploymentEnvironment || firewallOptions.environment,
628
668
  apiUrl: firewallOptions.apiUrl,
669
+ apiUrlFallbacks: firewallOptions.apiUrlFallbacks,
629
670
  versionCheckInterval: firewallOptions.versionCheckInterval,
630
671
  syncInterval: firewallOptions.syncInterval,
631
672
  failMode: firewallOptions.failMode,
@@ -26,8 +26,6 @@ const { resolveClientIpWithDetails } = nodeRequire('./resolve-ip');
26
26
 
27
27
  // ── Helpers ──
28
28
 
29
- const env = appConfig.env;
30
-
31
29
  function createResource(attributes) {
32
30
  if (typeof otelResources.resourceFromAttributes === 'function') {
33
31
  return otelResources.resourceFromAttributes(attributes);
@@ -74,7 +72,7 @@ function getRuntimeOptions() {
74
72
  export default defineNitroPlugin(async (nitroApp) => {
75
73
  const opts = getRuntimeOptions();
76
74
 
77
- // Resolution order: opts -> .securenow/credentials.json -> legacy env fallback -> package.json#name
75
+ // Resolution order: opts -> .securenow/credentials.json -> package.json#name
78
76
  const resolvedApp = appConfig.resolveAll();
79
77
 
80
78
  // ── Naming ──
@@ -125,12 +123,9 @@ export default defineNitroPlugin(async (nitroApp) => {
125
123
  // Opt-out default: set config.capture.body=false (or opts.captureBody=false) to disable.
126
124
  const captureBody =
127
125
  opts.captureBody ??
128
- !/^(0|false)$/i.test(String(env('SECURENOW_CAPTURE_BODY') ?? ''));
129
- const maxBodySize = Math.max(1024, parseInt(env('SECURENOW_MAX_BODY_SIZE'), 10) || 10240);
130
- const customSensitiveFields = (env('SECURENOW_SENSITIVE_FIELDS') || '')
131
- .split(',')
132
- .map((s) => s.trim())
133
- .filter(Boolean);
126
+ appConfig.boolConfig('capture.body', true);
127
+ const maxBodySize = appConfig.numberConfig('capture.maxBodySize', 10240, 1024);
128
+ const customSensitiveFields = appConfig.listConfig('capture.sensitiveFields');
134
129
  const allSensitiveFields = [...DEFAULT_SENSITIVE_FIELDS, ...customSensitiveFields];
135
130
 
136
131
  // ── HTTP instrumentation ──
@@ -238,7 +233,7 @@ export default defineNitroPlugin(async (nitroApp) => {
238
233
  // Opt-out default: set config.logging.enabled=false (or opts.logging=false) to disable.
239
234
  const loggingEnabled =
240
235
  opts.logging ??
241
- !/^(0|false)$/i.test(String(env('SECURENOW_LOGGING_ENABLED') ?? ''));
236
+ appConfig.boolConfig('logging.enabled', true);
242
237
 
243
238
  let loggerProvider = null;
244
239
 
@@ -314,7 +309,7 @@ export default defineNitroPlugin(async (nitroApp) => {
314
309
  // ── Free trial banner ──
315
310
  try {
316
311
  const { isFreeTrial, patchHttpForBanner } = await import('./free-trial-banner.js');
317
- if (isFreeTrial(endpointBase) && String(env('SECURENOW_HIDE_BANNER')) !== '1') {
312
+ if (isFreeTrial(endpointBase) && !appConfig.boolConfig('runtime.hideBanner', false)) {
318
313
  patchHttpForBanner();
319
314
  }
320
315
  } catch {
@@ -331,6 +326,7 @@ export default defineNitroPlugin(async (nitroApp) => {
331
326
  appKey: firewallOptions.appKey,
332
327
  environment: deploymentEnvironment || firewallOptions.environment,
333
328
  apiUrl: firewallOptions.apiUrl,
329
+ apiUrlFallbacks: firewallOptions.apiUrlFallbacks,
334
330
  versionCheckInterval: firewallOptions.versionCheckInterval,
335
331
  syncInterval: firewallOptions.syncInterval,
336
332
  failMode: firewallOptions.failMode,
package/nuxt.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- /**
2
- * SecureNow Nuxt 3 Module TypeScript Declarations
3
- */
4
-
5
- export interface SecureNowNuxtOptions {
1
+ /**
2
+ * SecureNow Nuxt 3 Module TypeScript Declarations
3
+ */
4
+
5
+ export interface SecureNowNuxtOptions {
6
6
  /**
7
7
  * Service name for OpenTelemetry traces.
8
8
  * @default .securenow/credentials.json app.key/app.name
@@ -11,7 +11,11 @@ export interface SecureNowNuxtOptions {
11
11
 
12
12
  /**
13
13
  * OTLP endpoint base URL.
14
- * @default .securenow/credentials.json app.instance, or https://freetrial.securenow.ai:4318
14
+ * @default https://ingest.securenow.ai
15
+ *
16
+ * Advanced OTLP endpoint override. Normal SecureNow apps should leave this
17
+ * unset so the ingest gateway can route by app.key to the dashboard-selected
18
+ * instance.
15
19
  */
16
20
  endpoint?: string;
17
21
 
@@ -20,14 +24,14 @@ export interface SecureNowNuxtOptions {
20
24
  * @default .securenow/credentials.json config.runtime.deploymentEnvironment
21
25
  */
22
26
  environment?: string;
23
-
24
- /**
25
- * Don't append UUID to service name (useful when running a single instance).
26
- * @default false
27
- */
28
- noUuid?: boolean;
29
-
30
- /**
27
+
28
+ /**
29
+ * Don't append UUID to service name (useful when running a single instance).
30
+ * @default false
31
+ */
32
+ noUuid?: boolean;
33
+
34
+ /**
31
35
  * Capture request bodies (POST/PUT/PATCH) on traced spans.
32
36
  * Sensitive fields are automatically redacted.
33
37
  * @default true from .securenow/credentials.json secure defaults
@@ -40,27 +44,27 @@ export interface SecureNowNuxtOptions {
40
44
  */
41
45
  logging?: boolean;
42
46
  }
43
-
44
- declare module 'nuxt/schema' {
45
- interface NuxtConfig {
46
- securenow?: SecureNowNuxtOptions;
47
- }
48
- interface NuxtOptions {
49
- securenow?: SecureNowNuxtOptions;
50
- }
51
- interface RuntimeConfig {
52
- securenow?: SecureNowNuxtOptions;
53
- }
54
- }
55
-
56
- declare module '@nuxt/schema' {
57
- interface NuxtConfig {
58
- securenow?: SecureNowNuxtOptions;
59
- }
60
- interface NuxtOptions {
61
- securenow?: SecureNowNuxtOptions;
62
- }
63
- interface RuntimeConfig {
64
- securenow?: SecureNowNuxtOptions;
65
- }
66
- }
47
+
48
+ declare module 'nuxt/schema' {
49
+ interface NuxtConfig {
50
+ securenow?: SecureNowNuxtOptions;
51
+ }
52
+ interface NuxtOptions {
53
+ securenow?: SecureNowNuxtOptions;
54
+ }
55
+ interface RuntimeConfig {
56
+ securenow?: SecureNowNuxtOptions;
57
+ }
58
+ }
59
+
60
+ declare module '@nuxt/schema' {
61
+ interface NuxtConfig {
62
+ securenow?: SecureNowNuxtOptions;
63
+ }
64
+ interface NuxtOptions {
65
+ securenow?: SecureNowNuxtOptions;
66
+ }
67
+ interface RuntimeConfig {
68
+ securenow?: SecureNowNuxtOptions;
69
+ }
70
+ }
package/nuxt.mjs CHANGED
@@ -11,7 +11,7 @@
11
11
  * });
12
12
  *
13
13
  * Environment variables (same as all SecureNow integrations):
14
- * SECURENOW_APPID, SECURENOW_INSTANCE, SECURENOW_LOGGING_ENABLED, etc.
14
+ * Configuration is read from .securenow/credentials.json.
15
15
  */
16
16
 
17
17
  import { defineNuxtModule, createResolver, addServerPlugin } from '@nuxt/kit';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securenow",
3
- "version": "7.7.14",
3
+ "version": "7.7.16",
4
4
  "description": "OpenTelemetry instrumentation for Node.js, Next.js, and Nuxt - Send traces and logs to any OTLP-compatible backend",
5
5
  "type": "commonjs",
6
6
  "main": "register.js",
package/tracing.d.ts CHANGED
@@ -173,7 +173,8 @@ export const loggerProvider: LoggerProvider | null;
173
173
  * generated JSON to .securenow/credentials.json in the running app.
174
174
  *
175
175
  * Main config fields:
176
- * - app.key / app.name / app.instance
176
+ * - app.key / app.name
177
+ * - config.otel.endpoint only for advanced/self-hosted collector overrides
177
178
  * - apiKey
178
179
  * - config.runtime.deploymentEnvironment
179
180
  * - config.logging.enabled