securenow 4.0.5 → 4.0.9

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/README.md +4 -3
  2. package/cli.js +4 -1
  3. package/docs/ARCHITECTURE.md +408 -0
  4. package/{AUTO-BODY-CAPTURE.md → docs/AUTO-BODY-CAPTURE.md} +3 -0
  5. package/docs/AUTO-SETUP-SUMMARY.md +331 -0
  6. package/{AUTO-SETUP.md → docs/AUTO-SETUP.md} +3 -0
  7. package/{AUTOMATIC-IP-CAPTURE.md → docs/AUTOMATIC-IP-CAPTURE.md} +3 -0
  8. package/{BODY-CAPTURE-FIX.md → docs/BODY-CAPTURE-FIX.md} +3 -0
  9. package/{BODY-CAPTURE-QUICKSTART.md → docs/BODY-CAPTURE-QUICKSTART.md} +147 -147
  10. package/docs/CHANGELOG-NEXTJS.md +235 -0
  11. package/docs/COMPLETION-REPORT.md +408 -0
  12. package/{EASIEST-SETUP.md → docs/EASIEST-SETUP.md} +3 -0
  13. package/docs/EXPRESS-BODY-CAPTURE.md +1027 -0
  14. package/{FINAL-SOLUTION.md → docs/FINAL-SOLUTION.md} +3 -0
  15. package/docs/IMPLEMENTATION-SUMMARY.md +410 -0
  16. package/docs/INDEX.md +129 -0
  17. package/{NEXTJS-BODY-CAPTURE-COMPARISON.md → docs/NEXTJS-BODY-CAPTURE-COMPARISON.md} +3 -0
  18. package/docs/NEXTJS-WEBPACK-WARNINGS.md +267 -0
  19. package/{NEXTJS-WRAPPER-APPROACH.md → docs/NEXTJS-WRAPPER-APPROACH.md} +3 -0
  20. package/{QUICKSTART-BODY-CAPTURE.md → docs/QUICKSTART-BODY-CAPTURE.md} +3 -0
  21. package/{REDACTION-EXAMPLES.md → docs/REDACTION-EXAMPLES.md} +3 -0
  22. package/{REQUEST-BODY-CAPTURE.md → docs/REQUEST-BODY-CAPTURE.md} +575 -575
  23. package/{SOLUTION-SUMMARY.md → docs/SOLUTION-SUMMARY.md} +3 -0
  24. package/docs/VERCEL-OTEL-MIGRATION.md +255 -0
  25. package/examples/README.md +3 -0
  26. package/examples/instrumentation-with-auto-capture.ts +3 -0
  27. package/examples/next.config.js +3 -0
  28. package/examples/nextjs-api-route-with-body-capture.ts +3 -0
  29. package/examples/nextjs-env-example.txt +3 -0
  30. package/examples/nextjs-instrumentation.js +3 -0
  31. package/examples/nextjs-instrumentation.ts +3 -0
  32. package/examples/nextjs-middleware.js +3 -0
  33. package/examples/nextjs-middleware.ts +3 -0
  34. package/examples/nextjs-with-options.ts +3 -0
  35. package/examples/test-nextjs-setup.js +3 -0
  36. package/nextjs-auto-capture.js +3 -0
  37. package/nextjs-middleware.js +3 -0
  38. package/nextjs-wrapper.js +3 -0
  39. package/nextjs.js +174 -72
  40. package/package.json +3 -19
  41. package/postinstall.js +310 -310
  42. package/tracing.js +287 -287
  43. /package/{CUSTOMER-GUIDE.md → docs/CUSTOMER-GUIDE.md} +0 -0
  44. /package/{NEXTJS-BODY-CAPTURE.md → docs/NEXTJS-BODY-CAPTURE.md} +0 -0
  45. /package/{NEXTJS-GUIDE.md → docs/NEXTJS-GUIDE.md} +0 -0
  46. /package/{NEXTJS-QUICKSTART.md → docs/NEXTJS-QUICKSTART.md} +0 -0
