@rogatio/cli 6.14.2 → 6.14.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/node/index.js +205 -248
- package/package.json +1 -1
package/dist/node/index.js
CHANGED
|
@@ -27188,25 +27188,6 @@ import { readFile as readFile4 } from "node:fs/promises";
|
|
|
27188
27188
|
import { dirname as dirname6, isAbsolute as isAbsolute5, resolve as resolve2 } from "node:path";
|
|
27189
27189
|
|
|
27190
27190
|
// packages/dry-run/dist/node/index.js
|
|
27191
|
-
function parseTestUrl(input) {
|
|
27192
|
-
if (typeof input !== "string" || input.length === 0) {
|
|
27193
|
-
return { ok: false };
|
|
27194
|
-
}
|
|
27195
|
-
let url;
|
|
27196
|
-
try {
|
|
27197
|
-
url = new URL(input);
|
|
27198
|
-
} catch {
|
|
27199
|
-
return { ok: false };
|
|
27200
|
-
}
|
|
27201
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
27202
|
-
return { ok: false };
|
|
27203
|
-
}
|
|
27204
|
-
if (url.origin === "null") {
|
|
27205
|
-
return { ok: false };
|
|
27206
|
-
}
|
|
27207
|
-
return { ok: true, value: { origin: url.origin, href: url.href } };
|
|
27208
|
-
}
|
|
27209
|
-
var DEFAULT_MAX_CASES = 256;
|
|
27210
27191
|
function invalidCase(index, message = "Test case is invalid") {
|
|
27211
27192
|
return {
|
|
27212
27193
|
code: "dryrun.invalid-case",
|
|
@@ -27220,6 +27201,69 @@ function invalidUrl(index, message = "Test case URL is invalid") {
|
|
|
27220
27201
|
function invalidOptions() {
|
|
27221
27202
|
return invalidCase(void 0, "Dry-run options are invalid");
|
|
27222
27203
|
}
|
|
27204
|
+
function batchLimit(maxCases) {
|
|
27205
|
+
return {
|
|
27206
|
+
code: "dryrun.batch-limit",
|
|
27207
|
+
message: `Test batch exceeds maxCases (${maxCases})`
|
|
27208
|
+
};
|
|
27209
|
+
}
|
|
27210
|
+
function buildDimension(state, detail) {
|
|
27211
|
+
return {
|
|
27212
|
+
state,
|
|
27213
|
+
matched: state === "not-applicable" ? null : state === "matched",
|
|
27214
|
+
detail
|
|
27215
|
+
};
|
|
27216
|
+
}
|
|
27217
|
+
function sourceDetail(source, matched) {
|
|
27218
|
+
const subject = source.key === "host" ? "hostname" : "url";
|
|
27219
|
+
return matched ? `${subject} matched /${source.value}/ (${source.key})` : `${subject} did not match /${source.value}/ (${source.key})`;
|
|
27220
|
+
}
|
|
27221
|
+
function sourceDimension(matcher, url) {
|
|
27222
|
+
const sourceState = sourceMatches(matcher.source, url) ? "matched" : "unmatched";
|
|
27223
|
+
return buildDimension(
|
|
27224
|
+
sourceState,
|
|
27225
|
+
sourceDetail(matcher.source, sourceState === "matched")
|
|
27226
|
+
);
|
|
27227
|
+
}
|
|
27228
|
+
function methodDimension(matcher, testCase) {
|
|
27229
|
+
const methodState = testCase.method === void 0 ? "not-applicable" : matcher.method === void 0 || matcher.method === testCase.method ? "matched" : "unmatched";
|
|
27230
|
+
return buildDimension(
|
|
27231
|
+
methodState,
|
|
27232
|
+
methodState === "not-applicable" ? "method not specified" : methodState === "matched" ? matcher.method === void 0 ? "rule has no method constraint" : `method ${testCase.method} matches` : `rule method ${matcher.method} != ${testCase.method}`
|
|
27233
|
+
);
|
|
27234
|
+
}
|
|
27235
|
+
function resourceTypeDimension(matcher, testCase) {
|
|
27236
|
+
const resourceState = testCase.resourceType === void 0 ? "not-applicable" : matcher.resourceTypes.length === 0 || matcher.resourceTypes.includes(testCase.resourceType) ? "matched" : "unmatched";
|
|
27237
|
+
return buildDimension(
|
|
27238
|
+
resourceState,
|
|
27239
|
+
resourceState === "not-applicable" ? "resource type not specified" : resourceState === "matched" ? matcher.resourceTypes.length === 0 ? "rule has no resource type constraint" : `resource type ${testCase.resourceType} matches` : `rule resource types [${matcher.resourceTypes.join(", ")}] exclude ${testCase.resourceType}`
|
|
27240
|
+
);
|
|
27241
|
+
}
|
|
27242
|
+
function safePreview(fn, operation, url, testCase) {
|
|
27243
|
+
try {
|
|
27244
|
+
return fn(operation, url, testCase);
|
|
27245
|
+
} catch {
|
|
27246
|
+
return null;
|
|
27247
|
+
}
|
|
27248
|
+
}
|
|
27249
|
+
function evaluateRule(operation, testCase, previewAction) {
|
|
27250
|
+
const matcher = operation.matcher;
|
|
27251
|
+
const source = sourceDimension(matcher, testCase.url);
|
|
27252
|
+
const method = methodDimension(matcher, testCase);
|
|
27253
|
+
const resourceType = resourceTypeDimension(matcher, testCase);
|
|
27254
|
+
const matched = source.state === "matched" && method.state !== "unmatched" && resourceType.state !== "unmatched";
|
|
27255
|
+
const actionPreview = previewAction ? safePreview(previewAction, operation, testCase.url, testCase) : null;
|
|
27256
|
+
return {
|
|
27257
|
+
groupId: operation.groupId,
|
|
27258
|
+
ruleId: operation.ruleId,
|
|
27259
|
+
matched,
|
|
27260
|
+
source,
|
|
27261
|
+
method,
|
|
27262
|
+
resourceType,
|
|
27263
|
+
actionPreview
|
|
27264
|
+
};
|
|
27265
|
+
}
|
|
27266
|
+
var DEFAULT_MAX_CASES = 256;
|
|
27223
27267
|
function ownPropertyNames(value) {
|
|
27224
27268
|
try {
|
|
27225
27269
|
const names = Object.getOwnPropertyNames(value);
|
|
@@ -27291,32 +27335,6 @@ function validateCase(raw, index) {
|
|
|
27291
27335
|
}
|
|
27292
27336
|
};
|
|
27293
27337
|
}
|
|
27294
|
-
function safePreview(fn, operation, url, testCase) {
|
|
27295
|
-
try {
|
|
27296
|
-
return fn(operation, url, testCase);
|
|
27297
|
-
} catch {
|
|
27298
|
-
return null;
|
|
27299
|
-
}
|
|
27300
|
-
}
|
|
27301
|
-
function buildDimension(state, detail) {
|
|
27302
|
-
return {
|
|
27303
|
-
state,
|
|
27304
|
-
matched: state === "not-applicable" ? null : state === "matched",
|
|
27305
|
-
detail
|
|
27306
|
-
};
|
|
27307
|
-
}
|
|
27308
|
-
function sourceDetail(source, matched) {
|
|
27309
|
-
const subject = source.key === "host" ? "hostname" : "url";
|
|
27310
|
-
return matched ? `${subject} matched /${source.value}/ (${source.key})` : `${subject} did not match /${source.value}/ (${source.key})`;
|
|
27311
|
-
}
|
|
27312
|
-
function emptySummary() {
|
|
27313
|
-
return {
|
|
27314
|
-
caseCount: 0,
|
|
27315
|
-
urlCount: 0,
|
|
27316
|
-
matchedUrlCount: 0,
|
|
27317
|
-
matchedRuleTotal: 0
|
|
27318
|
-
};
|
|
27319
|
-
}
|
|
27320
27338
|
function normalizeOptions(raw) {
|
|
27321
27339
|
if (raw === void 0) {
|
|
27322
27340
|
return { ok: true, maxCases: DEFAULT_MAX_CASES };
|
|
@@ -27354,47 +27372,29 @@ function normalizeOptions(raw) {
|
|
|
27354
27372
|
}
|
|
27355
27373
|
return { ok: true, maxCases, previewAction };
|
|
27356
27374
|
}
|
|
27357
|
-
function
|
|
27358
|
-
const normalizedOptions = normalizeOptions(options);
|
|
27359
|
-
if (!normalizedOptions.ok) {
|
|
27360
|
-
return { results: [], errors: [invalidOptions()], summary: emptySummary() };
|
|
27361
|
-
}
|
|
27362
|
-
const errors = [];
|
|
27375
|
+
function readCaseBatch(cases, maxCases) {
|
|
27363
27376
|
if (!Array.isArray(cases)) {
|
|
27364
27377
|
return {
|
|
27365
|
-
|
|
27366
|
-
|
|
27367
|
-
summary: emptySummary()
|
|
27378
|
+
ok: false,
|
|
27379
|
+
error: invalidCase(void 0, "Test cases must be an array")
|
|
27368
27380
|
};
|
|
27369
27381
|
}
|
|
27370
27382
|
let caseCount;
|
|
27371
27383
|
try {
|
|
27372
27384
|
caseCount = cases.length;
|
|
27373
|
-
if (caseCount >
|
|
27374
|
-
return {
|
|
27375
|
-
results: [],
|
|
27376
|
-
errors: [
|
|
27377
|
-
{
|
|
27378
|
-
code: "dryrun.batch-limit",
|
|
27379
|
-
message: `Test batch exceeds maxCases (${normalizedOptions.maxCases})`
|
|
27380
|
-
}
|
|
27381
|
-
],
|
|
27382
|
-
summary: emptySummary()
|
|
27383
|
-
};
|
|
27385
|
+
if (caseCount > maxCases) {
|
|
27386
|
+
return { ok: false, error: batchLimit(maxCases) };
|
|
27384
27387
|
}
|
|
27385
27388
|
for (let index = 0; index < caseCount; index += 1) {
|
|
27386
27389
|
if (!Object.hasOwn(cases, index)) {
|
|
27387
|
-
return {
|
|
27388
|
-
results: [],
|
|
27389
|
-
errors: [invalidCase(index)],
|
|
27390
|
-
summary: emptySummary()
|
|
27391
|
-
};
|
|
27390
|
+
return { ok: false, error: invalidCase(index) };
|
|
27392
27391
|
}
|
|
27393
27392
|
}
|
|
27394
27393
|
} catch {
|
|
27395
|
-
return {
|
|
27394
|
+
return { ok: false, error: invalidCase() };
|
|
27396
27395
|
}
|
|
27397
|
-
const
|
|
27396
|
+
const errors = [];
|
|
27397
|
+
const valid = [];
|
|
27398
27398
|
for (let index = 0; index < caseCount; index += 1) {
|
|
27399
27399
|
let raw;
|
|
27400
27400
|
try {
|
|
@@ -27405,15 +27405,57 @@ function dryRunProject(operations, cases, options) {
|
|
|
27405
27405
|
}
|
|
27406
27406
|
const result = validateCase(raw, index);
|
|
27407
27407
|
if (result.ok) {
|
|
27408
|
-
|
|
27408
|
+
valid.push({ value: result.value, index });
|
|
27409
27409
|
} else {
|
|
27410
27410
|
errors.push(result.error);
|
|
27411
27411
|
}
|
|
27412
27412
|
}
|
|
27413
|
+
return { ok: true, valid, errors };
|
|
27414
|
+
}
|
|
27415
|
+
function parseTestUrl(input) {
|
|
27416
|
+
if (typeof input !== "string" || input.length === 0) {
|
|
27417
|
+
return { ok: false };
|
|
27418
|
+
}
|
|
27419
|
+
let url;
|
|
27420
|
+
try {
|
|
27421
|
+
url = new URL(input);
|
|
27422
|
+
} catch {
|
|
27423
|
+
return { ok: false };
|
|
27424
|
+
}
|
|
27425
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
27426
|
+
return { ok: false };
|
|
27427
|
+
}
|
|
27428
|
+
if (url.origin === "null") {
|
|
27429
|
+
return { ok: false };
|
|
27430
|
+
}
|
|
27431
|
+
return { ok: true, value: { origin: url.origin, href: url.href } };
|
|
27432
|
+
}
|
|
27433
|
+
function emptySummary() {
|
|
27434
|
+
return {
|
|
27435
|
+
caseCount: 0,
|
|
27436
|
+
urlCount: 0,
|
|
27437
|
+
matchedUrlCount: 0,
|
|
27438
|
+
matchedRuleTotal: 0
|
|
27439
|
+
};
|
|
27440
|
+
}
|
|
27441
|
+
function dryRunProject(operations, cases, options) {
|
|
27442
|
+
const normalizedOptions = normalizeOptions(options);
|
|
27443
|
+
if (!normalizedOptions.ok) {
|
|
27444
|
+
return { results: [], errors: [invalidOptions()], summary: emptySummary() };
|
|
27445
|
+
}
|
|
27446
|
+
const batch = readCaseBatch(cases, normalizedOptions.maxCases);
|
|
27447
|
+
if (!batch.ok) {
|
|
27448
|
+
return {
|
|
27449
|
+
results: [],
|
|
27450
|
+
errors: [batch.error],
|
|
27451
|
+
summary: emptySummary()
|
|
27452
|
+
};
|
|
27453
|
+
}
|
|
27454
|
+
const errors = [...batch.errors];
|
|
27413
27455
|
const results = [];
|
|
27414
27456
|
let matchedUrlCount = 0;
|
|
27415
27457
|
let matchedRuleTotal = 0;
|
|
27416
|
-
for (const validCase of
|
|
27458
|
+
for (const validCase of batch.valid) {
|
|
27417
27459
|
const testCase = validCase.value;
|
|
27418
27460
|
const parsed = parseTestUrl(testCase.url);
|
|
27419
27461
|
if (!parsed.ok) {
|
|
@@ -27422,41 +27464,7 @@ function dryRunProject(operations, cases, options) {
|
|
|
27422
27464
|
}
|
|
27423
27465
|
const rules = [];
|
|
27424
27466
|
for (const op of operations) {
|
|
27425
|
-
|
|
27426
|
-
const sourceState = sourceMatches(
|
|
27427
|
-
matcher.source,
|
|
27428
|
-
testCase.url
|
|
27429
|
-
) ? "matched" : "unmatched";
|
|
27430
|
-
const methodState = testCase.method === void 0 ? "not-applicable" : matcher.method === void 0 || matcher.method === testCase.method ? "matched" : "unmatched";
|
|
27431
|
-
const resourceState = testCase.resourceType === void 0 ? "not-applicable" : matcher.resourceTypes.length === 0 || matcher.resourceTypes.includes(testCase.resourceType) ? "matched" : "unmatched";
|
|
27432
|
-
const matched = sourceState === "matched" && methodState !== "unmatched" && resourceState !== "unmatched";
|
|
27433
|
-
const sourceDim = buildDimension(
|
|
27434
|
-
sourceState,
|
|
27435
|
-
sourceDetail(matcher.source, sourceState === "matched")
|
|
27436
|
-
);
|
|
27437
|
-
const methodDim = buildDimension(
|
|
27438
|
-
methodState,
|
|
27439
|
-
methodState === "not-applicable" ? "method not specified" : methodState === "matched" ? matcher.method === void 0 ? "rule has no method constraint" : `method ${testCase.method} matches` : `rule method ${matcher.method} != ${testCase.method}`
|
|
27440
|
-
);
|
|
27441
|
-
const resourceDim = buildDimension(
|
|
27442
|
-
resourceState,
|
|
27443
|
-
resourceState === "not-applicable" ? "resource type not specified" : resourceState === "matched" ? matcher.resourceTypes.length === 0 ? "rule has no resource type constraint" : `resource type ${testCase.resourceType} matches` : `rule resource types [${matcher.resourceTypes.join(", ")}] exclude ${testCase.resourceType}`
|
|
27444
|
-
);
|
|
27445
|
-
const actionPreview = normalizedOptions.previewAction ? safePreview(
|
|
27446
|
-
normalizedOptions.previewAction,
|
|
27447
|
-
op,
|
|
27448
|
-
testCase.url,
|
|
27449
|
-
testCase
|
|
27450
|
-
) : null;
|
|
27451
|
-
rules.push({
|
|
27452
|
-
groupId: op.groupId,
|
|
27453
|
-
ruleId: op.ruleId,
|
|
27454
|
-
matched,
|
|
27455
|
-
source: sourceDim,
|
|
27456
|
-
method: methodDim,
|
|
27457
|
-
resourceType: resourceDim,
|
|
27458
|
-
actionPreview
|
|
27459
|
-
});
|
|
27467
|
+
rules.push(evaluateRule(op, testCase, normalizedOptions.previewAction));
|
|
27460
27468
|
}
|
|
27461
27469
|
const matchedRuleCount = rules.filter((rule) => rule.matched).length;
|
|
27462
27470
|
results.push({
|
|
@@ -27473,7 +27481,7 @@ function dryRunProject(operations, cases, options) {
|
|
|
27473
27481
|
results,
|
|
27474
27482
|
errors,
|
|
27475
27483
|
summary: {
|
|
27476
|
-
caseCount:
|
|
27484
|
+
caseCount: batch.valid.length,
|
|
27477
27485
|
urlCount: results.length,
|
|
27478
27486
|
matchedUrlCount,
|
|
27479
27487
|
matchedRuleTotal
|
|
@@ -27548,6 +27556,45 @@ function previewRuleAction(operation, url) {
|
|
|
27548
27556
|
return null;
|
|
27549
27557
|
}
|
|
27550
27558
|
|
|
27559
|
+
// packages/cli/src/commands/diagnose.ts
|
|
27560
|
+
function diagnoseProject(projectData) {
|
|
27561
|
+
const diagnostics = [];
|
|
27562
|
+
const schemaResult = validateProjectDetailed(projectData);
|
|
27563
|
+
if (!schemaResult.valid) {
|
|
27564
|
+
for (const error of schemaResult.errors) {
|
|
27565
|
+
diagnostics.push({
|
|
27566
|
+
code: `schema.${error.keyword}`,
|
|
27567
|
+
severity: "error",
|
|
27568
|
+
path: error.instancePath || "/",
|
|
27569
|
+
message: error.message,
|
|
27570
|
+
params: error.params
|
|
27571
|
+
});
|
|
27572
|
+
}
|
|
27573
|
+
return { diagnostics, stage: "schema" };
|
|
27574
|
+
}
|
|
27575
|
+
const compileResult = compileProject(schemaResult.data);
|
|
27576
|
+
if (!compileResult.ok) {
|
|
27577
|
+
for (const diag of compileResult.diagnostics) {
|
|
27578
|
+
diagnostics.push({
|
|
27579
|
+
code: diag.code,
|
|
27580
|
+
severity: diag.severity,
|
|
27581
|
+
path: diag.path,
|
|
27582
|
+
message: diag.message,
|
|
27583
|
+
params: { ...diag.params }
|
|
27584
|
+
});
|
|
27585
|
+
}
|
|
27586
|
+
return { diagnostics, stage: "compiler" };
|
|
27587
|
+
}
|
|
27588
|
+
return {
|
|
27589
|
+
diagnostics,
|
|
27590
|
+
project: schemaResult.data,
|
|
27591
|
+
operations: compileResult.operations
|
|
27592
|
+
};
|
|
27593
|
+
}
|
|
27594
|
+
function formatDiagnostics(diagnostics) {
|
|
27595
|
+
return diagnostics.map((diag) => `${diag.path}: ${diag.message} (${diag.code})`).join("\n");
|
|
27596
|
+
}
|
|
27597
|
+
|
|
27551
27598
|
// packages/cli/src/mock-root-config.ts
|
|
27552
27599
|
import { mkdir as mkdir3, readFile as readFile3, realpath as realpath3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
27553
27600
|
import { homedir } from "node:os";
|
|
@@ -27714,26 +27761,14 @@ function parseUrl(req) {
|
|
|
27714
27761
|
);
|
|
27715
27762
|
return { pathname: url.pathname, searchParams: url.searchParams };
|
|
27716
27763
|
}
|
|
27717
|
-
function parseDiagnostics(result) {
|
|
27718
|
-
if (!result.valid) {
|
|
27719
|
-
return result.errors.map((e) => ({
|
|
27720
|
-
code: `schema.${e.keyword}`,
|
|
27721
|
-
severity: "error",
|
|
27722
|
-
path: e.instancePath || "/",
|
|
27723
|
-
message: e.message,
|
|
27724
|
-
params: e.params
|
|
27725
|
-
}));
|
|
27726
|
-
}
|
|
27727
|
-
return [];
|
|
27728
|
-
}
|
|
27729
27764
|
function schemaDiagnosticsForAssist(value) {
|
|
27730
|
-
const
|
|
27731
|
-
if (
|
|
27732
|
-
return
|
|
27733
|
-
code:
|
|
27765
|
+
const diagnosis = diagnoseProject(value);
|
|
27766
|
+
if (diagnosis.stage !== "schema") return [];
|
|
27767
|
+
return diagnosis.diagnostics.map((diagnostic) => ({
|
|
27768
|
+
code: diagnostic.code,
|
|
27734
27769
|
severity: "error",
|
|
27735
|
-
path:
|
|
27736
|
-
message:
|
|
27770
|
+
path: diagnostic.path,
|
|
27771
|
+
message: diagnostic.message
|
|
27737
27772
|
}));
|
|
27738
27773
|
}
|
|
27739
27774
|
function isAIAssistRequestBody(body) {
|
|
@@ -27745,18 +27780,6 @@ function isAIAssistRequestBody(body) {
|
|
|
27745
27780
|
if (!isRecord2(body.context) || !isRecord2(body.context.project)) return false;
|
|
27746
27781
|
return true;
|
|
27747
27782
|
}
|
|
27748
|
-
function parseCompilerDiagnostics(result) {
|
|
27749
|
-
if (!result.ok) {
|
|
27750
|
-
return result.diagnostics.map((d) => ({
|
|
27751
|
-
code: d.code,
|
|
27752
|
-
severity: d.severity,
|
|
27753
|
-
path: d.path,
|
|
27754
|
-
message: d.message,
|
|
27755
|
-
params: d.params
|
|
27756
|
-
}));
|
|
27757
|
-
}
|
|
27758
|
-
return [];
|
|
27759
|
-
}
|
|
27760
27783
|
function createRoutes(context) {
|
|
27761
27784
|
return async function handleRequest(req, res) {
|
|
27762
27785
|
const host = headerValue3(req.headers.host);
|
|
@@ -27878,14 +27901,9 @@ function createRoutes(context) {
|
|
|
27878
27901
|
res.end(JSON.stringify(failure2.body));
|
|
27879
27902
|
return;
|
|
27880
27903
|
}
|
|
27881
|
-
const
|
|
27882
|
-
const diagnostics = [...parseDiagnostics(schemaResult)];
|
|
27883
|
-
if (schemaResult.valid) {
|
|
27884
|
-
const compileResult = compileProject(schemaResult.data);
|
|
27885
|
-
diagnostics.push(...parseCompilerDiagnostics(compileResult));
|
|
27886
|
-
}
|
|
27904
|
+
const diagnosis = diagnoseProject(body);
|
|
27887
27905
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
27888
|
-
res.end(JSON.stringify({ diagnostics }));
|
|
27906
|
+
res.end(JSON.stringify({ diagnostics: diagnosis.diagnostics }));
|
|
27889
27907
|
return;
|
|
27890
27908
|
}
|
|
27891
27909
|
if (pathname === "/api/mock-root" && method === "GET") {
|
|
@@ -27963,26 +27981,25 @@ function createRoutes(context) {
|
|
|
27963
27981
|
res.end(JSON.stringify(failure2.body));
|
|
27964
27982
|
return;
|
|
27965
27983
|
}
|
|
27966
|
-
const
|
|
27967
|
-
if (
|
|
27984
|
+
const diagnosis = diagnoseProject(body);
|
|
27985
|
+
if (diagnosis.stage === "schema") {
|
|
27968
27986
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
27969
27987
|
res.end(
|
|
27970
27988
|
JSON.stringify({
|
|
27971
27989
|
code: "validation-failed",
|
|
27972
27990
|
message: "Project validation failed",
|
|
27973
|
-
diagnostics:
|
|
27991
|
+
diagnostics: diagnosis.diagnostics
|
|
27974
27992
|
})
|
|
27975
27993
|
);
|
|
27976
27994
|
return;
|
|
27977
27995
|
}
|
|
27978
|
-
|
|
27979
|
-
if (!compileResult.ok) {
|
|
27996
|
+
if (diagnosis.stage === "compiler") {
|
|
27980
27997
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
27981
27998
|
res.end(
|
|
27982
27999
|
JSON.stringify({
|
|
27983
28000
|
code: "compilation-failed",
|
|
27984
28001
|
message: "Project compilation failed",
|
|
27985
|
-
diagnostics:
|
|
28002
|
+
diagnostics: diagnosis.diagnostics
|
|
27986
28003
|
})
|
|
27987
28004
|
);
|
|
27988
28005
|
return;
|
|
@@ -28061,35 +28078,37 @@ function createRoutes(context) {
|
|
|
28061
28078
|
);
|
|
28062
28079
|
return;
|
|
28063
28080
|
}
|
|
28064
|
-
const
|
|
28065
|
-
if (
|
|
28081
|
+
const diagnosis = diagnoseProject(body.project);
|
|
28082
|
+
if (diagnosis.stage === "schema") {
|
|
28066
28083
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
28067
28084
|
res.end(
|
|
28068
28085
|
JSON.stringify({
|
|
28069
28086
|
code: "validation-failed",
|
|
28070
28087
|
message: "Project validation failed",
|
|
28071
|
-
diagnostics:
|
|
28088
|
+
diagnostics: diagnosis.diagnostics
|
|
28072
28089
|
})
|
|
28073
28090
|
);
|
|
28074
28091
|
return;
|
|
28075
28092
|
}
|
|
28076
|
-
|
|
28077
|
-
if (!compileResult.ok) {
|
|
28093
|
+
if (diagnosis.stage === "compiler") {
|
|
28078
28094
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
28079
28095
|
res.end(
|
|
28080
28096
|
JSON.stringify({
|
|
28081
28097
|
code: "compilation-failed",
|
|
28082
28098
|
message: "Project compilation failed",
|
|
28083
|
-
diagnostics:
|
|
28099
|
+
diagnostics: diagnosis.diagnostics
|
|
28084
28100
|
})
|
|
28085
28101
|
);
|
|
28086
28102
|
return;
|
|
28087
28103
|
}
|
|
28104
|
+
if (diagnosis.operations === void 0) {
|
|
28105
|
+
throw new Error("Valid project diagnosis is missing operations");
|
|
28106
|
+
}
|
|
28088
28107
|
const requested = isRecord2(body.options) && typeof body.options.maxCases === "number" && Number.isSafeInteger(body.options.maxCases) && body.options.maxCases > 0 ? body.options.maxCases : void 0;
|
|
28089
28108
|
const options = { previewAction: previewRuleAction };
|
|
28090
28109
|
if (requested !== void 0) options.maxCases = requested;
|
|
28091
28110
|
const result = dryRunProject(
|
|
28092
|
-
|
|
28111
|
+
diagnosis.operations,
|
|
28093
28112
|
body.cases,
|
|
28094
28113
|
options
|
|
28095
28114
|
);
|
|
@@ -29217,9 +29236,12 @@ var METHOD_SET = new Set(HTTP_METHODS);
|
|
|
29217
29236
|
var SOURCE_CHANGE = {
|
|
29218
29237
|
caseInsensitive: "The case-insensitive match flag was dropped. Rogatio regular expressions are case-sensitive.",
|
|
29219
29238
|
hostPort: "Requestly compares the host and a non-default port. This host condition matches the hostname on any port.",
|
|
29220
|
-
hostAsUrl: "The host condition was imported as a URL regular expression
|
|
29239
|
+
hostAsUrl: "The host condition was imported as a URL regular expression over the authority. Wildcard host patterns accept any numeric port; Contains does not pin a port.",
|
|
29221
29240
|
path: "The path condition was imported as a URL regular expression."
|
|
29222
29241
|
};
|
|
29242
|
+
var HOST_MATCHES_SKIP_REASON = "Host regular expressions cannot be confined to the host in a URL regex.";
|
|
29243
|
+
var HOST_AUTHORITY_META_SKIP_REASON = "Host Contains or Wildcard values with /, ?, #, @, or \\ cannot be confined to the host in a URL regex.";
|
|
29244
|
+
var HOST_AUTHORITY_META = /[/?#@\\]/;
|
|
29223
29245
|
function escapeRegex(literal) {
|
|
29224
29246
|
return literal.replace(/[\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
29225
29247
|
}
|
|
@@ -29353,24 +29375,26 @@ function convertHost(operator, value) {
|
|
|
29353
29375
|
};
|
|
29354
29376
|
}
|
|
29355
29377
|
if (operator === "Contains") {
|
|
29356
|
-
|
|
29378
|
+
if (HOST_AUTHORITY_META.test(value)) {
|
|
29379
|
+
return { ok: false, reason: HOST_AUTHORITY_META_SKIP_REASON };
|
|
29380
|
+
}
|
|
29381
|
+
const body = value.length === 0 ? "[^/?#@]*" : `[^/?#@]*${escapeRegex(value)}[^/?#@]*`;
|
|
29357
29382
|
return finishUrl(`^https?:\\/\\/${body}(?:[/?#].*)?$`, [
|
|
29358
29383
|
SOURCE_CHANGE.hostAsUrl
|
|
29359
29384
|
]);
|
|
29360
29385
|
}
|
|
29361
29386
|
if (operator === "Wildcard_Matches") {
|
|
29362
|
-
|
|
29363
|
-
|
|
29364
|
-
|
|
29365
|
-
}
|
|
29366
|
-
if (operator === "Matches") {
|
|
29367
|
-
const parsed = parseRequestlyRegex(value);
|
|
29368
|
-
if (!parsed.ok) return parsed;
|
|
29387
|
+
if (HOST_AUTHORITY_META.test(value)) {
|
|
29388
|
+
return { ok: false, reason: HOST_AUTHORITY_META_SKIP_REASON };
|
|
29389
|
+
}
|
|
29369
29390
|
return finishUrl(
|
|
29370
|
-
`^https
|
|
29371
|
-
|
|
29391
|
+
`^https?:\\/\\/${hostWildcardBody(value)}(?::[0-9]+)?(?:[/?#].*)?$`,
|
|
29392
|
+
[SOURCE_CHANGE.hostAsUrl]
|
|
29372
29393
|
);
|
|
29373
29394
|
}
|
|
29395
|
+
if (operator === "Matches") {
|
|
29396
|
+
return { ok: false, reason: HOST_MATCHES_SKIP_REASON };
|
|
29397
|
+
}
|
|
29374
29398
|
return { ok: false, reason: `Unsupported source operator "${operator}".` };
|
|
29375
29399
|
}
|
|
29376
29400
|
function convertPath(operator, value) {
|
|
@@ -29439,6 +29463,9 @@ function parseRequestlyRegex(value) {
|
|
|
29439
29463
|
function wildcardBody(pattern) {
|
|
29440
29464
|
return pattern.split("*").map((part) => escapeRegex(part)).join("(.*?)");
|
|
29441
29465
|
}
|
|
29466
|
+
function hostWildcardBody(pattern) {
|
|
29467
|
+
return pattern.split("*").map((part) => escapeRegex(part)).join("([^/?#@]*?)");
|
|
29468
|
+
}
|
|
29442
29469
|
function isRequestlyRegexLiteral(value) {
|
|
29443
29470
|
return REQUESTLY_REGEX.test(value);
|
|
29444
29471
|
}
|
|
@@ -31023,41 +31050,6 @@ function cloneProject(value) {
|
|
|
31023
31050
|
return record;
|
|
31024
31051
|
}
|
|
31025
31052
|
|
|
31026
|
-
// packages/cli/src/commands/diagnose.ts
|
|
31027
|
-
function diagnoseProject(projectData) {
|
|
31028
|
-
const diagnostics = [];
|
|
31029
|
-
const schemaResult = validateProjectDetailed(projectData);
|
|
31030
|
-
if (!schemaResult.valid) {
|
|
31031
|
-
for (const error of schemaResult.errors) {
|
|
31032
|
-
diagnostics.push({
|
|
31033
|
-
code: `schema.${error.keyword}`,
|
|
31034
|
-
severity: "error",
|
|
31035
|
-
path: error.instancePath || "/",
|
|
31036
|
-
message: error.message,
|
|
31037
|
-
params: error.params
|
|
31038
|
-
});
|
|
31039
|
-
}
|
|
31040
|
-
return { diagnostics };
|
|
31041
|
-
}
|
|
31042
|
-
const compileResult = compileProject(schemaResult.data);
|
|
31043
|
-
if (!compileResult.ok) {
|
|
31044
|
-
for (const diag of compileResult.diagnostics) {
|
|
31045
|
-
diagnostics.push({
|
|
31046
|
-
code: diag.code,
|
|
31047
|
-
severity: diag.severity,
|
|
31048
|
-
path: diag.path,
|
|
31049
|
-
message: diag.message,
|
|
31050
|
-
params: { ...diag.params }
|
|
31051
|
-
});
|
|
31052
|
-
}
|
|
31053
|
-
return { diagnostics };
|
|
31054
|
-
}
|
|
31055
|
-
return { diagnostics, project: schemaResult.data };
|
|
31056
|
-
}
|
|
31057
|
-
function formatDiagnostics(diagnostics) {
|
|
31058
|
-
return diagnostics.map((diag) => `${diag.path}: ${diag.message} (${diag.code})`).join("\n");
|
|
31059
|
-
}
|
|
31060
|
-
|
|
31061
31053
|
// packages/cli/src/commands/import.ts
|
|
31062
31054
|
async function importCommand(args) {
|
|
31063
31055
|
const parsed = parseImportArgs(args);
|
|
@@ -31615,27 +31607,6 @@ function resultOptions(maxCases) {
|
|
|
31615
31607
|
if (maxCases !== void 0) options.maxCases = maxCases;
|
|
31616
31608
|
return options;
|
|
31617
31609
|
}
|
|
31618
|
-
function diagnosticsFromSchema(projectData) {
|
|
31619
|
-
const result = validateProjectDetailed(projectData);
|
|
31620
|
-
if (result.valid) return [];
|
|
31621
|
-
return result.errors.map((error) => ({
|
|
31622
|
-
code: `schema.${error.keyword}`,
|
|
31623
|
-
severity: "error",
|
|
31624
|
-
path: error.instancePath || "/",
|
|
31625
|
-
message: error.message,
|
|
31626
|
-
params: error.params
|
|
31627
|
-
}));
|
|
31628
|
-
}
|
|
31629
|
-
function diagnosticsFromCompiler(result) {
|
|
31630
|
-
if (result.ok) return [];
|
|
31631
|
-
return result.diagnostics.map((diagnostic) => ({
|
|
31632
|
-
code: diagnostic.code,
|
|
31633
|
-
severity: diagnostic.severity,
|
|
31634
|
-
path: diagnostic.path,
|
|
31635
|
-
message: diagnostic.message,
|
|
31636
|
-
params: diagnostic.params
|
|
31637
|
-
}));
|
|
31638
|
-
}
|
|
31639
31610
|
function jsonOutput(value) {
|
|
31640
31611
|
return `${JSON.stringify(value, null, 2)}
|
|
31641
31612
|
`;
|
|
@@ -31777,21 +31748,9 @@ async function testCommandImpl(args, stdinInput, captureOutput, options = {}) {
|
|
|
31777
31748
|
console.error(output.trim());
|
|
31778
31749
|
return 2;
|
|
31779
31750
|
}
|
|
31780
|
-
const
|
|
31781
|
-
|
|
31782
|
-
|
|
31783
|
-
const output = jsonMode ? jsonOutput({ diagnostics }) : diagnostics.map(
|
|
31784
|
-
(diagnostic) => `${diagnostic.path}: ${diagnostic.message} (${diagnostic.code})
|
|
31785
|
-
`
|
|
31786
|
-
).join("");
|
|
31787
|
-
if (captureOutput) return output;
|
|
31788
|
-
if (jsonMode) console.log(output.trim());
|
|
31789
|
-
else console.error(output.trim());
|
|
31790
|
-
return 1;
|
|
31791
|
-
}
|
|
31792
|
-
const compileResult = compileProject(schemaResult.data);
|
|
31793
|
-
diagnostics = diagnosticsFromCompiler(compileResult);
|
|
31794
|
-
if (!compileResult.ok) {
|
|
31751
|
+
const diagnosis = diagnoseProject(projectData);
|
|
31752
|
+
if (diagnosis.stage !== void 0 || diagnosis.project === void 0 || diagnosis.operations === void 0) {
|
|
31753
|
+
const diagnostics = diagnosis.diagnostics;
|
|
31795
31754
|
const output = jsonMode ? jsonOutput({ diagnostics }) : diagnostics.map(
|
|
31796
31755
|
(diagnostic) => `${diagnostic.path}: ${diagnostic.message} (${diagnostic.code})
|
|
31797
31756
|
`
|
|
@@ -31807,7 +31766,7 @@ async function testCommandImpl(args, stdinInput, captureOutput, options = {}) {
|
|
|
31807
31766
|
defaultResourceType
|
|
31808
31767
|
);
|
|
31809
31768
|
const dryRunResult = dryRunProject(
|
|
31810
|
-
|
|
31769
|
+
diagnosis.operations,
|
|
31811
31770
|
testCases,
|
|
31812
31771
|
resultOptions(maxCases)
|
|
31813
31772
|
);
|
|
@@ -31817,13 +31776,11 @@ async function testCommandImpl(args, stdinInput, captureOutput, options = {}) {
|
|
|
31817
31776
|
console.log(output.trim());
|
|
31818
31777
|
} else {
|
|
31819
31778
|
const groupNames = /* @__PURE__ */ new Map();
|
|
31820
|
-
|
|
31821
|
-
|
|
31822
|
-
groupNames.set(group.id, group.name);
|
|
31823
|
-
}
|
|
31779
|
+
for (const group of diagnosis.project.groups) {
|
|
31780
|
+
groupNames.set(group.id, group.name);
|
|
31824
31781
|
}
|
|
31825
31782
|
const labels = /* @__PURE__ */ new Map();
|
|
31826
|
-
for (const operation of
|
|
31783
|
+
for (const operation of diagnosis.operations) {
|
|
31827
31784
|
const groupName = groupNames.get(operation.groupId);
|
|
31828
31785
|
labels.set(
|
|
31829
31786
|
`${operation.groupId}/${operation.ruleId}`,
|
package/package.json
CHANGED