securenow 7.6.0 → 7.6.2
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/SKILL-API.md +8 -12
- package/app-config.js +78 -6
- package/cli/init.js +5 -8
- package/cli.js +1 -1
- package/docs/NEXTJS-QUICKSTART.md +4 -6
- package/nextjs.js +2 -1
- package/package.json +1 -1
package/SKILL-API.md
CHANGED
|
@@ -151,15 +151,13 @@ For Next.js < 15, add `securenow` to `experimental.serverComponentsExternalPacka
|
|
|
151
151
|
**2. `instrumentation.ts`** (or `.js`, can be in `src/`):
|
|
152
152
|
|
|
153
153
|
```typescript
|
|
154
|
-
import { createRequire } from 'node:module';
|
|
155
|
-
|
|
156
|
-
const require = createRequire(import.meta.url);
|
|
157
|
-
|
|
158
154
|
export async function register() {
|
|
159
155
|
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
|
|
160
|
-
|
|
156
|
+
|
|
157
|
+
const securenowNext = await import(/* webpackIgnore: true */ 'securenow/nextjs');
|
|
158
|
+
const registerSecureNow = securenowNext.registerSecureNow || securenowNext.default?.registerSecureNow;
|
|
161
159
|
registerSecureNow({ captureBody: true });
|
|
162
|
-
|
|
160
|
+
await import(/* webpackIgnore: true */ 'securenow/nextjs-auto-capture');
|
|
163
161
|
}
|
|
164
162
|
```
|
|
165
163
|
|
|
@@ -202,15 +200,13 @@ Local development and production do not need `.env.local`; `npx securenow login`
|
|
|
202
200
|
Add to your `instrumentation.ts`:
|
|
203
201
|
|
|
204
202
|
```typescript
|
|
205
|
-
import { createRequire } from 'node:module';
|
|
206
|
-
|
|
207
|
-
const require = createRequire(import.meta.url);
|
|
208
|
-
|
|
209
203
|
export async function register() {
|
|
210
204
|
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
|
|
211
|
-
|
|
205
|
+
|
|
206
|
+
const securenowNext = await import(/* webpackIgnore: true */ 'securenow/nextjs');
|
|
207
|
+
const registerSecureNow = securenowNext.registerSecureNow || securenowNext.default?.registerSecureNow;
|
|
212
208
|
registerSecureNow({ captureBody: true });
|
|
213
|
-
|
|
209
|
+
await import(/* webpackIgnore: true */ 'securenow/nextjs-auto-capture');
|
|
214
210
|
}
|
|
215
211
|
```
|
|
216
212
|
|
package/app-config.js
CHANGED
|
@@ -164,10 +164,84 @@ function readJsonSafe(filepath) {
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
function fileIfReadable(filepath) {
|
|
168
|
+
if (!filepath) return null;
|
|
169
|
+
try {
|
|
170
|
+
return fs.existsSync(filepath) && fs.statSync(filepath).isFile() ? filepath : null;
|
|
171
|
+
} catch {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function findUpFile(startDir, relativePath) {
|
|
177
|
+
if (!startDir) return null;
|
|
178
|
+
let dir;
|
|
179
|
+
try {
|
|
180
|
+
dir = path.resolve(startDir);
|
|
181
|
+
} catch {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
while (true) {
|
|
186
|
+
const found = fileIfReadable(path.join(dir, relativePath));
|
|
187
|
+
if (found) return found;
|
|
188
|
+
|
|
189
|
+
const parent = path.dirname(dir);
|
|
190
|
+
if (!parent || parent === dir) return null;
|
|
191
|
+
dir = parent;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function uniq(values) {
|
|
196
|
+
const seen = new Set();
|
|
197
|
+
const out = [];
|
|
198
|
+
for (const value of values) {
|
|
199
|
+
if (!value || seen.has(value)) continue;
|
|
200
|
+
seen.add(value);
|
|
201
|
+
out.push(value);
|
|
202
|
+
}
|
|
203
|
+
return out;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function resolveLocalCredentialsFile() {
|
|
207
|
+
const starts = [];
|
|
208
|
+
try {
|
|
209
|
+
if (typeof process !== 'undefined' && process.cwd) starts.push(process.cwd());
|
|
210
|
+
} catch {}
|
|
211
|
+
|
|
212
|
+
if (process.env.INIT_CWD) starts.push(process.env.INIT_CWD);
|
|
213
|
+
if (process.argv && process.argv[1]) starts.push(path.dirname(process.argv[1]));
|
|
214
|
+
if (require.main && require.main.filename) starts.push(path.dirname(require.main.filename));
|
|
215
|
+
|
|
216
|
+
for (const start of uniq(starts)) {
|
|
217
|
+
const found = findUpFile(start, path.join('.securenow', 'credentials.json'));
|
|
218
|
+
if (found) return found;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function resolvePackageJsonFile() {
|
|
225
|
+
const starts = [];
|
|
226
|
+
try {
|
|
227
|
+
if (typeof process !== 'undefined' && process.cwd) starts.push(process.cwd());
|
|
228
|
+
} catch {}
|
|
229
|
+
|
|
230
|
+
if (process.env.INIT_CWD) starts.push(process.env.INIT_CWD);
|
|
231
|
+
if (process.argv && process.argv[1]) starts.push(path.dirname(process.argv[1]));
|
|
232
|
+
if (require.main && require.main.filename) starts.push(path.dirname(require.main.filename));
|
|
233
|
+
|
|
234
|
+
for (const start of uniq(starts)) {
|
|
235
|
+
const found = findUpFile(start, 'package.json');
|
|
236
|
+
if (found) return found;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
|
|
167
242
|
function loadLocalCredentials() {
|
|
168
243
|
try {
|
|
169
|
-
|
|
170
|
-
return withCredentialDefaults(readJsonSafe(path.join(cwd, '.securenow', 'credentials.json')));
|
|
244
|
+
return withCredentialDefaults(readJsonSafe(resolveLocalCredentialsFile()));
|
|
171
245
|
} catch {
|
|
172
246
|
return null;
|
|
173
247
|
}
|
|
@@ -183,8 +257,7 @@ function loadGlobalCredentials() {
|
|
|
183
257
|
|
|
184
258
|
function loadCredentials() {
|
|
185
259
|
try {
|
|
186
|
-
const
|
|
187
|
-
const local = readJsonSafe(path.join(cwd, '.securenow', 'credentials.json'));
|
|
260
|
+
const local = readJsonSafe(resolveLocalCredentialsFile());
|
|
188
261
|
const global = readJsonSafe(path.join(os.homedir(), '.securenow', 'credentials.json'));
|
|
189
262
|
return withCredentialDefaults(mergeCredentials(global, local));
|
|
190
263
|
} catch {
|
|
@@ -194,8 +267,7 @@ function loadCredentials() {
|
|
|
194
267
|
|
|
195
268
|
function loadPackageJsonName() {
|
|
196
269
|
try {
|
|
197
|
-
const
|
|
198
|
-
const pkg = readJsonSafe(path.join(cwd, 'package.json'));
|
|
270
|
+
const pkg = readJsonSafe(resolvePackageJsonFile());
|
|
199
271
|
if (pkg && typeof pkg.name === 'string' && pkg.name.trim()) {
|
|
200
272
|
return pkg.name.trim().replace(/^@[^/]+\//, '');
|
|
201
273
|
}
|
package/cli/init.js
CHANGED
|
@@ -5,16 +5,13 @@ const path = require('path');
|
|
|
5
5
|
const ui = require('./ui');
|
|
6
6
|
const config = require('./config');
|
|
7
7
|
|
|
8
|
-
const INSTRUMENTATION = `
|
|
9
|
-
|
|
10
|
-
const require = createRequire(import.meta.url);
|
|
11
|
-
|
|
12
|
-
export async function register() {
|
|
8
|
+
const INSTRUMENTATION = `export async function register() {
|
|
13
9
|
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
|
|
14
10
|
|
|
15
|
-
const
|
|
11
|
+
const securenowNext = await import(/* webpackIgnore: true */ 'securenow/nextjs');
|
|
12
|
+
const registerSecureNow = securenowNext.registerSecureNow || securenowNext.default?.registerSecureNow;
|
|
16
13
|
registerSecureNow({ captureBody: true });
|
|
17
|
-
|
|
14
|
+
await import(/* webpackIgnore: true */ 'securenow/nextjs-auto-capture');
|
|
18
15
|
}
|
|
19
16
|
`;
|
|
20
17
|
|
|
@@ -190,7 +187,7 @@ function printAgentPrompt(kind, filename, major) {
|
|
|
190
187
|
'Set up SecureNow in this existing Next.js project without using .env files.',
|
|
191
188
|
'Use .securenow/credentials.json for local and production configuration; do not add .env files.',
|
|
192
189
|
kind === 'instrumentation'
|
|
193
|
-
? `Merge this into ${filename}: in register(), return unless process.env.NEXT_RUNTIME === "nodejs";
|
|
190
|
+
? `Merge this into ${filename}: in register(), return unless process.env.NEXT_RUNTIME === "nodejs"; then dynamically import "securenow/nextjs" and "securenow/nextjs-auto-capture" with /* webpackIgnore: true */ so Next does not bundle OpenTelemetry internals. Preserve all existing instrumentation.`
|
|
194
191
|
: null,
|
|
195
192
|
kind === 'next-config' && major >= 15
|
|
196
193
|
? `Update ${filename} while preserving existing config: add securenow to serverExternalPackages, e.g. serverExternalPackages: [...(existing || []), "securenow"].`
|
package/cli.js
CHANGED
|
@@ -25,15 +25,13 @@ No `.env.local` edits. No API key copy-paste. The app you picked in step 2 is wh
|
|
|
25
25
|
**`instrumentation.ts`** (or `.js`, auto-detected):
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
|
-
import { createRequire } from 'node:module';
|
|
29
|
-
|
|
30
|
-
const require = createRequire(import.meta.url);
|
|
31
|
-
|
|
32
28
|
export async function register() {
|
|
33
29
|
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
|
|
34
|
-
|
|
30
|
+
|
|
31
|
+
const securenowNext = await import(/* webpackIgnore: true */ 'securenow/nextjs');
|
|
32
|
+
const registerSecureNow = securenowNext.registerSecureNow || securenowNext.default?.registerSecureNow;
|
|
35
33
|
registerSecureNow({ captureBody: true });
|
|
36
|
-
|
|
34
|
+
await import(/* webpackIgnore: true */ 'securenow/nextjs-auto-capture');
|
|
37
35
|
}
|
|
38
36
|
```
|
|
39
37
|
|
package/nextjs.js
CHANGED
|
@@ -131,6 +131,7 @@ function registerSecureNow(options = {}) {
|
|
|
131
131
|
|
|
132
132
|
// Detect environment outside try block for error handling
|
|
133
133
|
const isVercel = !!(env('VERCEL') || env('VERCEL_ENV') || env('VERCEL_URL'));
|
|
134
|
+
let deploymentEnvironment = appConfig.resolveDeploymentEnvironment();
|
|
134
135
|
|
|
135
136
|
try {
|
|
136
137
|
console.log('[securenow] Next.js integration loading (pid=%d)', process.pid);
|
|
@@ -145,7 +146,7 @@ function registerSecureNow(options = {}) {
|
|
|
145
146
|
// and the dashboard does exact match). opts.noUuid or SECURENOW_NO_UUID
|
|
146
147
|
// override.
|
|
147
148
|
const noUuid = appConfig.resolveNoUuid({ noUuid: options.noUuid });
|
|
148
|
-
|
|
149
|
+
deploymentEnvironment = appConfig.normalizeDeploymentEnvironment(
|
|
149
150
|
options.environment || resolvedApp.deploymentEnvironment || env('VERCEL_ENV')
|
|
150
151
|
);
|
|
151
152
|
|
package/package.json
CHANGED