package/postinstall.js CHANGED
@@ -1,310 +1,310 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- /**
5
- * SecureNow Post-Install Script
6
- *
7
- * Automatically detects Next.js projects and offers to create instrumentation file
8
- */
9
-
10
- const fs = require('fs');
11
- const path = require('path');
12
- const readline = require('readline');
13
-
14
- // Check if we're in a Next.js project
15
- function isNextJsProject() {
16
- try {
17
- const packageJsonPath = path.join(process.cwd(), 'package.json');
18
- if (!fs.existsSync(packageJsonPath)) return false;
19
-
20
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
21
- const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
22
-
23
- return !!deps.next;
24
- } catch (error) {
25
- return false;
26
- }
27
- }
28
-
29
- // Check if instrumentation file already exists
30
- function hasInstrumentationFile() {
31
- const files = [
32
- 'instrumentation.ts',
33
- 'instrumentation.js',
34
- 'src/instrumentation.ts',
35
- 'src/instrumentation.js'
36
- ];
37
-
38
- return files.some(file => fs.existsSync(path.join(process.cwd(), file)));
39
- }
40
-
41
- // Create TypeScript instrumentation file
42
- function createTsInstrumentation(targetPath) {
43
- const content = `import { registerSecureNow } from 'securenow/nextjs';
44
-
45
- export function register() {
46
- registerSecureNow();
47
- }
48
-
49
- /**
50
- * Configuration via .env.local:
51
- *
52
- * Required:
53
- * SECURENOW_APPID=my-nextjs-app
54
- *
55
- * Optional:
56
- * SECURENOW_INSTANCE=http://your-signoz-server:4318
57
- * OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-key"
58
- * OTEL_LOG_LEVEL=info
59
- */
60
- `;
61
-
62
- fs.writeFileSync(targetPath, content, 'utf8');
63
- }
64
-
65
- // Create JavaScript instrumentation file
66
- function createJsInstrumentation(targetPath) {
67
- const content = `const { registerSecureNow } = require('securenow/nextjs');
68
-
69
- export function register() {
70
- registerSecureNow();
71
- }
72
-
73
- /**
74
- * Configuration via .env.local:
75
- *
76
- * Required:
77
- * SECURENOW_APPID=my-nextjs-app
78
- *
79
- * Optional:
80
- * SECURENOW_INSTANCE=http://your-signoz-server:4318
81
- * OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-key"
82
- * OTEL_LOG_LEVEL=info
83
- *
84
- * Optional: Enable request body capture
85
- * SECURENOW_CAPTURE_BODY=1
86
- * (Also create middleware.ts to activate - run: npx securenow init)
87
- */
88
- `;
89
-
90
- fs.writeFileSync(targetPath, content, 'utf8');
91
- }
92
-
93
- // Create TypeScript middleware file
94
- function createTsMiddleware(targetPath) {
95
- const content = `// SecureNow Middleware - Automatic Request Body Capture
96
- // This enables capturing JSON, GraphQL, and Form request bodies
97
- // with automatic sensitive field redaction
98
-
99
- export { middleware } from 'securenow/nextjs-middleware';
100
-
101
- export const config = {
102
- matcher: '/api/:path*', // Apply to all API routes
103
- };
104
-
105
- /**
106
- * Bodies are captured with:
107
- * - Automatic redaction of passwords, tokens, cards, etc.
108
- * - Size limits (configurable via SECURENOW_MAX_BODY_SIZE)
109
- * - JSON, GraphQL, Form data support
110
- *
111
- * Configure in .env.local:
112
- * SECURENOW_MAX_BODY_SIZE=20480
113
- * SECURENOW_SENSITIVE_FIELDS=email,phone
114
- */
115
- `;
116
-
117
- fs.writeFileSync(targetPath, content, 'utf8');
118
- }
119
-
120
- // Create JavaScript middleware file
121
- function createJsMiddleware(targetPath) {
122
- const content = `// SecureNow Middleware - Automatic Request Body Capture
123
- // This enables capturing JSON, GraphQL, and Form request bodies
124
- // with automatic sensitive field redaction
125
-
126
- export { middleware } from 'securenow/nextjs-middleware';
127
-
128
- export const config = {
129
- matcher: '/api/:path*', // Apply to all API routes
130
- };
131
-
132
- /**
133
- * Bodies are captured with:
134
- * - Automatic redaction of passwords, tokens, cards, etc.
135
- * - Size limits (configurable via SECURENOW_MAX_BODY_SIZE)
136
- * - JSON, GraphQL, Form data support
137
- *
138
- * Configure in .env.local:
139
- * SECURENOW_MAX_BODY_SIZE=20480
140
- * SECURENOW_SENSITIVE_FIELDS=email,phone
141
- */
142
- `;
143
-
144
- fs.writeFileSync(targetPath, content, 'utf8');
145
- }
146
-
147
- // Create .env.local template
148
- function createEnvTemplate(targetPath) {
149
- const content = `# SecureNow Configuration
150
- # Required: Your application identifier
151
- SECURENOW_APPID=my-nextjs-app
152
-
153
- # Optional: Your SigNoz/OpenTelemetry collector endpoint
154
- # Default: http://46.62.173.237:4318
155
- SECURENOW_INSTANCE=http://your-signoz-server:4318
156
-
157
- # Optional: API key or authentication headers
158
- # OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-api-key-here"
159
-
160
- # Optional: Log level (debug|info|warn|error)
161
- # OTEL_LOG_LEVEL=info
162
-
163
- # Optional: Enable request body capture (requires middleware.ts)
164
- # SECURENOW_CAPTURE_BODY=1
165
- # SECURENOW_MAX_BODY_SIZE=10240
166
- # SECURENOW_SENSITIVE_FIELDS=email,phone
167
- `;
168
-
169
- fs.writeFileSync(targetPath, content, 'utf8');
170
- }
171
-
172
- // Check if TypeScript is used
173
- function isTypeScriptProject() {
174
- return fs.existsSync(path.join(process.cwd(), 'tsconfig.json'));
175
- }
176
-
177
- // Main setup function
178
- async function setup() {
179
- // Skip if not in Next.js project
180
- if (!isNextJsProject()) {
181
- console.log('[securenow] Not a Next.js project, skipping auto-setup');
182
- return;
183
- }
184
-
185
- // Skip if instrumentation file already exists
186
- if (hasInstrumentationFile()) {
187
- console.log('[securenow] ✅ Instrumentation file already exists');
188
- return;
189
- }
190
-
191
- console.log('\n┌─────────────────────────────────────────────────┐');
192
- console.log('│ 🎉 SecureNow installed successfully! │');
193
- console.log('│ Next.js project detected │');
194
- console.log('└─────────────────────────────────────────────────┘\n');
195
-
196
- // Check if we're in CI/non-interactive environment
197
- if (process.env.CI || !process.stdin.isTTY) {
198
- console.log('[securenow] ℹ️ Non-interactive environment detected');
199
- console.log('[securenow] 💡 To complete setup, run: npx securenow init');
200
- return;
201
- }
202
-
203
- // Ask user if they want to auto-setup
204
- const rl = readline.createInterface({
205
- input: process.stdin,
206
- output: process.stdout
207
- });
208
-
209
- rl.question('Would you like to automatically create instrumentation file? (Y/n) ', (answer) => {
210
- const shouldCreate = !answer || answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
211
-
212
- if (!shouldCreate) {
213
- console.log('\n[securenow] No problem! To setup later, run: npx securenow init');
214
- rl.close();
215
- return;
216
- }
217
-
218
- try {
219
- const useTypeScript = isTypeScriptProject();
220
- const srcExists = fs.existsSync(path.join(process.cwd(), 'src'));
221
-
222
- // Determine file path
223
- const fileName = useTypeScript ? 'instrumentation.ts' : 'instrumentation.js';
224
- const filePath = srcExists
225
- ? path.join(process.cwd(), 'src', fileName)
226
- : path.join(process.cwd(), fileName);
227
-
228
- // Create instrumentation file
229
- if (useTypeScript) {
230
- createTsInstrumentation(filePath);
231
- } else {
232
- createJsInstrumentation(filePath);
233
- }
234
-
235
- console.log(`\n✅ Created ${srcExists ? 'src/' : ''}${fileName}`);
236
-
237
- // Ask about middleware for body capture
238
- rl.question('\nWould you like to enable request body capture? (y/N) ', (middlewareAnswer) => {
239
- const shouldCreateMiddleware = middlewareAnswer && (middlewareAnswer.toLowerCase() === 'y' || middlewareAnswer.toLowerCase() === 'yes');
240
-
241
- if (shouldCreateMiddleware) {
242
- try {
243
- const middlewareName = useTypeScript ? 'middleware.ts' : 'middleware.js';
244
- const middlewarePath = srcExists
245
- ? path.join(process.cwd(), 'src', middlewareName)
246
- : path.join(process.cwd(), middlewareName);
247
-
248
- if (useTypeScript) {
249
- createTsMiddleware(middlewarePath);
250
- } else {
251
- createJsMiddleware(middlewarePath);
252
- }
253
-
254
- console.log(`✅ Created ${srcExists ? 'src/' : ''}${middlewareName}`);
255
- console.log(' → Captures JSON, GraphQL, Form bodies with auto-redaction');
256
- } catch (error) {
257
- console.warn(`⚠️ Could not create middleware: ${error.message}`);
258
- }
259
- }
260
-
261
- // Create .env.local if it doesn't exist
262
- const envPath = path.join(process.cwd(), '.env.local');
263
- if (!fs.existsSync(envPath)) {
264
- createEnvTemplate(envPath);
265
- console.log('✅ Created .env.local template');
266
- }
267
-
268
- console.log('\n┌─────────────────────────────────────────────────┐');
269
- console.log('│ 🚀 Next Steps: │');
270
- console.log('│ │');
271
- console.log('│ 1. Edit .env.local and set: │');
272
- console.log('│ SECURENOW_APPID=your-app-name │');
273
- console.log('│ SECURENOW_INSTANCE=http://signoz:4318 │');
274
- if (shouldCreateMiddleware) {
275
- console.log('│ SECURENOW_CAPTURE_BODY=1 │');
276
- }
277
- console.log('│ │');
278
- console.log('│ 2. Run your app: npm run dev │');
279
- console.log('│ │');
280
- console.log('│ 3. Check SigNoz for traces! │');
281
- console.log('│ │');
282
- if (shouldCreateMiddleware) {
283
- console.log('│ 📝 Body capture enabled with auto-redaction │');
284
- }
285
- console.log('│ 📚 Full guide: npm docs securenow │');
286
- console.log('└─────────────────────────────────────────────────┘\n');
287
-
288
- rl.close();
289
- });
290
-
291
- } catch (error) {
292
- console.error('\n❌ Failed to create instrumentation file:', error.message);
293
- console.log('💡 You can create it manually or run: npx securenow init');
294
- rl.close();
295
- }
296
- });
297
- }
298
-
299
- // Run setup if this is a new installation (not being installed as a dependency of another package)
300
- if (require.main === module || process.env.npm_config_global !== 'true') {
301
- setup().catch(err => {
302
- console.error('[securenow] Setup error:', err);
303
- });
304
- }
305
-
306
- module.exports = { setup };
307
-
308
-
309
-
310
-
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * SecureNow Post-Install Script
6
+ *
7
+ * Automatically detects Next.js projects and offers to create instrumentation file
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const readline = require('readline');
13
+
14
+ // Check if we're in a Next.js project
15
+ function isNextJsProject() {
16
+ try {
17
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
18
+ if (!fs.existsSync(packageJsonPath)) return false;
19
+
20
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
21
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
22
+
23
+ return !!deps.next;
24
+ } catch (error) {
25
+ return false;
26
+ }
27
+ }
28
+
29
+ // Check if instrumentation file already exists
30
+ function hasInstrumentationFile() {
31
+ const files = [
32
+ 'instrumentation.ts',
33
+ 'instrumentation.js',
34
+ 'src/instrumentation.ts',
35
+ 'src/instrumentation.js'
36
+ ];
37
+
38
+ return files.some(file => fs.existsSync(path.join(process.cwd(), file)));
39
+ }
40
+
41
+ // Create TypeScript instrumentation file
42
+ function createTsInstrumentation(targetPath) {
43
+ const content = `import { registerSecureNow } from 'securenow/nextjs';
44
+
45
+ export function register() {
46
+ registerSecureNow();
47
+ }
48
+
49
+ /**
50
+ * Configuration via .env.local:
51
+ *
52
+ * Required:
53
+ * SECURENOW_APPID=my-nextjs-app
54
+ *
55
+ * Optional:
56
+ * SECURENOW_INSTANCE=http://your-signoz-server:4318
57
+ * OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-key"
58
+ * OTEL_LOG_LEVEL=info
59
+ */
60
+ `;
61
+
62
+ fs.writeFileSync(targetPath, content, 'utf8');
63
+ }
64
+
65
+ // Create JavaScript instrumentation file
66
+ function createJsInstrumentation(targetPath) {
67
+ const content = `const { registerSecureNow } = require('securenow/nextjs');
68
+
69
+ export function register() {
70
+ registerSecureNow();
71
+ }
72
+
73
+ /**
74
+ * Configuration via .env.local:
75
+ *
76
+ * Required:
77
+ * SECURENOW_APPID=my-nextjs-app
78
+ *
79
+ * Optional:
80
+ * SECURENOW_INSTANCE=http://your-signoz-server:4318
81
+ * OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-key"
82
+ * OTEL_LOG_LEVEL=info
83
+ *
84
+ * Optional: Enable request body capture
85
+ * SECURENOW_CAPTURE_BODY=1
86
+ * (Also create middleware.ts to activate - run: npx securenow init)
87
+ */
88
+ `;
89
+
90
+ fs.writeFileSync(targetPath, content, 'utf8');
91
+ }
92
+
93
+ // Create TypeScript middleware file
94
+ function createTsMiddleware(targetPath) {
95
+ const content = `// SecureNow Middleware - Automatic Request Body Capture
96
+ // This enables capturing JSON, GraphQL, and Form request bodies
97
+ // with automatic sensitive field redaction
98
+
99
+ export { middleware } from 'securenow/nextjs-middleware';
100
+
101
+ export const config = {
102
+ matcher: '/api/:path*', // Apply to all API routes
103
+ };
104
+
105
+ /**
106
+ * Bodies are captured with:
107
+ * - Automatic redaction of passwords, tokens, cards, etc.
108
+ * - Size limits (configurable via SECURENOW_MAX_BODY_SIZE)
109
+ * - JSON, GraphQL, Form data support
110
+ *
111
+ * Configure in .env.local:
112
+ * SECURENOW_MAX_BODY_SIZE=20480
113
+ * SECURENOW_SENSITIVE_FIELDS=email,phone
114
+ */
115
+ `;
116
+
117
+ fs.writeFileSync(targetPath, content, 'utf8');
118
+ }
119
+
120
+ // Create JavaScript middleware file
121
+ function createJsMiddleware(targetPath) {
122
+ const content = `// SecureNow Middleware - Automatic Request Body Capture
123
+ // This enables capturing JSON, GraphQL, and Form request bodies
124
+ // with automatic sensitive field redaction
125
+
126
+ export { middleware } from 'securenow/nextjs-middleware';
127
+
128
+ export const config = {
129
+ matcher: '/api/:path*', // Apply to all API routes
130
+ };
131
+
132
+ /**
133
+ * Bodies are captured with:
134
+ * - Automatic redaction of passwords, tokens, cards, etc.
135
+ * - Size limits (configurable via SECURENOW_MAX_BODY_SIZE)
136
+ * - JSON, GraphQL, Form data support
137
+ *
138
+ * Configure in .env.local:
139
+ * SECURENOW_MAX_BODY_SIZE=20480
140
+ * SECURENOW_SENSITIVE_FIELDS=email,phone
141
+ */
142
+ `;
143
+
144
+ fs.writeFileSync(targetPath, content, 'utf8');
145
+ }
146
+
147
+ // Create .env.local template
148
+ function createEnvTemplate(targetPath) {
149
+ const content = `# SecureNow Configuration
150
+ # Required: Your application identifier
151
+ SECURENOW_APPID=my-nextjs-app
152
+
153
+ # Optional: Your SigNoz/OpenTelemetry collector endpoint
154
+ # Default: http://46.62.173.237:4318
155
+ SECURENOW_INSTANCE=http://your-signoz-server:4318
156
+
157
+ # Optional: API key or authentication headers
158
+ # OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-api-key-here"
159
+
160
+ # Optional: Log level (debug|info|warn|error)
161
+ # OTEL_LOG_LEVEL=info
162
+
163
+ # Optional: Enable request body capture (requires middleware.ts)
164
+ # SECURENOW_CAPTURE_BODY=1
165
+ # SECURENOW_MAX_BODY_SIZE=10240
166
+ # SECURENOW_SENSITIVE_FIELDS=email,phone
167
+ `;
168
+
169
+ fs.writeFileSync(targetPath, content, 'utf8');
170
+ }
171
+
172
+ // Check if TypeScript is used
173
+ function isTypeScriptProject() {
174
+ return fs.existsSync(path.join(process.cwd(), 'tsconfig.json'));
175
+ }
176
+
177
+ // Main setup function
178
+ async function setup() {
179
+ // Skip if not in Next.js project
180
+ if (!isNextJsProject()) {
181
+ console.log('[securenow] Not a Next.js project, skipping auto-setup');
182
+ return;
183
+ }
184
+
185
+ // Skip if instrumentation file already exists
186
+ if (hasInstrumentationFile()) {
187
+ console.log('[securenow] ✅ Instrumentation file already exists');
188
+ return;
189
+ }
190
+
191
+ console.log('\n┌─────────────────────────────────────────────────┐');
192
+ console.log('│ 🎉 SecureNow installed successfully! │');
193
+ console.log('│ Next.js project detected │');
194
+ console.log('└─────────────────────────────────────────────────┘\n');
195
+
196
+ // Check if we're in CI/non-interactive environment
197
+ if (process.env.CI || !process.stdin.isTTY) {
198
+ console.log('[securenow] ℹ️ Non-interactive environment detected');
199
+ console.log('[securenow] 💡 To complete setup, run: npx securenow init');
200
+ return;
201
+ }
202
+
203
+ // Ask user if they want to auto-setup
204
+ const rl = readline.createInterface({
205
+ input: process.stdin,
206
+ output: process.stdout
207
+ });
208
+
209
+ rl.question('Would you like to automatically create instrumentation file? (Y/n) ', (answer) => {
210
+ const shouldCreate = !answer || answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
211
+
212
+ if (!shouldCreate) {
213
+ console.log('\n[securenow] No problem! To setup later, run: npx securenow init');
214
+ rl.close();
215
+ return;
216
+ }
217
+
218
+ try {
219
+ const useTypeScript = isTypeScriptProject();
220
+ const srcExists = fs.existsSync(path.join(process.cwd(), 'src'));
221
+
222
+ // Determine file path
223
+ const fileName = useTypeScript ? 'instrumentation.ts' : 'instrumentation.js';
224
+ const filePath = srcExists
225
+ ? path.join(process.cwd(), 'src', fileName)
226
+ : path.join(process.cwd(), fileName);
227
+
228
+ // Create instrumentation file
229
+ if (useTypeScript) {
230
+ createTsInstrumentation(filePath);
231
+ } else {
232
+ createJsInstrumentation(filePath);
233
+ }
234
+
235
+ console.log(`\n✅ Created ${srcExists ? 'src/' : ''}${fileName}`);
236
+
237
+ // Ask about middleware for body capture
238
+ rl.question('\nWould you like to enable request body capture? (y/N) ', (middlewareAnswer) => {
239
+ const shouldCreateMiddleware = middlewareAnswer && (middlewareAnswer.toLowerCase() === 'y' || middlewareAnswer.toLowerCase() === 'yes');
240
+
241
+ if (shouldCreateMiddleware) {
242
+ try {
243
+ const middlewareName = useTypeScript ? 'middleware.ts' : 'middleware.js';
244
+ const middlewarePath = srcExists
245
+ ? path.join(process.cwd(), 'src', middlewareName)
246
+ : path.join(process.cwd(), middlewareName);
247
+
248
+ if (useTypeScript) {
249
+ createTsMiddleware(middlewarePath);
250
+ } else {
251
+ createJsMiddleware(middlewarePath);
252
+ }
253
+
254
+ console.log(`✅ Created ${srcExists ? 'src/' : ''}${middlewareName}`);
255
+ console.log(' → Captures JSON, GraphQL, Form bodies with auto-redaction');
256
+ } catch (error) {
257
+ console.warn(`⚠️ Could not create middleware: ${error.message}`);
258
+ }
259
+ }
260
+
261
+ // Create .env.local if it doesn't exist
262
+ const envPath = path.join(process.cwd(), '.env.local');
263
+ if (!fs.existsSync(envPath)) {
264
+ createEnvTemplate(envPath);
265
+ console.log('✅ Created .env.local template');
266
+ }
267
+
268
+ console.log('\n┌─────────────────────────────────────────────────┐');
269
+ console.log('│ 🚀 Next Steps: │');
270
+ console.log('│ │');
271
+ console.log('│ 1. Edit .env.local and set: │');
272
+ console.log('│ SECURENOW_APPID=your-app-name │');
273
+ console.log('│ SECURENOW_INSTANCE=http://signoz:4318 │');
274
+ if (shouldCreateMiddleware) {
275
+ console.log('│ SECURENOW_CAPTURE_BODY=1 │');
276
+ }
277
+ console.log('│ │');
278
+ console.log('│ 2. Run your app: npm run dev │');
279
+ console.log('│ │');
280
+ console.log('│ 3. Check SigNoz for traces! │');
281
+ console.log('│ │');
282
+ if (shouldCreateMiddleware) {
283
+ console.log('│ 📝 Body capture enabled with auto-redaction │');
284
+ }
285
+ console.log('│ 📚 Full guide: npm docs securenow │');
286
+ console.log('└─────────────────────────────────────────────────┘\n');
287
+
288
+ rl.close();
289
+ });
290
+
291
+ } catch (error) {
292
+ console.error('\n❌ Failed to create instrumentation file:', error.message);
293
+ console.log('💡 You can create it manually or run: npx securenow init');
294
+ rl.close();
295
+ }
296
+ });
297
+ }
298
+
299
+ // Run setup if this is a new installation (not being installed as a dependency of another package)
300
+ if (require.main === module || process.env.npm_config_global !== 'true') {
301
+ setup().catch(err => {
302
+ console.error('[securenow] Setup error:', err);
303
+ });
304
+ }
305
+
306
+ module.exports = { setup };
307
+
308
+
309
+
310
+