@saptools/cf-inspector 0.9.0 → 0.9.3
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/dist/cli.js +49 -18
- package/dist/cli.js.map +1 -1
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1298,6 +1298,20 @@ function registerSelfUpdateCommand(program, options) {
|
|
|
1298
1298
|
});
|
|
1299
1299
|
}
|
|
1300
1300
|
|
|
1301
|
+
// ../core/src/cloud-logging/instance-discovery.ts
|
|
1302
|
+
var INSTANCE_LISTING_FIELDS = `&${encodeURIComponent("fields[service_plan]")}=guid,name,relationships.service_offering&${encodeURIComponent("fields[service_plan.service_offering]")}=guid,name`;
|
|
1303
|
+
|
|
1304
|
+
// ../core/src/cloud-logging/credential-cache.ts
|
|
1305
|
+
import { readdir, rm } from "fs/promises";
|
|
1306
|
+
import { dirname as dirname5, join as join7 } from "path";
|
|
1307
|
+
|
|
1308
|
+
// ../core/src/cloud-logging/result-store.ts
|
|
1309
|
+
import { randomBytes } from "crypto";
|
|
1310
|
+
import { mkdir, readdir as readdir2, readFile, rename, rm as rm2, stat, unlink, writeFile } from "fs/promises";
|
|
1311
|
+
import { join as join8 } from "path";
|
|
1312
|
+
var DEFAULT_MAX_BYTES = 256 * 1024 * 1024;
|
|
1313
|
+
var STRANDED_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
1314
|
+
|
|
1301
1315
|
// src/cli/program.ts
|
|
1302
1316
|
import { Command } from "commander";
|
|
1303
1317
|
|
|
@@ -2931,9 +2945,9 @@ init_types();
|
|
|
2931
2945
|
import { execFileSync } from "child_process";
|
|
2932
2946
|
import { createHash, randomUUID } from "crypto";
|
|
2933
2947
|
import { constants as constants3 } from "fs";
|
|
2934
|
-
import { mkdir, open, readFile, readdir, stat, unlink, writeFile } from "fs/promises";
|
|
2948
|
+
import { mkdir as mkdir2, open, readFile as readFile2, readdir as readdir3, stat as stat2, unlink as unlink2, writeFile as writeFile2 } from "fs/promises";
|
|
2935
2949
|
import { homedir as homedir3 } from "os";
|
|
2936
|
-
import { join as
|
|
2950
|
+
import { join as join9 } from "path";
|
|
2937
2951
|
var ELECTION_WINDOW_MS = 25;
|
|
2938
2952
|
var LOCK_FILE_SUFFIX = ".lock";
|
|
2939
2953
|
async function acquireDebugSessionLock(target, options = {}) {
|
|
@@ -2945,8 +2959,8 @@ async function acquireDebugSessionLock(target, options = {}) {
|
|
|
2945
2959
|
const targetIdentity = debugTargetIdentity(target);
|
|
2946
2960
|
const key = createHash("sha256").update(targetIdentity).digest("hex");
|
|
2947
2961
|
const lockRoot = options.stateRoot ?? defaultStateRoot();
|
|
2948
|
-
const lockDirectory =
|
|
2949
|
-
const ownPath =
|
|
2962
|
+
const lockDirectory = join9(lockRoot, "cf-inspector", "locks");
|
|
2963
|
+
const ownPath = join9(lockDirectory, `${key}.${pid.toString()}.${token}${LOCK_FILE_SUFFIX}`);
|
|
2950
2964
|
const metadata = {
|
|
2951
2965
|
pid,
|
|
2952
2966
|
...ownerProcessStart === void 0 ? {} : { processStart: ownerProcessStart },
|
|
@@ -2955,7 +2969,7 @@ async function acquireDebugSessionLock(target, options = {}) {
|
|
|
2955
2969
|
token,
|
|
2956
2970
|
target: targetIdentity
|
|
2957
2971
|
};
|
|
2958
|
-
await
|
|
2972
|
+
await mkdir2(lockDirectory, { recursive: true, mode: 448 });
|
|
2959
2973
|
const handle = await open(ownPath, constants3.O_CREAT | constants3.O_EXCL | constants3.O_WRONLY, 384);
|
|
2960
2974
|
try {
|
|
2961
2975
|
await handle.writeFile(`${JSON.stringify(metadata)}
|
|
@@ -2980,7 +2994,7 @@ async function acquireDebugSessionLock(target, options = {}) {
|
|
|
2980
2994
|
}
|
|
2981
2995
|
await writeLockMetadata(ownPath, { ...metadata, state: "owned" });
|
|
2982
2996
|
} catch (error) {
|
|
2983
|
-
await
|
|
2997
|
+
await unlink2(ownPath).catch(() => {
|
|
2984
2998
|
});
|
|
2985
2999
|
throw error;
|
|
2986
3000
|
}
|
|
@@ -2996,7 +3010,7 @@ async function acquireDebugSessionLock(target, options = {}) {
|
|
|
2996
3010
|
if (current?.token !== token || current.pid !== pid) {
|
|
2997
3011
|
return;
|
|
2998
3012
|
}
|
|
2999
|
-
await
|
|
3013
|
+
await unlink2(ownPath).catch((error) => {
|
|
3000
3014
|
if (!isNodeError(error, "ENOENT")) {
|
|
3001
3015
|
throw error;
|
|
3002
3016
|
}
|
|
@@ -3025,28 +3039,28 @@ function debugTargetIdentity(target) {
|
|
|
3025
3039
|
}
|
|
3026
3040
|
function defaultStateRoot() {
|
|
3027
3041
|
const configured = process.env["CF_INSPECTOR_STATE_DIR"]?.trim();
|
|
3028
|
-
return configured === void 0 || configured.length === 0 ?
|
|
3042
|
+
return configured === void 0 || configured.length === 0 ? join9(homedir3(), ".saptools") : configured;
|
|
3029
3043
|
}
|
|
3030
3044
|
async function findLiveContenders(lockDirectory, key, ownPath, isProcessAlive, getProcessStart) {
|
|
3031
3045
|
const prefix = `${key}.`;
|
|
3032
|
-
const names = await
|
|
3046
|
+
const names = await readdir3(lockDirectory);
|
|
3033
3047
|
const contenders = [];
|
|
3034
3048
|
for (const name of names) {
|
|
3035
3049
|
if (!name.startsWith(prefix) || !name.endsWith(LOCK_FILE_SUFFIX)) {
|
|
3036
3050
|
continue;
|
|
3037
3051
|
}
|
|
3038
|
-
const path =
|
|
3052
|
+
const path = join9(lockDirectory, name);
|
|
3039
3053
|
if (path === ownPath) {
|
|
3040
3054
|
continue;
|
|
3041
3055
|
}
|
|
3042
|
-
const info = await
|
|
3056
|
+
const info = await stat2(path).catch(() => {
|
|
3043
3057
|
});
|
|
3044
3058
|
const metadata = await readLockMetadata(path) ?? (info === void 0 ? void 0 : metadataFromFilename(name, key, info.mtimeMs));
|
|
3045
3059
|
if (metadata !== void 0) {
|
|
3046
3060
|
if (ownerIsAlive(metadata, isProcessAlive, getProcessStart)) {
|
|
3047
3061
|
contenders.push(metadata);
|
|
3048
3062
|
} else {
|
|
3049
|
-
await
|
|
3063
|
+
await unlink2(path).catch(() => {
|
|
3050
3064
|
});
|
|
3051
3065
|
}
|
|
3052
3066
|
continue;
|
|
@@ -3065,7 +3079,7 @@ async function findLiveContenders(lockDirectory, key, ownPath, isProcessAlive, g
|
|
|
3065
3079
|
}
|
|
3066
3080
|
async function readLockMetadata(path) {
|
|
3067
3081
|
try {
|
|
3068
|
-
const parsed = JSON.parse(await
|
|
3082
|
+
const parsed = JSON.parse(await readFile2(path, "utf8"));
|
|
3069
3083
|
if (!isRecord3(parsed)) {
|
|
3070
3084
|
return void 0;
|
|
3071
3085
|
}
|
|
@@ -3091,7 +3105,7 @@ async function readLockMetadata(path) {
|
|
|
3091
3105
|
}
|
|
3092
3106
|
}
|
|
3093
3107
|
async function writeLockMetadata(path, metadata) {
|
|
3094
|
-
await
|
|
3108
|
+
await writeFile2(path, `${JSON.stringify(metadata)}
|
|
3095
3109
|
`, { encoding: "utf8", mode: 384 });
|
|
3096
3110
|
}
|
|
3097
3111
|
function metadataFromFilename(name, key, mtimeMs) {
|
|
@@ -3408,7 +3422,7 @@ function parsePositiveInt(raw, label) {
|
|
|
3408
3422
|
}
|
|
3409
3423
|
return value;
|
|
3410
3424
|
}
|
|
3411
|
-
function
|
|
3425
|
+
function resolveTarget2(opts, options = {}) {
|
|
3412
3426
|
const port = parsePositiveInt(opts.port, "--port");
|
|
3413
3427
|
const targetIndex = parseTargetIndex(opts.target);
|
|
3414
3428
|
const workerIndex = parseSelectionIndex(opts.worker, "--worker");
|
|
@@ -3453,7 +3467,7 @@ function resolveTarget(opts, options = {}) {
|
|
|
3453
3467
|
);
|
|
3454
3468
|
}
|
|
3455
3469
|
async function resolveTargetWithCurrentCfTarget(opts, options = {}) {
|
|
3456
|
-
return await Promise.resolve(
|
|
3470
|
+
return await Promise.resolve(resolveTarget2(opts, options));
|
|
3457
3471
|
}
|
|
3458
3472
|
function parseTunnelTimeout(opts, options) {
|
|
3459
3473
|
if (options.useTimeoutForTunnel === false) {
|
|
@@ -3679,6 +3693,22 @@ init_types();
|
|
|
3679
3693
|
var REGEX_PREFIX = "regex:";
|
|
3680
3694
|
var REGEX_FLAGS_PATTERN = /^[dgimsuvy]*$/;
|
|
3681
3695
|
var TS_JS_EXT_PATTERN = /\.(?:ts|js|mts|mjs|cts|cjs)$/i;
|
|
3696
|
+
var MAX_REMOTE_ROOT_PATTERN_LENGTH = 200;
|
|
3697
|
+
var NESTED_QUANTIFIER_PATTERN = /\([^()]*[+*][^()]*\)[+*]/;
|
|
3698
|
+
function assertSafeRemoteRootPattern(pattern) {
|
|
3699
|
+
if (pattern.length > MAX_REMOTE_ROOT_PATTERN_LENGTH) {
|
|
3700
|
+
throw new CfInspectorError(
|
|
3701
|
+
"INVALID_REMOTE_ROOT",
|
|
3702
|
+
`--remote-root regex pattern is too long (${pattern.length.toString()} chars, max ${MAX_REMOTE_ROOT_PATTERN_LENGTH.toString()}) \u2014 this bounds worst-case backtracking cost`
|
|
3703
|
+
);
|
|
3704
|
+
}
|
|
3705
|
+
if (NESTED_QUANTIFIER_PATTERN.test(pattern)) {
|
|
3706
|
+
throw new CfInspectorError(
|
|
3707
|
+
"INVALID_REMOTE_ROOT",
|
|
3708
|
+
`--remote-root regex pattern "${pattern}" contains a nested quantifier (e.g. "(x+)+"), which can cause catastrophic backtracking \u2014 simplify the pattern`
|
|
3709
|
+
);
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3682
3712
|
function parseBreakpointSpec(input) {
|
|
3683
3713
|
const idx = input.lastIndexOf(":");
|
|
3684
3714
|
if (idx <= 0 || idx === input.length - 1) {
|
|
@@ -3719,6 +3749,7 @@ function parseRemoteRoot(value) {
|
|
|
3719
3749
|
return { kind: "literal", value: stripTrailingSlash(trimmed) };
|
|
3720
3750
|
}
|
|
3721
3751
|
function toRegex(pattern, flags) {
|
|
3752
|
+
assertSafeRemoteRootPattern(pattern);
|
|
3722
3753
|
return { kind: "regex", pattern, flags };
|
|
3723
3754
|
}
|
|
3724
3755
|
function parseSlashDelimited(value) {
|
|
@@ -5595,7 +5626,7 @@ import process10 from "process";
|
|
|
5595
5626
|
init_types();
|
|
5596
5627
|
|
|
5597
5628
|
// src/logpoint/condition.ts
|
|
5598
|
-
import { randomBytes } from "crypto";
|
|
5629
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
5599
5630
|
var SENTINEL_PREFIX = "__CFI_LOG_";
|
|
5600
5631
|
var SENTINEL_SUFFIX = "__";
|
|
5601
5632
|
var HITS_GLOBAL2 = "globalThis.__CFI_LOG_HITS";
|
|
@@ -5653,7 +5684,7 @@ function buildLogpointCondition(sentinel, expression, options = {}) {
|
|
|
5653
5684
|
return `(${guard})?${iife}:false`;
|
|
5654
5685
|
}
|
|
5655
5686
|
function generateSentinel() {
|
|
5656
|
-
return `${SENTINEL_PREFIX}${
|
|
5687
|
+
return `${SENTINEL_PREFIX}${randomBytes2(8).toString("hex")}${SENTINEL_SUFFIX}`;
|
|
5657
5688
|
}
|
|
5658
5689
|
|
|
5659
5690
|
// src/logpoint/events.ts
|