@rogatio/cli 6.13.0 → 6.14.1
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/README.md +1 -1
- package/dist/editor/index.css +29 -0
- package/dist/editor/index.js +282 -31
- package/dist/node/index.js +1553 -390
- package/package.json +3 -2
package/dist/node/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// packages/cli/src/index.ts
|
|
4
4
|
import { realpathSync } from "node:fs";
|
|
5
|
-
import { basename as basename3, dirname as
|
|
5
|
+
import { basename as basename3, dirname as dirname10, resolve as resolve9 } from "node:path";
|
|
6
6
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7
7
|
|
|
8
8
|
// packages/runtime/dist/node/index.js
|
|
@@ -701,7 +701,8 @@ var projectSchemaDefinition = {
|
|
|
701
701
|
"query",
|
|
702
702
|
"header",
|
|
703
703
|
"response-body",
|
|
704
|
-
"request-body"
|
|
704
|
+
"request-body",
|
|
705
|
+
"mock"
|
|
705
706
|
]
|
|
706
707
|
},
|
|
707
708
|
redirect: {
|
|
@@ -726,6 +727,7 @@ var projectSchemaDefinition = {
|
|
|
726
727
|
},
|
|
727
728
|
responseBody: { $ref: "#/$defs/responseBodyAction" },
|
|
728
729
|
requestBody: { $ref: "#/$defs/requestBodyAction" },
|
|
730
|
+
mock: { $ref: "#/$defs/mockAction" },
|
|
729
731
|
redactSensitiveInLogs: { type: "boolean" }
|
|
730
732
|
},
|
|
731
733
|
allOf: [
|
|
@@ -808,9 +810,66 @@ var projectSchemaDefinition = {
|
|
|
808
810
|
then: {
|
|
809
811
|
required: ["requestBody", "method", "resourceTypes"]
|
|
810
812
|
}
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
if: {
|
|
816
|
+
required: ["type"],
|
|
817
|
+
properties: { type: { const: "mock" } }
|
|
818
|
+
},
|
|
819
|
+
// biome-ignore lint/suspicious/noThenProperty: AJV conditional schema keyword
|
|
820
|
+
then: {
|
|
821
|
+
required: ["mock"]
|
|
822
|
+
}
|
|
811
823
|
}
|
|
812
824
|
]
|
|
813
825
|
},
|
|
826
|
+
mockHeader: {
|
|
827
|
+
type: "object",
|
|
828
|
+
additionalProperties: false,
|
|
829
|
+
required: ["name", "value"],
|
|
830
|
+
properties: {
|
|
831
|
+
name: {
|
|
832
|
+
type: "string",
|
|
833
|
+
minLength: 1,
|
|
834
|
+
maxLength: LIMITS.maxMockHeaderNameLength
|
|
835
|
+
},
|
|
836
|
+
value: {
|
|
837
|
+
type: "string",
|
|
838
|
+
maxLength: LIMITS.maxMockHeaderValueLength
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
},
|
|
842
|
+
mockAction: {
|
|
843
|
+
type: "object",
|
|
844
|
+
additionalProperties: false,
|
|
845
|
+
required: ["status"],
|
|
846
|
+
properties: {
|
|
847
|
+
status: {
|
|
848
|
+
type: "integer",
|
|
849
|
+
minimum: LIMITS.minMockStatus,
|
|
850
|
+
maximum: LIMITS.maxMockStatus
|
|
851
|
+
},
|
|
852
|
+
headers: {
|
|
853
|
+
type: "array",
|
|
854
|
+
maxItems: LIMITS.maxMockHeadersPerRule,
|
|
855
|
+
items: { $ref: "#/$defs/mockHeader" }
|
|
856
|
+
},
|
|
857
|
+
delayMs: {
|
|
858
|
+
type: "integer",
|
|
859
|
+
minimum: 0,
|
|
860
|
+
maximum: LIMITS.maxMockDelayMs
|
|
861
|
+
},
|
|
862
|
+
body: {
|
|
863
|
+
type: "string",
|
|
864
|
+
maxLength: LIMITS.maxMockInlineBodyLength
|
|
865
|
+
},
|
|
866
|
+
file: {
|
|
867
|
+
type: "string",
|
|
868
|
+
minLength: 1,
|
|
869
|
+
maxLength: LIMITS.maxMockFilePathLength
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
},
|
|
814
873
|
queryParam: {
|
|
815
874
|
type: "object",
|
|
816
875
|
additionalProperties: false,
|
|
@@ -1178,18 +1237,19 @@ function semanticIssues(project) {
|
|
|
1178
1237
|
ids.set(rule.id, `${rulePath}/id`);
|
|
1179
1238
|
}
|
|
1180
1239
|
claimName(rule.name, `${rulePath}/name`);
|
|
1181
|
-
if (rule.type !== void 0 && rule.type !== "redirect" && rule.type !== "query" && rule.type !== "header" && rule.type !== "response-body" && rule.type !== "request-body") {
|
|
1240
|
+
if (rule.type !== void 0 && rule.type !== "redirect" && rule.type !== "query" && rule.type !== "header" && rule.type !== "response-body" && rule.type !== "request-body" && rule.type !== "mock") {
|
|
1182
1241
|
issues.push({
|
|
1183
1242
|
instancePath: `${rulePath}/type`,
|
|
1184
1243
|
keyword: "enum",
|
|
1185
|
-
message: 'must be "redirect", "query", "header", "response-body",
|
|
1244
|
+
message: 'must be "redirect", "query", "header", "response-body", "request-body", or "mock"',
|
|
1186
1245
|
params: {
|
|
1187
1246
|
allowedValues: [
|
|
1188
1247
|
"redirect",
|
|
1189
1248
|
"query",
|
|
1190
1249
|
"header",
|
|
1191
1250
|
"response-body",
|
|
1192
|
-
"request-body"
|
|
1251
|
+
"request-body",
|
|
1252
|
+
"mock"
|
|
1193
1253
|
]
|
|
1194
1254
|
}
|
|
1195
1255
|
});
|
|
@@ -1481,6 +1541,86 @@ function semanticIssues(project) {
|
|
|
1481
1541
|
});
|
|
1482
1542
|
}
|
|
1483
1543
|
}
|
|
1544
|
+
if (rule.type === "mock") {
|
|
1545
|
+
const mock = rule.mock;
|
|
1546
|
+
const mockPath = `${rulePath}/mock`;
|
|
1547
|
+
if (mock !== void 0) {
|
|
1548
|
+
const forbiddenMockStatuses = /* @__PURE__ */ new Set([204, 205, 304]);
|
|
1549
|
+
if (forbiddenMockStatuses.has(mock.status)) {
|
|
1550
|
+
issues.push({
|
|
1551
|
+
instancePath: `${mockPath}/status`,
|
|
1552
|
+
keyword: "mock-status",
|
|
1553
|
+
message: "Mock status must not be 204, 205, or 304 because those responses require special body handling.",
|
|
1554
|
+
params: { status: mock.status }
|
|
1555
|
+
});
|
|
1556
|
+
}
|
|
1557
|
+
const bodySet = mock.body !== void 0;
|
|
1558
|
+
const fileSet = mock.file !== void 0;
|
|
1559
|
+
if (bodySet === fileSet) {
|
|
1560
|
+
issues.push({
|
|
1561
|
+
instancePath: mockPath,
|
|
1562
|
+
keyword: "mock-body-source",
|
|
1563
|
+
message: "Mock rules require exactly one of body or file.",
|
|
1564
|
+
params: {}
|
|
1565
|
+
});
|
|
1566
|
+
} else if (fileSet && typeof mock.file === "string" && !isValidMockLogicalPath(mock.file)) {
|
|
1567
|
+
issues.push({
|
|
1568
|
+
instancePath: `${mockPath}/file`,
|
|
1569
|
+
keyword: "mock-file-path",
|
|
1570
|
+
message: "Mock file must be a relative logical path without absolute segments, backslashes, percent escapes, control characters, dot segments, colons, or glob characters.",
|
|
1571
|
+
params: {}
|
|
1572
|
+
});
|
|
1573
|
+
}
|
|
1574
|
+
if (mock.headers !== void 0) {
|
|
1575
|
+
const seenHeaderNames = /* @__PURE__ */ new Set();
|
|
1576
|
+
for (let index = 0; index < mock.headers.length; index += 1) {
|
|
1577
|
+
const header = mock.headers[index];
|
|
1578
|
+
if (header === void 0) continue;
|
|
1579
|
+
const namePath = `${mockPath}/headers/${index}/name`;
|
|
1580
|
+
const valuePath = `${mockPath}/headers/${index}/value`;
|
|
1581
|
+
if (hasControl(header.name)) {
|
|
1582
|
+
issues.push({
|
|
1583
|
+
instancePath: namePath,
|
|
1584
|
+
keyword: "mock-header-control",
|
|
1585
|
+
message: "Mock header names must not contain control characters.",
|
|
1586
|
+
params: {}
|
|
1587
|
+
});
|
|
1588
|
+
}
|
|
1589
|
+
if (hasControl(header.value)) {
|
|
1590
|
+
issues.push({
|
|
1591
|
+
instancePath: valuePath,
|
|
1592
|
+
keyword: "mock-header-control",
|
|
1593
|
+
message: "Mock header values must not contain control characters.",
|
|
1594
|
+
params: {}
|
|
1595
|
+
});
|
|
1596
|
+
}
|
|
1597
|
+
const comparableName = header.name.trim();
|
|
1598
|
+
if (isForbiddenHeader(comparableName, "response")) {
|
|
1599
|
+
issues.push({
|
|
1600
|
+
instancePath: namePath,
|
|
1601
|
+
keyword: "forbiddenHeader",
|
|
1602
|
+
message: `Header "${header.name}" is forbidden for response headers.`,
|
|
1603
|
+
params: {
|
|
1604
|
+
headerName: header.name,
|
|
1605
|
+
headerDirection: "response"
|
|
1606
|
+
}
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
const normalizedName = comparableName.toLowerCase();
|
|
1610
|
+
if (seenHeaderNames.has(normalizedName)) {
|
|
1611
|
+
issues.push({
|
|
1612
|
+
instancePath: namePath,
|
|
1613
|
+
keyword: "uniqueMockHeaderName",
|
|
1614
|
+
message: `mock header name must be unique; duplicate "${header.name}"`,
|
|
1615
|
+
params: { name: header.name }
|
|
1616
|
+
});
|
|
1617
|
+
} else {
|
|
1618
|
+
seenHeaderNames.add(normalizedName);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1484
1624
|
}
|
|
1485
1625
|
}
|
|
1486
1626
|
if (project.requestBodyPolicy !== void 0) {
|
|
@@ -1546,6 +1686,22 @@ function semanticIssues(project) {
|
|
|
1546
1686
|
}
|
|
1547
1687
|
return issues;
|
|
1548
1688
|
}
|
|
1689
|
+
function isValidMockLogicalPath(value) {
|
|
1690
|
+
if (value.length === 0) return false;
|
|
1691
|
+
if (value.includes("\\") || value.includes("%") || hasControl(value)) {
|
|
1692
|
+
return false;
|
|
1693
|
+
}
|
|
1694
|
+
if (value.startsWith("/") || value.endsWith("/") || value.includes("//")) {
|
|
1695
|
+
return false;
|
|
1696
|
+
}
|
|
1697
|
+
const parts = value.split("/");
|
|
1698
|
+
if (parts.some(
|
|
1699
|
+
(part) => part.length === 0 || part === "." || part === ".." || part.includes(":") || /[*?[\]]/.test(part)
|
|
1700
|
+
)) {
|
|
1701
|
+
return false;
|
|
1702
|
+
}
|
|
1703
|
+
return true;
|
|
1704
|
+
}
|
|
1549
1705
|
function captureValidationIssues(value, urlRegex, instancePath) {
|
|
1550
1706
|
return validateCaptureTemplate(value, urlRegex).map((issue) => ({
|
|
1551
1707
|
instancePath,
|
|
@@ -1739,7 +1895,9 @@ var MESSAGES = {
|
|
|
1739
1895
|
"compiler.header-value-required": "Header value is required for set and append operations.",
|
|
1740
1896
|
"compiler.header-value-unexpected": "Header value must not be provided for remove operation.",
|
|
1741
1897
|
"compiler.invalid-header-direction": "Invalid header direction.",
|
|
1742
|
-
"compiler.invalid-header-operation": "Invalid header operation."
|
|
1898
|
+
"compiler.invalid-header-operation": "Invalid header operation.",
|
|
1899
|
+
"compiler.mock-body-source": "Mock rules require exactly one of body or file.",
|
|
1900
|
+
"compiler.mock-forbidden-header": "The header name is forbidden for mock response headers."
|
|
1743
1901
|
};
|
|
1744
1902
|
function copySafeParams(params) {
|
|
1745
1903
|
const safe = {};
|
|
@@ -1777,9 +1935,22 @@ function stableParams(params) {
|
|
|
1777
1935
|
const keys = Object.keys(params).sort(compareCodeUnits);
|
|
1778
1936
|
return keys.map((key) => `${JSON.stringify(key)}:${JSON.stringify(params[key])}`).join(",");
|
|
1779
1937
|
}
|
|
1938
|
+
var MOCK_HEADER_NAME_PATH = /^\/groups\/\d+\/rules\/\d+\/mock\/headers\/\d+\/name$/;
|
|
1939
|
+
function validationIssueCode(issue) {
|
|
1940
|
+
if (issue.keyword === "mock-body-source") {
|
|
1941
|
+
return "compiler.mock-body-source";
|
|
1942
|
+
}
|
|
1943
|
+
if (issue.keyword === "forbiddenHeader" && MOCK_HEADER_NAME_PATH.test(issue.instancePath)) {
|
|
1944
|
+
return "compiler.mock-forbidden-header";
|
|
1945
|
+
}
|
|
1946
|
+
if (Object.hasOwn(ISSUE_CODES, issue.keyword)) {
|
|
1947
|
+
return ISSUE_CODES[issue.keyword];
|
|
1948
|
+
}
|
|
1949
|
+
return "schema.invalid-value";
|
|
1950
|
+
}
|
|
1780
1951
|
function mapValidationIssues(issues) {
|
|
1781
1952
|
return issues.map((issue) => {
|
|
1782
|
-
const code =
|
|
1953
|
+
const code = validationIssueCode(issue);
|
|
1783
1954
|
return {
|
|
1784
1955
|
code,
|
|
1785
1956
|
severity: "error",
|
|
@@ -1953,6 +2124,21 @@ function compileOperations(project) {
|
|
|
1953
2124
|
requestBody: rule.requestBody ?? { mode: "replace", body: "" }
|
|
1954
2125
|
};
|
|
1955
2126
|
operations.push(operation);
|
|
2127
|
+
} else if (rule.type === "mock") {
|
|
2128
|
+
const mock = rule.mock;
|
|
2129
|
+
if (mock === void 0) {
|
|
2130
|
+
throw new Error("validated mock rule missing mock payload");
|
|
2131
|
+
}
|
|
2132
|
+
const operation = {
|
|
2133
|
+
kind: "mock",
|
|
2134
|
+
groupId: group.id,
|
|
2135
|
+
ruleId: rule.id,
|
|
2136
|
+
name: rule.name,
|
|
2137
|
+
redactSensitiveInLogs,
|
|
2138
|
+
matcher,
|
|
2139
|
+
mock
|
|
2140
|
+
};
|
|
2141
|
+
operations.push(operation);
|
|
1956
2142
|
} else {
|
|
1957
2143
|
const operation = {
|
|
1958
2144
|
kind: "matcher",
|
|
@@ -2070,9 +2256,16 @@ function sameOrigin(a, b) {
|
|
|
2070
2256
|
|
|
2071
2257
|
// packages/runtime/dist/node/index.js
|
|
2072
2258
|
import { isIP as isIP2 } from "node:net";
|
|
2259
|
+
import { constants, existsSync } from "node:fs";
|
|
2260
|
+
import { open, readlink, realpath } from "node:fs/promises";
|
|
2261
|
+
import { isAbsolute, relative } from "node:path";
|
|
2262
|
+
import { close, fstat, read } from "node:fs";
|
|
2263
|
+
import { createRequire } from "node:module";
|
|
2264
|
+
import { constants as constants2 } from "node:fs";
|
|
2265
|
+
import { open as open2, realpath as realpath2 } from "node:fs/promises";
|
|
2266
|
+
import { isAbsolute as isAbsolute2 } from "node:path";
|
|
2073
2267
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
2074
|
-
import { existsSync } from "node:fs";
|
|
2075
|
-
import { createServer as createServer2 } from "node:http";
|
|
2268
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
2076
2269
|
import { join as join3 } from "node:path";
|
|
2077
2270
|
import {
|
|
2078
2271
|
createServer
|
|
@@ -2083,24 +2276,24 @@ import { lookup as dnsLookup } from "node:dns/promises";
|
|
|
2083
2276
|
import { request as httpRequest } from "node:http";
|
|
2084
2277
|
import { request as httpsRequest } from "node:https";
|
|
2085
2278
|
import { createHash as createHash2, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2279
|
+
import { spawn } from "node:child_process";
|
|
2086
2280
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
2087
|
-
import { readFile as readFile2, realpath as realpath2, stat } from "node:fs/promises";
|
|
2088
|
-
import { isAbsolute as isAbsolute2, relative as relative2, resolve, sep } from "node:path";
|
|
2089
2281
|
import { createHash as createHash3 } from "node:crypto";
|
|
2090
|
-
import {
|
|
2091
|
-
import {
|
|
2282
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
2283
|
+
import { mkdir as mkdir2, readFile as readFile2, rename, rm, stat, writeFile as writeFile2 } from "node:fs/promises";
|
|
2284
|
+
import { basename, dirname as dirname2, isAbsolute as isAbsolute3, join as join2, relative as relative2 } from "node:path";
|
|
2092
2285
|
import { generateKeyPairSync, webcrypto } from "node:crypto";
|
|
2093
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
2094
|
-
import { accessSync, constants as
|
|
2286
|
+
import { spawn as spawn2, spawnSync } from "node:child_process";
|
|
2287
|
+
import { accessSync, constants as constants3, unlinkSync, writeFileSync } from "node:fs";
|
|
2095
2288
|
import { tmpdir } from "node:os";
|
|
2096
2289
|
import { dirname as dirname3, join as join4 } from "node:path";
|
|
2097
2290
|
import { join as posixJoin } from "node:path/posix";
|
|
2098
|
-
import { spawn as
|
|
2099
|
-
import { accessSync as accessSync2, constants as
|
|
2291
|
+
import { spawn as spawn3, spawnSync as spawnSync2 } from "node:child_process";
|
|
2292
|
+
import { accessSync as accessSync2, constants as constants4, mkdirSync, unlinkSync as unlinkSync2 } from "node:fs";
|
|
2100
2293
|
import { dirname as dirname4 } from "node:path";
|
|
2101
2294
|
import { join as posixJoin2 } from "node:path/posix";
|
|
2102
|
-
import { spawn as
|
|
2103
|
-
import { accessSync as accessSync3, constants as
|
|
2295
|
+
import { spawn as spawn4, spawnSync as spawnSync3 } from "node:child_process";
|
|
2296
|
+
import { accessSync as accessSync3, constants as constants5, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
2104
2297
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
2105
2298
|
import { join as join5 } from "node:path";
|
|
2106
2299
|
import { join as posixJoin3 } from "node:path/posix";
|
|
@@ -3347,11 +3540,11 @@ function __metadata(metadataKey, metadataValue) {
|
|
|
3347
3540
|
}
|
|
3348
3541
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
3349
3542
|
function adopt(value) {
|
|
3350
|
-
return value instanceof P ? value : new P(function(
|
|
3351
|
-
|
|
3543
|
+
return value instanceof P ? value : new P(function(resolve10) {
|
|
3544
|
+
resolve10(value);
|
|
3352
3545
|
});
|
|
3353
3546
|
}
|
|
3354
|
-
return new (P || (P = Promise))(function(
|
|
3547
|
+
return new (P || (P = Promise))(function(resolve10, reject) {
|
|
3355
3548
|
function fulfilled(value) {
|
|
3356
3549
|
try {
|
|
3357
3550
|
step(generator.next(value));
|
|
@@ -3367,7 +3560,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
3367
3560
|
}
|
|
3368
3561
|
}
|
|
3369
3562
|
function step(result) {
|
|
3370
|
-
result.done ?
|
|
3563
|
+
result.done ? resolve10(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
3371
3564
|
}
|
|
3372
3565
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
3373
3566
|
});
|
|
@@ -3558,14 +3751,14 @@ function __asyncValues(o) {
|
|
|
3558
3751
|
}, i);
|
|
3559
3752
|
function verb(n) {
|
|
3560
3753
|
i[n] = o[n] && function(v) {
|
|
3561
|
-
return new Promise(function(
|
|
3562
|
-
v = o[n](v), settle(
|
|
3754
|
+
return new Promise(function(resolve10, reject) {
|
|
3755
|
+
v = o[n](v), settle(resolve10, reject, v.done, v.value);
|
|
3563
3756
|
});
|
|
3564
3757
|
};
|
|
3565
3758
|
}
|
|
3566
|
-
function settle(
|
|
3759
|
+
function settle(resolve10, reject, d, v) {
|
|
3567
3760
|
Promise.resolve(v).then(function(v2) {
|
|
3568
|
-
|
|
3761
|
+
resolve10({ value: v2, done: d });
|
|
3569
3762
|
}, reject);
|
|
3570
3763
|
}
|
|
3571
3764
|
}
|
|
@@ -3950,8 +4143,8 @@ var require_build = __commonJS({
|
|
|
3950
4143
|
return Buffer.from(buf).toString("base64");
|
|
3951
4144
|
}
|
|
3952
4145
|
}
|
|
3953
|
-
static FromBase64(
|
|
3954
|
-
const formatted = this.formatString(
|
|
4146
|
+
static FromBase64(base64) {
|
|
4147
|
+
const formatted = this.formatString(base64);
|
|
3955
4148
|
if (!formatted) {
|
|
3956
4149
|
return new ArrayBuffer(0);
|
|
3957
4150
|
}
|
|
@@ -4062,14 +4255,14 @@ var require_build = __commonJS({
|
|
|
4062
4255
|
static FromUtf16String(text, littleEndian = false) {
|
|
4063
4256
|
return Utf16Converter.fromString(text, littleEndian);
|
|
4064
4257
|
}
|
|
4065
|
-
static Base64Padding(
|
|
4066
|
-
const padCount = 4 -
|
|
4258
|
+
static Base64Padding(base64) {
|
|
4259
|
+
const padCount = 4 - base64.length % 4;
|
|
4067
4260
|
if (padCount < 4) {
|
|
4068
4261
|
for (let i = 0; i < padCount; i++) {
|
|
4069
|
-
|
|
4262
|
+
base64 += "=";
|
|
4070
4263
|
}
|
|
4071
4264
|
}
|
|
4072
|
-
return
|
|
4265
|
+
return base64;
|
|
4073
4266
|
}
|
|
4074
4267
|
static formatString(data) {
|
|
4075
4268
|
return (data === null || data === void 0 ? void 0 : data.replace(/[\n\r\t ]/g, "")) || "";
|
|
@@ -9054,8 +9247,8 @@ var require_convert2 = __commonJS({
|
|
|
9054
9247
|
static ToBase64(buffer) {
|
|
9055
9248
|
return index_js_1.convert.toBase64(buffer);
|
|
9056
9249
|
}
|
|
9057
|
-
static FromBase64(
|
|
9058
|
-
return index_js_1.convert.fromBase64(
|
|
9250
|
+
static FromBase64(base64) {
|
|
9251
|
+
return index_js_1.convert.fromBase64(base64);
|
|
9059
9252
|
}
|
|
9060
9253
|
static FromBase64Url(base64url) {
|
|
9061
9254
|
return index_js_1.convert.fromBase64Url(base64url);
|
|
@@ -9087,9 +9280,9 @@ var require_convert2 = __commonJS({
|
|
|
9087
9280
|
static FromUtf16String(text, littleEndian = false) {
|
|
9088
9281
|
return index_js_1.convert.fromUtf16String(text, littleEndian);
|
|
9089
9282
|
}
|
|
9090
|
-
static Base64Padding(
|
|
9091
|
-
const padCount = 4 -
|
|
9092
|
-
return padCount < 4 ?
|
|
9283
|
+
static Base64Padding(base64) {
|
|
9284
|
+
const padCount = 4 - base64.length % 4;
|
|
9285
|
+
return padCount < 4 ? base64 + "=".repeat(padCount) : base64;
|
|
9093
9286
|
}
|
|
9094
9287
|
static formatString(data) {
|
|
9095
9288
|
return index_js_1.convert.formatString(data);
|
|
@@ -15043,11 +15236,11 @@ function __metadata2(metadataKey, metadataValue) {
|
|
|
15043
15236
|
}
|
|
15044
15237
|
function __awaiter2(thisArg, _arguments, P, generator) {
|
|
15045
15238
|
function adopt(value) {
|
|
15046
|
-
return value instanceof P ? value : new P(function(
|
|
15047
|
-
|
|
15239
|
+
return value instanceof P ? value : new P(function(resolve10) {
|
|
15240
|
+
resolve10(value);
|
|
15048
15241
|
});
|
|
15049
15242
|
}
|
|
15050
|
-
return new (P || (P = Promise))(function(
|
|
15243
|
+
return new (P || (P = Promise))(function(resolve10, reject) {
|
|
15051
15244
|
function fulfilled(value) {
|
|
15052
15245
|
try {
|
|
15053
15246
|
step(generator.next(value));
|
|
@@ -15063,7 +15256,7 @@ function __awaiter2(thisArg, _arguments, P, generator) {
|
|
|
15063
15256
|
}
|
|
15064
15257
|
}
|
|
15065
15258
|
function step(result) {
|
|
15066
|
-
result.done ?
|
|
15259
|
+
result.done ? resolve10(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
15067
15260
|
}
|
|
15068
15261
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
15069
15262
|
});
|
|
@@ -15241,14 +15434,14 @@ function __asyncValues2(o) {
|
|
|
15241
15434
|
}, i);
|
|
15242
15435
|
function verb(n) {
|
|
15243
15436
|
i[n] = o[n] && function(v) {
|
|
15244
|
-
return new Promise(function(
|
|
15245
|
-
v = o[n](v), settle(
|
|
15437
|
+
return new Promise(function(resolve10, reject) {
|
|
15438
|
+
v = o[n](v), settle(resolve10, reject, v.done, v.value);
|
|
15246
15439
|
});
|
|
15247
15440
|
};
|
|
15248
15441
|
}
|
|
15249
|
-
function settle(
|
|
15442
|
+
function settle(resolve10, reject, d, v) {
|
|
15250
15443
|
Promise.resolve(v).then(function(v2) {
|
|
15251
|
-
|
|
15444
|
+
resolve10({ value: v2, done: d });
|
|
15252
15445
|
}, reject);
|
|
15253
15446
|
}
|
|
15254
15447
|
}
|
|
@@ -15433,13 +15626,13 @@ var require_lazy_helpers = __commonJS({
|
|
|
15433
15626
|
}
|
|
15434
15627
|
};
|
|
15435
15628
|
exports.DelayedConstructor = DelayedConstructor;
|
|
15436
|
-
function
|
|
15629
|
+
function delay(wrappedConstructor) {
|
|
15437
15630
|
if (typeof wrappedConstructor === "undefined") {
|
|
15438
15631
|
throw new Error("Attempt to `delay` undefined. Constructor must be wrapped in a callback");
|
|
15439
15632
|
}
|
|
15440
15633
|
return new DelayedConstructor(wrappedConstructor);
|
|
15441
15634
|
}
|
|
15442
|
-
exports.delay =
|
|
15635
|
+
exports.delay = delay;
|
|
15443
15636
|
}
|
|
15444
15637
|
});
|
|
15445
15638
|
var require_injection_token = __commonJS({
|
|
@@ -18445,11 +18638,11 @@ var require_x509_cjs = __commonJS({
|
|
|
18445
18638
|
const res = [];
|
|
18446
18639
|
let matches = null;
|
|
18447
18640
|
while (matches = pattern.exec(pem)) {
|
|
18448
|
-
const
|
|
18641
|
+
const base64 = matches[3].replace(rEolPattern, "");
|
|
18449
18642
|
const pemStruct = {
|
|
18450
18643
|
type: matches[1],
|
|
18451
18644
|
headers: [],
|
|
18452
|
-
rawData: pvtsutils.Convert.FromBase64(
|
|
18645
|
+
rawData: pvtsutils.Convert.FromBase64(base64)
|
|
18453
18646
|
};
|
|
18454
18647
|
const headersString = matches[2];
|
|
18455
18648
|
if (headersString) {
|
|
@@ -18534,9 +18727,9 @@ var require_x509_cjs = __commonJS({
|
|
|
18534
18727
|
}
|
|
18535
18728
|
res.push("");
|
|
18536
18729
|
}
|
|
18537
|
-
const
|
|
18538
|
-
for (let i = 0; i <
|
|
18539
|
-
res.push(
|
|
18730
|
+
const base64 = pvtsutils.Convert.ToBase64(pem.rawData);
|
|
18731
|
+
for (let i = 0; i < base64.length; i += 64) {
|
|
18732
|
+
res.push(base64.substring(i, i + 64));
|
|
18540
18733
|
}
|
|
18541
18734
|
res.push(`-----END ${upperCaseType}-----`);
|
|
18542
18735
|
return res.join("\n");
|
|
@@ -20915,7 +21108,7 @@ var RETRY_DELAY_BASE = 1e3;
|
|
|
20915
21108
|
var COMPLETE_TIMEOUT = 6e4;
|
|
20916
21109
|
var STREAM_TIMEOUT = 12e4;
|
|
20917
21110
|
function sleep(ms) {
|
|
20918
|
-
return new Promise((
|
|
21111
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
20919
21112
|
}
|
|
20920
21113
|
function calculateRetryDelay(attempt) {
|
|
20921
21114
|
return RETRY_DELAY_BASE * 2 ** attempt + Math.random() * 100;
|
|
@@ -20943,8 +21136,8 @@ async function fetchWithRetry(url, init, signal) {
|
|
|
20943
21136
|
const shouldRetry = response.status === 429 || response.status >= 500;
|
|
20944
21137
|
if (shouldRetry && attempt < MAX_RETRIES) {
|
|
20945
21138
|
const retryAfter = response.headers.get("Retry-After");
|
|
20946
|
-
const
|
|
20947
|
-
await sleep(Math.min(
|
|
21139
|
+
const delay = retryAfter ? parseInt(retryAfter, 10) * 1e3 : calculateRetryDelay(attempt);
|
|
21140
|
+
await sleep(Math.min(delay, 1e4));
|
|
20948
21141
|
continue;
|
|
20949
21142
|
}
|
|
20950
21143
|
const errorText = await response.text().catch(() => "");
|
|
@@ -20986,8 +21179,8 @@ async function fetchStreamWithRetry(url, init, signal) {
|
|
|
20986
21179
|
const shouldRetry = response.status === 429 || response.status >= 500;
|
|
20987
21180
|
if (shouldRetry && attempt < MAX_RETRIES) {
|
|
20988
21181
|
const retryAfter = response.headers.get("Retry-After");
|
|
20989
|
-
const
|
|
20990
|
-
await sleep(Math.min(
|
|
21182
|
+
const delay = retryAfter ? parseInt(retryAfter, 10) * 1e3 : calculateRetryDelay(attempt);
|
|
21183
|
+
await sleep(Math.min(delay, 1e4));
|
|
20991
21184
|
continue;
|
|
20992
21185
|
}
|
|
20993
21186
|
const errorText = await response.text().catch(() => "");
|
|
@@ -21939,12 +22132,299 @@ var RUNTIME_LIMITS = Object.freeze({
|
|
|
21939
22132
|
maxRegexDeadlineMs: 250,
|
|
21940
22133
|
maxLocalOrigins: 32
|
|
21941
22134
|
});
|
|
22135
|
+
var F_GETPATH = 50;
|
|
22136
|
+
var MAXPATHLEN = 1024;
|
|
22137
|
+
var O_CLOEXEC = 16777216;
|
|
22138
|
+
var LIB_SYSTEM = "/usr/lib/libSystem.B.dylib";
|
|
22139
|
+
var binding;
|
|
22140
|
+
function loadKoffi() {
|
|
22141
|
+
const require2 = createRequire(import.meta.url);
|
|
22142
|
+
const loaded = require2("koffi");
|
|
22143
|
+
if (typeof loaded.load === "function") {
|
|
22144
|
+
return loaded;
|
|
22145
|
+
}
|
|
22146
|
+
return loaded.default;
|
|
22147
|
+
}
|
|
22148
|
+
function decodePath(value) {
|
|
22149
|
+
if (typeof value !== "string" || value.length === 0 || value.length >= MAXPATHLEN) {
|
|
22150
|
+
return null;
|
|
22151
|
+
}
|
|
22152
|
+
const end = value.indexOf("\0");
|
|
22153
|
+
const path2 = end === -1 ? value : value.slice(0, end);
|
|
22154
|
+
return path2.length > 0 ? path2 : null;
|
|
22155
|
+
}
|
|
22156
|
+
function loadDarwinConfined() {
|
|
22157
|
+
if (binding) return binding;
|
|
22158
|
+
const koffi = loadKoffi();
|
|
22159
|
+
const lib = koffi.load(LIB_SYSTEM);
|
|
22160
|
+
const openat = lib.func(
|
|
22161
|
+
"int openat(int dirfd, const char *pathname, int flags, ...)"
|
|
22162
|
+
);
|
|
22163
|
+
const fcntl = lib.func("int fcntl(int fd, int cmd, ...)");
|
|
22164
|
+
binding = {
|
|
22165
|
+
openat(dirfd, path2, flags) {
|
|
22166
|
+
const fd = openat(dirfd, path2, flags | O_CLOEXEC);
|
|
22167
|
+
if (typeof fd !== "number" || fd < 0) {
|
|
22168
|
+
throw new Error("openat failed");
|
|
22169
|
+
}
|
|
22170
|
+
return fd;
|
|
22171
|
+
},
|
|
22172
|
+
pathOf(fd) {
|
|
22173
|
+
try {
|
|
22174
|
+
const out = ["\0".repeat(MAXPATHLEN)];
|
|
22175
|
+
const result = fcntl(fd, F_GETPATH, "_Out_ char *", out);
|
|
22176
|
+
if (typeof result !== "number" || result < 0) return null;
|
|
22177
|
+
return decodePath(out[0]);
|
|
22178
|
+
} catch {
|
|
22179
|
+
return null;
|
|
22180
|
+
}
|
|
22181
|
+
}
|
|
22182
|
+
};
|
|
22183
|
+
return binding;
|
|
22184
|
+
}
|
|
22185
|
+
function darwinConfinedAvailable() {
|
|
22186
|
+
if (process.platform !== "darwin") return false;
|
|
22187
|
+
try {
|
|
22188
|
+
loadDarwinConfined();
|
|
22189
|
+
return true;
|
|
22190
|
+
} catch {
|
|
22191
|
+
return false;
|
|
22192
|
+
}
|
|
22193
|
+
}
|
|
22194
|
+
function isSingleComponent(component) {
|
|
22195
|
+
return component.length > 0 && component !== "." && component !== ".." && !component.includes("/") && !component.includes("\\") && !component.includes("\0");
|
|
22196
|
+
}
|
|
22197
|
+
function handleFromFd(fd) {
|
|
22198
|
+
let closed = false;
|
|
22199
|
+
return {
|
|
22200
|
+
fd,
|
|
22201
|
+
read(buffer, offset, length, position) {
|
|
22202
|
+
return new Promise((resolve10, reject) => {
|
|
22203
|
+
read(fd, buffer, offset, length, position, (error, bytesRead) => {
|
|
22204
|
+
if (error) reject(error);
|
|
22205
|
+
else resolve10({ bytesRead });
|
|
22206
|
+
});
|
|
22207
|
+
});
|
|
22208
|
+
},
|
|
22209
|
+
stat() {
|
|
22210
|
+
return new Promise((resolve10, reject) => {
|
|
22211
|
+
fstat(fd, (error, stats) => {
|
|
22212
|
+
if (error) reject(error);
|
|
22213
|
+
else resolve10(stats);
|
|
22214
|
+
});
|
|
22215
|
+
});
|
|
22216
|
+
},
|
|
22217
|
+
async close() {
|
|
22218
|
+
if (closed) return;
|
|
22219
|
+
closed = true;
|
|
22220
|
+
await new Promise((resolve10, reject) => {
|
|
22221
|
+
close(fd, (error) => {
|
|
22222
|
+
if (error) reject(error);
|
|
22223
|
+
else resolve10();
|
|
22224
|
+
});
|
|
22225
|
+
});
|
|
22226
|
+
}
|
|
22227
|
+
};
|
|
22228
|
+
}
|
|
22229
|
+
async function openDarwinRelative(dirFd, component, flags) {
|
|
22230
|
+
if (!isSingleComponent(component)) throw new Error("openat rejected");
|
|
22231
|
+
const fd = loadDarwinConfined().openat(dirFd, component, flags);
|
|
22232
|
+
return handleFromFd(fd);
|
|
22233
|
+
}
|
|
22234
|
+
async function darwinPathOf(fd) {
|
|
22235
|
+
return loadDarwinConfined().pathOf(fd);
|
|
22236
|
+
}
|
|
22237
|
+
function isConfinedFileSupported() {
|
|
22238
|
+
if (process.platform === "linux") {
|
|
22239
|
+
return typeof constants.O_NOFOLLOW === "number" && typeof constants.O_DIRECTORY === "number" && typeof constants.O_NONBLOCK === "number" && existsSync("/proc/self/fd");
|
|
22240
|
+
}
|
|
22241
|
+
return darwinConfinedAvailable();
|
|
22242
|
+
}
|
|
22243
|
+
function fdRelativePath(dirFd, component) {
|
|
22244
|
+
return `/proc/self/fd/${dirFd}/${component}`;
|
|
22245
|
+
}
|
|
22246
|
+
function withinRoot(root, candidate) {
|
|
22247
|
+
const rest = relative(root, candidate);
|
|
22248
|
+
return rest.length > 0 && rest !== ".." && !rest.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) && !isAbsolute(rest);
|
|
22249
|
+
}
|
|
22250
|
+
function fromNodeHandle(file) {
|
|
22251
|
+
return {
|
|
22252
|
+
fd: file.fd,
|
|
22253
|
+
read: (buffer, offset, length, position) => file.read(buffer, offset, length, position),
|
|
22254
|
+
stat: () => file.stat(),
|
|
22255
|
+
close: () => file.close()
|
|
22256
|
+
};
|
|
22257
|
+
}
|
|
22258
|
+
var linuxOps = {
|
|
22259
|
+
async openRelative(dirFd, component, flags) {
|
|
22260
|
+
return fromNodeHandle(await open(fdRelativePath(dirFd, component), flags));
|
|
22261
|
+
},
|
|
22262
|
+
async pathOf(fd) {
|
|
22263
|
+
try {
|
|
22264
|
+
return await readlink(`/proc/self/fd/${fd}`);
|
|
22265
|
+
} catch {
|
|
22266
|
+
return null;
|
|
22267
|
+
}
|
|
22268
|
+
}
|
|
22269
|
+
};
|
|
22270
|
+
function platformOps() {
|
|
22271
|
+
if (process.platform === "linux" && isConfinedFileSupported())
|
|
22272
|
+
return linuxOps;
|
|
22273
|
+
if (process.platform === "darwin" && darwinConfinedAvailable()) {
|
|
22274
|
+
return { openRelative: openDarwinRelative, pathOf: darwinPathOf };
|
|
22275
|
+
}
|
|
22276
|
+
return void 0;
|
|
22277
|
+
}
|
|
22278
|
+
async function closeQuietly(file) {
|
|
22279
|
+
try {
|
|
22280
|
+
await file.close();
|
|
22281
|
+
} catch {
|
|
22282
|
+
}
|
|
22283
|
+
}
|
|
22284
|
+
async function proveDescriptorWithinRoot(file, canonicalRoot, pathOf) {
|
|
22285
|
+
const resolved = await pathOf(file.fd);
|
|
22286
|
+
if (resolved === null || !withinRoot(canonicalRoot, resolved)) {
|
|
22287
|
+
return failure("runtime.file-race-rejected");
|
|
22288
|
+
}
|
|
22289
|
+
return { ok: true, value: void 0 };
|
|
22290
|
+
}
|
|
22291
|
+
function openFlags(directory) {
|
|
22292
|
+
if (directory) {
|
|
22293
|
+
return constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW;
|
|
22294
|
+
}
|
|
22295
|
+
return constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK;
|
|
22296
|
+
}
|
|
22297
|
+
async function openConfinedUsing(root, logicalPath, ops) {
|
|
22298
|
+
const normalized = normalizeLogicalPath(logicalPath);
|
|
22299
|
+
if (normalized === null) return failure("runtime.file-denied");
|
|
22300
|
+
const components = normalized.split("/");
|
|
22301
|
+
let parent;
|
|
22302
|
+
try {
|
|
22303
|
+
const canonicalRoot = await realpath(root);
|
|
22304
|
+
parent = fromNodeHandle(
|
|
22305
|
+
await open(canonicalRoot, constants.O_RDONLY | constants.O_DIRECTORY)
|
|
22306
|
+
);
|
|
22307
|
+
for (let index = 0; index < components.length - 1; index += 1) {
|
|
22308
|
+
const component = components[index] ?? "";
|
|
22309
|
+
const next = await ops.openRelative(
|
|
22310
|
+
parent.fd,
|
|
22311
|
+
component,
|
|
22312
|
+
openFlags(true)
|
|
22313
|
+
);
|
|
22314
|
+
await closeQuietly(parent);
|
|
22315
|
+
parent = next;
|
|
22316
|
+
}
|
|
22317
|
+
const leaf = components[components.length - 1] ?? "";
|
|
22318
|
+
const file = await ops.openRelative(parent.fd, leaf, openFlags(false));
|
|
22319
|
+
await closeQuietly(parent);
|
|
22320
|
+
parent = void 0;
|
|
22321
|
+
try {
|
|
22322
|
+
const containment = await proveDescriptorWithinRoot(
|
|
22323
|
+
file,
|
|
22324
|
+
canonicalRoot,
|
|
22325
|
+
ops.pathOf
|
|
22326
|
+
);
|
|
22327
|
+
if (!containment.ok) {
|
|
22328
|
+
await closeQuietly(file);
|
|
22329
|
+
return containment;
|
|
22330
|
+
}
|
|
22331
|
+
const stat22 = await file.stat();
|
|
22332
|
+
if (!stat22.isFile()) {
|
|
22333
|
+
await closeQuietly(file);
|
|
22334
|
+
return failure("runtime.file-denied");
|
|
22335
|
+
}
|
|
22336
|
+
if (stat22.nlink !== 1) {
|
|
22337
|
+
await closeQuietly(file);
|
|
22338
|
+
return failure("runtime.file-race-rejected");
|
|
22339
|
+
}
|
|
22340
|
+
if (stat22.size > RUNTIME_LIMITS.maxFileBytes) {
|
|
22341
|
+
await closeQuietly(file);
|
|
22342
|
+
return failure("runtime.size-limit");
|
|
22343
|
+
}
|
|
22344
|
+
return { ok: true, value: file };
|
|
22345
|
+
} catch {
|
|
22346
|
+
await closeQuietly(file);
|
|
22347
|
+
return failure("runtime.file-denied");
|
|
22348
|
+
}
|
|
22349
|
+
} catch {
|
|
22350
|
+
return failure("runtime.file-denied");
|
|
22351
|
+
} finally {
|
|
22352
|
+
if (parent !== void 0) await closeQuietly(parent);
|
|
22353
|
+
}
|
|
22354
|
+
}
|
|
22355
|
+
async function openConfinedFile(root, logicalPath) {
|
|
22356
|
+
if (normalizeLogicalPath(logicalPath) === null) {
|
|
22357
|
+
return failure("runtime.file-denied");
|
|
22358
|
+
}
|
|
22359
|
+
const ops = platformOps();
|
|
22360
|
+
if (ops === void 0) return failure("runtime.platform-unsupported");
|
|
22361
|
+
return openConfinedUsing(root, logicalPath, ops);
|
|
22362
|
+
}
|
|
22363
|
+
async function closeQuietly2(file) {
|
|
22364
|
+
try {
|
|
22365
|
+
await file.close();
|
|
22366
|
+
} catch {
|
|
22367
|
+
}
|
|
22368
|
+
}
|
|
22369
|
+
async function readOpenedConfinedFile(file, signal) {
|
|
22370
|
+
try {
|
|
22371
|
+
const chunks = [];
|
|
22372
|
+
let total = 0;
|
|
22373
|
+
let position = 0;
|
|
22374
|
+
while (true) {
|
|
22375
|
+
if (signal?.aborted) return failure("runtime.timeout");
|
|
22376
|
+
const buffer = Buffer.allocUnsafe(
|
|
22377
|
+
Math.min(64 * 1024, RUNTIME_LIMITS.maxFileBytes - total + 1)
|
|
22378
|
+
);
|
|
22379
|
+
const read2 = await file.read(buffer, 0, buffer.byteLength, position);
|
|
22380
|
+
if (read2.bytesRead === 0) break;
|
|
22381
|
+
total += read2.bytesRead;
|
|
22382
|
+
if (total > RUNTIME_LIMITS.maxFileBytes)
|
|
22383
|
+
return failure("runtime.size-limit");
|
|
22384
|
+
chunks.push(Uint8Array.from(buffer.subarray(0, read2.bytesRead)));
|
|
22385
|
+
position += read2.bytesRead;
|
|
22386
|
+
}
|
|
22387
|
+
const finalStat = await file.stat();
|
|
22388
|
+
if (!finalStat.isFile() || finalStat.nlink !== 1 || finalStat.size > RUNTIME_LIMITS.maxFileBytes || finalStat.size !== total) {
|
|
22389
|
+
return failure(
|
|
22390
|
+
finalStat.size > RUNTIME_LIMITS.maxFileBytes ? "runtime.size-limit" : "runtime.file-race-rejected"
|
|
22391
|
+
);
|
|
22392
|
+
}
|
|
22393
|
+
const output = new Uint8Array(total);
|
|
22394
|
+
let offset = 0;
|
|
22395
|
+
for (const chunk of chunks) {
|
|
22396
|
+
output.set(chunk, offset);
|
|
22397
|
+
offset += chunk.byteLength;
|
|
22398
|
+
}
|
|
22399
|
+
return { ok: true, value: output };
|
|
22400
|
+
} catch {
|
|
22401
|
+
return signal?.aborted ? failure("runtime.timeout") : failure("runtime.file-denied");
|
|
22402
|
+
}
|
|
22403
|
+
}
|
|
22404
|
+
async function readConfinedPathBytes(root, logicalPath, signal) {
|
|
22405
|
+
const normalized = normalizeLogicalPath(logicalPath);
|
|
22406
|
+
if (normalized === null) return failure("runtime.file-denied");
|
|
22407
|
+
if (!isConfinedFileSupported())
|
|
22408
|
+
return failure("runtime.platform-unsupported");
|
|
22409
|
+
if (signal?.aborted) return failure("runtime.timeout");
|
|
22410
|
+
const opened = await openConfinedFile(root, normalized);
|
|
22411
|
+
if (!opened.ok) return opened;
|
|
22412
|
+
const file = opened.value;
|
|
22413
|
+
try {
|
|
22414
|
+
return await readOpenedConfinedFile(file, signal);
|
|
22415
|
+
} finally {
|
|
22416
|
+
await closeQuietly2(file);
|
|
22417
|
+
}
|
|
22418
|
+
}
|
|
21942
22419
|
var PROTOCOL = "v1";
|
|
21943
22420
|
var ENVELOPE_MAX_BYTES = 64 * 1024;
|
|
21944
22421
|
var MAX_PAC_ROUTES = 256;
|
|
21945
|
-
var FORBIDDEN_BODY_KEYS = /* @__PURE__ */ new Set([
|
|
21946
|
-
|
|
21947
|
-
|
|
22422
|
+
var FORBIDDEN_BODY_KEYS = /* @__PURE__ */ new Set([
|
|
22423
|
+
"body",
|
|
22424
|
+
"requestBody",
|
|
22425
|
+
"responseBody",
|
|
22426
|
+
"mockBody"
|
|
22427
|
+
]);
|
|
21948
22428
|
var BODY_CHECK_EXEMPT_TYPES = /* @__PURE__ */ new Set(["runtime.project.set"]);
|
|
21949
22429
|
var ENVELOPE_MESSAGE_TYPES = /* @__PURE__ */ new Set([
|
|
21950
22430
|
"runtime.start",
|
|
@@ -21962,12 +22442,13 @@ var ENVELOPE_MESSAGE_TYPES = /* @__PURE__ */ new Set([
|
|
|
21962
22442
|
"authorize.request",
|
|
21963
22443
|
"authorize.response",
|
|
21964
22444
|
"mock.connect",
|
|
21965
|
-
"mock.request",
|
|
21966
|
-
"mock.response",
|
|
21967
22445
|
"ai.complete",
|
|
21968
22446
|
"ai.stream.chunk",
|
|
21969
22447
|
"ai.error",
|
|
21970
|
-
"ai.status"
|
|
22448
|
+
"ai.status",
|
|
22449
|
+
"runtime.pick-directory",
|
|
22450
|
+
"runtime.check-directory",
|
|
22451
|
+
"runtime.set-file-root"
|
|
21971
22452
|
]);
|
|
21972
22453
|
var EnvelopeError = class extends Error {
|
|
21973
22454
|
constructor(message) {
|
|
@@ -21996,11 +22477,6 @@ function assertNoBodyContent(type, metadata) {
|
|
|
21996
22477
|
"envelope must not carry request or response body content"
|
|
21997
22478
|
);
|
|
21998
22479
|
}
|
|
21999
|
-
if (MOCK_BODY_KEY in metadata && !MOCK_BODY_ALLOWED_TYPES.has(type)) {
|
|
22000
|
-
throw new EnvelopeError(
|
|
22001
|
-
"mockBody is only permitted on the mock.response envelope"
|
|
22002
|
-
);
|
|
22003
|
-
}
|
|
22004
22480
|
}
|
|
22005
22481
|
function utf8ByteLength(value) {
|
|
22006
22482
|
return Buffer.byteLength(value, "utf8");
|
|
@@ -22080,6 +22556,45 @@ function describeExtensionIdMismatch(expectedExtensionId, allowedOrigins) {
|
|
|
22080
22556
|
`Run: ${command}`
|
|
22081
22557
|
].join("\n");
|
|
22082
22558
|
}
|
|
22559
|
+
async function resolveConfinedRoot(value) {
|
|
22560
|
+
if (typeof value !== "string" || value.length === 0 || !isAbsolute2(value)) {
|
|
22561
|
+
return failure("runtime.root-invalid");
|
|
22562
|
+
}
|
|
22563
|
+
let directory;
|
|
22564
|
+
try {
|
|
22565
|
+
directory = await open2(value, constants2.O_RDONLY | constants2.O_DIRECTORY);
|
|
22566
|
+
const info = await directory.stat();
|
|
22567
|
+
if (!info.isDirectory()) return failure("runtime.root-invalid");
|
|
22568
|
+
return { ok: true, value: await realpath2(value) };
|
|
22569
|
+
} catch {
|
|
22570
|
+
return failure("runtime.root-invalid");
|
|
22571
|
+
} finally {
|
|
22572
|
+
await directory?.close().catch(() => void 0);
|
|
22573
|
+
}
|
|
22574
|
+
}
|
|
22575
|
+
var MOCK_LISTENER_PREFIX = "/.rogatio/mock/";
|
|
22576
|
+
function isSingleSegment(value) {
|
|
22577
|
+
return value.length > 0 && value.length <= 2048 && value !== "." && value !== ".." && !value.includes("/") && !value.includes("\\") && !value.includes("?") && !hasControl(value);
|
|
22578
|
+
}
|
|
22579
|
+
function parseMockRedirect(rawUrl) {
|
|
22580
|
+
const queryAt = rawUrl.indexOf("?");
|
|
22581
|
+
const path2 = queryAt === -1 ? rawUrl : rawUrl.slice(0, queryAt);
|
|
22582
|
+
if (!path2.startsWith(MOCK_LISTENER_PREFIX)) return null;
|
|
22583
|
+
const rest = path2.slice(MOCK_LISTENER_PREFIX.length);
|
|
22584
|
+
const slash = rest.indexOf("/");
|
|
22585
|
+
if (slash <= 0) return null;
|
|
22586
|
+
if (rest.indexOf("/", slash + 1) !== -1) return null;
|
|
22587
|
+
let token;
|
|
22588
|
+
let digest;
|
|
22589
|
+
try {
|
|
22590
|
+
token = decodeURIComponent(rest.slice(0, slash));
|
|
22591
|
+
digest = decodeURIComponent(rest.slice(slash + 1));
|
|
22592
|
+
} catch {
|
|
22593
|
+
return null;
|
|
22594
|
+
}
|
|
22595
|
+
if (!isSingleSegment(token) || !isSingleSegment(digest)) return null;
|
|
22596
|
+
return { token, digest };
|
|
22597
|
+
}
|
|
22083
22598
|
function supportedContentType(value) {
|
|
22084
22599
|
if (value === void 0) return false;
|
|
22085
22600
|
const mediaType = value.split(";", 1)[0]?.trim().toLowerCase() ?? "";
|
|
@@ -22124,7 +22639,7 @@ function discardRegexWorker(worker) {
|
|
|
22124
22639
|
function bootRegexWorker() {
|
|
22125
22640
|
if (regexWorker !== null) return Promise.resolve(regexWorker);
|
|
22126
22641
|
if (regexWorkerBoot !== null) return regexWorkerBoot;
|
|
22127
|
-
const boot = new Promise((
|
|
22642
|
+
const boot = new Promise((resolve10, reject) => {
|
|
22128
22643
|
const start = () => {
|
|
22129
22644
|
let worker;
|
|
22130
22645
|
try {
|
|
@@ -22158,7 +22673,7 @@ function bootRegexWorker() {
|
|
|
22158
22673
|
}
|
|
22159
22674
|
});
|
|
22160
22675
|
regexWorker = worker;
|
|
22161
|
-
|
|
22676
|
+
resolve10(worker);
|
|
22162
22677
|
});
|
|
22163
22678
|
worker.once("error", (error) => {
|
|
22164
22679
|
if (settled) return;
|
|
@@ -22176,9 +22691,9 @@ function bootRegexWorker() {
|
|
|
22176
22691
|
});
|
|
22177
22692
|
};
|
|
22178
22693
|
if (regexWorkerBootDelayForTestsMs > 0) {
|
|
22179
|
-
const
|
|
22694
|
+
const delay = regexWorkerBootDelayForTestsMs;
|
|
22180
22695
|
regexWorkerBootDelayForTestsMs = 0;
|
|
22181
|
-
setTimeout(start,
|
|
22696
|
+
setTimeout(start, delay).unref();
|
|
22182
22697
|
} else {
|
|
22183
22698
|
start();
|
|
22184
22699
|
}
|
|
@@ -22190,7 +22705,7 @@ function bootRegexWorker() {
|
|
|
22190
22705
|
return boot;
|
|
22191
22706
|
}
|
|
22192
22707
|
function runOnRegexWorker(worker, id2, text, pattern, replacement, deadlineMs) {
|
|
22193
|
-
return new Promise((
|
|
22708
|
+
return new Promise((resolve10, reject) => {
|
|
22194
22709
|
let timer = null;
|
|
22195
22710
|
const cleanup = () => {
|
|
22196
22711
|
if (timer !== null) clearTimeout(timer);
|
|
@@ -22210,7 +22725,7 @@ function runOnRegexWorker(worker, id2, text, pattern, replacement, deadlineMs) {
|
|
|
22210
22725
|
}
|
|
22211
22726
|
if (msg.type === "result") {
|
|
22212
22727
|
cleanup();
|
|
22213
|
-
if (msg.ok && typeof msg.out === "string")
|
|
22728
|
+
if (msg.ok && typeof msg.out === "string") resolve10(msg.out);
|
|
22214
22729
|
else reject(new Error(msg.error || "regex-invalid"));
|
|
22215
22730
|
}
|
|
22216
22731
|
};
|
|
@@ -22336,7 +22851,7 @@ function responseHeaders(response) {
|
|
|
22336
22851
|
}
|
|
22337
22852
|
var defaultTransport = {
|
|
22338
22853
|
request(options) {
|
|
22339
|
-
return new Promise((
|
|
22854
|
+
return new Promise((resolve10, reject) => {
|
|
22340
22855
|
const lookup = (_hostname, _options, callback) => {
|
|
22341
22856
|
callback(null, options.address, options.address.includes(":") ? 6 : 4);
|
|
22342
22857
|
};
|
|
@@ -22355,14 +22870,14 @@ var defaultTransport = {
|
|
|
22355
22870
|
const request = options.protocol === "https:" ? httpsRequest(
|
|
22356
22871
|
{ ...requestOptions, servername: options.servername },
|
|
22357
22872
|
(response) => {
|
|
22358
|
-
|
|
22873
|
+
resolve10({
|
|
22359
22874
|
status: response.statusCode ?? 0,
|
|
22360
22875
|
headers: responseHeaders(response),
|
|
22361
22876
|
body: response
|
|
22362
22877
|
});
|
|
22363
22878
|
}
|
|
22364
22879
|
) : httpRequest(requestOptions, (response) => {
|
|
22365
|
-
|
|
22880
|
+
resolve10({
|
|
22366
22881
|
status: response.statusCode ?? 0,
|
|
22367
22882
|
headers: responseHeaders(response),
|
|
22368
22883
|
body: response
|
|
@@ -22374,7 +22889,7 @@ var defaultTransport = {
|
|
|
22374
22889
|
}
|
|
22375
22890
|
};
|
|
22376
22891
|
function headerValue(headers, name) {
|
|
22377
|
-
return headers.find(([
|
|
22892
|
+
return headers.find(([headerName2]) => headerName2.toLowerCase() === name)?.[1];
|
|
22378
22893
|
}
|
|
22379
22894
|
function responseHeaderBytes(headers) {
|
|
22380
22895
|
let bytes = 0;
|
|
@@ -22714,14 +23229,14 @@ function headerValue2(headers, name) {
|
|
|
22714
23229
|
return raw;
|
|
22715
23230
|
}
|
|
22716
23231
|
function readBoundedBody(req, maxBytes) {
|
|
22717
|
-
return new Promise((
|
|
23232
|
+
return new Promise((resolve10) => {
|
|
22718
23233
|
const chunks = [];
|
|
22719
23234
|
let total = 0;
|
|
22720
23235
|
let settled = false;
|
|
22721
23236
|
const finish2 = (result) => {
|
|
22722
23237
|
if (settled) return;
|
|
22723
23238
|
settled = true;
|
|
22724
|
-
|
|
23239
|
+
resolve10(result);
|
|
22725
23240
|
};
|
|
22726
23241
|
req.on("data", (chunk) => {
|
|
22727
23242
|
total += chunk.byteLength;
|
|
@@ -22785,7 +23300,7 @@ function pipeSockets(a, b) {
|
|
|
22785
23300
|
async function upstreamHttp(method, target, headers, body) {
|
|
22786
23301
|
const port = target.port ? Number(target.port) : 80;
|
|
22787
23302
|
const path2 = `${target.pathname}${target.search}`;
|
|
22788
|
-
return new Promise((
|
|
23303
|
+
return new Promise((resolve10, reject) => {
|
|
22789
23304
|
const socket = connect(port, target.hostname);
|
|
22790
23305
|
let buf = Buffer.alloc(0);
|
|
22791
23306
|
let settled = false;
|
|
@@ -22809,9 +23324,9 @@ ${lines}\r
|
|
|
22809
23324
|
socket.on("data", (chunk) => {
|
|
22810
23325
|
const piece = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
22811
23326
|
buf = Buffer.concat([buf, piece]);
|
|
22812
|
-
const
|
|
22813
|
-
if (
|
|
22814
|
-
const head = buf.subarray(0,
|
|
23327
|
+
const sep = buf.indexOf("\r\n\r\n");
|
|
23328
|
+
if (sep < 0) return;
|
|
23329
|
+
const head = buf.subarray(0, sep).toString("latin1");
|
|
22815
23330
|
const statusMatch = /^HTTP\/1\.[01] (\d+)(?: (.*))?/.exec(
|
|
22816
23331
|
head.split("\r\n")[0] ?? ""
|
|
22817
23332
|
);
|
|
@@ -22835,13 +23350,13 @@ ${lines}\r
|
|
|
22835
23350
|
const clRaw = headerMap["content-length"];
|
|
22836
23351
|
const hasContentLength = clRaw !== void 0;
|
|
22837
23352
|
const cl = typeof clRaw === "string" ? Number(clRaw) : Array.isArray(clRaw) ? Number(clRaw[0]) : Number.NaN;
|
|
22838
|
-
const bodyStart =
|
|
23353
|
+
const bodyStart = sep + 4;
|
|
22839
23354
|
if (hasContentLength && Number.isFinite(cl) && cl >= 0) {
|
|
22840
23355
|
if (buf.length - bodyStart < cl) return;
|
|
22841
23356
|
if (settled) return;
|
|
22842
23357
|
settled = true;
|
|
22843
23358
|
socket.destroy();
|
|
22844
|
-
|
|
23359
|
+
resolve10({
|
|
22845
23360
|
status,
|
|
22846
23361
|
statusMessage,
|
|
22847
23362
|
headers: headerMap,
|
|
@@ -22852,12 +23367,12 @@ ${lines}\r
|
|
|
22852
23367
|
});
|
|
22853
23368
|
socket.on("end", () => {
|
|
22854
23369
|
if (settled) return;
|
|
22855
|
-
const
|
|
22856
|
-
if (
|
|
23370
|
+
const sep = buf.indexOf("\r\n\r\n");
|
|
23371
|
+
if (sep < 0) {
|
|
22857
23372
|
fail(new Error("upstream closed early"));
|
|
22858
23373
|
return;
|
|
22859
23374
|
}
|
|
22860
|
-
const head = buf.subarray(0,
|
|
23375
|
+
const head = buf.subarray(0, sep).toString("latin1");
|
|
22861
23376
|
const statusMatch = /^HTTP\/1\.[01] (\d+)(?: (.*))?/.exec(
|
|
22862
23377
|
head.split("\r\n")[0] ?? ""
|
|
22863
23378
|
);
|
|
@@ -22871,7 +23386,7 @@ ${lines}\r
|
|
|
22871
23386
|
if (i <= 0) continue;
|
|
22872
23387
|
headerMap[line.slice(0, i).trim().toLowerCase()] = line.slice(i + 1).trim();
|
|
22873
23388
|
}
|
|
22874
|
-
let body2 = Buffer.from(buf.subarray(
|
|
23389
|
+
let body2 = Buffer.from(buf.subarray(sep + 4));
|
|
22875
23390
|
const te = headerMap["transfer-encoding"];
|
|
22876
23391
|
const teValue = Array.isArray(te) ? te[0] : te;
|
|
22877
23392
|
if (typeof teValue === "string" && teValue.toLowerCase().includes("chunked")) {
|
|
@@ -22880,7 +23395,7 @@ ${lines}\r
|
|
|
22880
23395
|
headerMap["content-length"] = String(body2.byteLength);
|
|
22881
23396
|
}
|
|
22882
23397
|
settled = true;
|
|
22883
|
-
|
|
23398
|
+
resolve10({
|
|
22884
23399
|
status: Number(statusMatch[1]),
|
|
22885
23400
|
statusMessage: statusMatch[2]?.trim() ?? "",
|
|
22886
23401
|
headers: headerMap,
|
|
@@ -22955,6 +23470,10 @@ function authorizeOp(policy, op, url, method, headers) {
|
|
|
22955
23470
|
}
|
|
22956
23471
|
async function startInterceptProxy(options = {}) {
|
|
22957
23472
|
let policy = options.policy ?? null;
|
|
23473
|
+
const serveMock = options.serveMock;
|
|
23474
|
+
let activeMocks = 0;
|
|
23475
|
+
const mockAborts = /* @__PURE__ */ new Set();
|
|
23476
|
+
let stopped = false;
|
|
22958
23477
|
const server = createServer((req, res) => {
|
|
22959
23478
|
void handleHttp(req, res);
|
|
22960
23479
|
});
|
|
@@ -22968,6 +23487,10 @@ async function startInterceptProxy(options = {}) {
|
|
|
22968
23487
|
await handleResponseBodyRedirect(req, res, targetUrl);
|
|
22969
23488
|
return;
|
|
22970
23489
|
}
|
|
23490
|
+
if (targetUrl.startsWith(MOCK_LISTENER_PREFIX.slice(0, -1))) {
|
|
23491
|
+
await handleMockRedirect(req, res, targetUrl);
|
|
23492
|
+
return;
|
|
23493
|
+
}
|
|
22971
23494
|
if (!/^https?:\/\//i.test(targetUrl)) {
|
|
22972
23495
|
res.writeHead(400);
|
|
22973
23496
|
res.end();
|
|
@@ -23083,6 +23606,71 @@ async function startInterceptProxy(options = {}) {
|
|
|
23083
23606
|
}
|
|
23084
23607
|
}
|
|
23085
23608
|
}
|
|
23609
|
+
function endEmpty(res, status) {
|
|
23610
|
+
if (res.writableEnded) return;
|
|
23611
|
+
res.writeHead(status, {
|
|
23612
|
+
"cache-control": "no-store",
|
|
23613
|
+
"content-length": "0"
|
|
23614
|
+
});
|
|
23615
|
+
res.end();
|
|
23616
|
+
}
|
|
23617
|
+
function discardRequestBody(req) {
|
|
23618
|
+
req.on("data", () => {
|
|
23619
|
+
});
|
|
23620
|
+
req.resume();
|
|
23621
|
+
}
|
|
23622
|
+
async function handleMockRedirect(req, res, rawUrl) {
|
|
23623
|
+
discardRequestBody(req);
|
|
23624
|
+
const parsed = parseMockRedirect(rawUrl);
|
|
23625
|
+
if (parsed === null) {
|
|
23626
|
+
endEmpty(res, 400);
|
|
23627
|
+
return;
|
|
23628
|
+
}
|
|
23629
|
+
const active = policy;
|
|
23630
|
+
if (serveMock === void 0 || active === null || active.presetDigest === void 0 || active.presetDigest.length === 0) {
|
|
23631
|
+
endEmpty(res, 403);
|
|
23632
|
+
return;
|
|
23633
|
+
}
|
|
23634
|
+
if (parsed.digest !== active.presetDigest) {
|
|
23635
|
+
endEmpty(res, 403);
|
|
23636
|
+
return;
|
|
23637
|
+
}
|
|
23638
|
+
if (activeMocks >= RUNTIME_LIMITS.maxConcurrentOperations) {
|
|
23639
|
+
endEmpty(res, 429);
|
|
23640
|
+
return;
|
|
23641
|
+
}
|
|
23642
|
+
activeMocks += 1;
|
|
23643
|
+
const abort = new AbortController();
|
|
23644
|
+
mockAborts.add(abort);
|
|
23645
|
+
const cancel = () => {
|
|
23646
|
+
if (!res.writableFinished) abort.abort();
|
|
23647
|
+
};
|
|
23648
|
+
req.on("aborted", cancel);
|
|
23649
|
+
res.on("close", cancel);
|
|
23650
|
+
try {
|
|
23651
|
+
const rendered = await serveMock({
|
|
23652
|
+
token: parsed.token,
|
|
23653
|
+
method: (req.method ?? "GET").toUpperCase(),
|
|
23654
|
+
signal: abort.signal
|
|
23655
|
+
});
|
|
23656
|
+
if (abort.signal.aborted || res.writableEnded) return;
|
|
23657
|
+
if (!rendered.ok) {
|
|
23658
|
+
const status = rendered.error.code === "runtime.unsupported-method" ? 405 : rendered.error.code === "runtime.mock-unknown" ? 404 : 502;
|
|
23659
|
+
endEmpty(res, status);
|
|
23660
|
+
return;
|
|
23661
|
+
}
|
|
23662
|
+
res.writeHead(
|
|
23663
|
+
rendered.value.status,
|
|
23664
|
+
rendered.value.headers.map(([name, value]) => [name, value])
|
|
23665
|
+
);
|
|
23666
|
+
res.end(Buffer.from(rendered.value.bodyBytes));
|
|
23667
|
+
} catch {
|
|
23668
|
+
endEmpty(res, 502);
|
|
23669
|
+
} finally {
|
|
23670
|
+
mockAborts.delete(abort);
|
|
23671
|
+
activeMocks = Math.max(0, activeMocks - 1);
|
|
23672
|
+
}
|
|
23673
|
+
}
|
|
23086
23674
|
async function handleResponseBodyRedirect(req, res, rawUrl) {
|
|
23087
23675
|
const method = (req.method ?? "GET").toUpperCase();
|
|
23088
23676
|
if (method !== "GET") {
|
|
@@ -23194,7 +23782,7 @@ async function startInterceptProxy(options = {}) {
|
|
|
23194
23782
|
});
|
|
23195
23783
|
clientSocket.on("error", () => upstream.destroy());
|
|
23196
23784
|
}
|
|
23197
|
-
const endpoint = await new Promise((
|
|
23785
|
+
const endpoint = await new Promise((resolve10, reject) => {
|
|
23198
23786
|
server.once("error", reject);
|
|
23199
23787
|
server.listen(0, "127.0.0.1", () => {
|
|
23200
23788
|
const addr = server.address();
|
|
@@ -23202,7 +23790,7 @@ async function startInterceptProxy(options = {}) {
|
|
|
23202
23790
|
reject(new Error("intercept-proxy bind failed"));
|
|
23203
23791
|
return;
|
|
23204
23792
|
}
|
|
23205
|
-
|
|
23793
|
+
resolve10({ host: "127.0.0.1", port: addr.port });
|
|
23206
23794
|
});
|
|
23207
23795
|
});
|
|
23208
23796
|
return {
|
|
@@ -23211,8 +23799,12 @@ async function startInterceptProxy(options = {}) {
|
|
|
23211
23799
|
policy = next;
|
|
23212
23800
|
},
|
|
23213
23801
|
async stop() {
|
|
23214
|
-
|
|
23215
|
-
|
|
23802
|
+
if (stopped) return;
|
|
23803
|
+
stopped = true;
|
|
23804
|
+
for (const abort of mockAborts) abort.abort();
|
|
23805
|
+
server.closeAllConnections();
|
|
23806
|
+
await new Promise((resolve10, reject) => {
|
|
23807
|
+
server.close((err) => err ? reject(err) : resolve10());
|
|
23216
23808
|
});
|
|
23217
23809
|
}
|
|
23218
23810
|
};
|
|
@@ -23315,7 +23907,7 @@ async function startInterception(activation, policyDigest, extensionId, pacRoute
|
|
|
23315
23907
|
return { kind: "unsupported", reasons: ["no-interception-provider"] };
|
|
23316
23908
|
}
|
|
23317
23909
|
const capabilities = registeredProvider.detect();
|
|
23318
|
-
if (!capabilities.supported) {
|
|
23910
|
+
if (pacRoutes.length > 0 && !capabilities.supported) {
|
|
23319
23911
|
return { kind: "unsupported", reasons: capabilities.reasons };
|
|
23320
23912
|
}
|
|
23321
23913
|
if (currentSession !== null) {
|
|
@@ -23546,68 +24138,194 @@ function closeCapabilityState(state) {
|
|
|
23546
24138
|
state.sessions.length = 0;
|
|
23547
24139
|
state.bootstrapDigest.fill(0);
|
|
23548
24140
|
}
|
|
23549
|
-
|
|
23550
|
-
|
|
23551
|
-
|
|
23552
|
-
|
|
23553
|
-
|
|
23554
|
-
|
|
23555
|
-
|
|
23556
|
-
|
|
23557
|
-
|
|
23558
|
-
|
|
23559
|
-
|
|
23560
|
-
|
|
23561
|
-
|
|
23562
|
-
|
|
23563
|
-
|
|
23564
|
-
|
|
23565
|
-
|
|
23566
|
-
|
|
23567
|
-
|
|
23568
|
-
|
|
23569
|
-
|
|
23570
|
-
|
|
23571
|
-
|
|
23572
|
-
|
|
24141
|
+
var WINDOWS_FOLDER_SCRIPT = [
|
|
24142
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
24143
|
+
"$dialog = New-Object System.Windows.Forms.FolderBrowserDialog",
|
|
24144
|
+
"$dialog.Description = 'Mock files folder'",
|
|
24145
|
+
"if ($dialog.ShowDialog() -eq 'OK') { $dialog.SelectedPath }"
|
|
24146
|
+
].join("; ");
|
|
24147
|
+
function directoryDialogCommands(platform = process.platform) {
|
|
24148
|
+
if (platform === "darwin") {
|
|
24149
|
+
return [
|
|
24150
|
+
{
|
|
24151
|
+
command: "osascript",
|
|
24152
|
+
args: [
|
|
24153
|
+
"-e",
|
|
24154
|
+
'POSIX path of (choose folder with prompt "Choose the mock files folder")'
|
|
24155
|
+
]
|
|
24156
|
+
}
|
|
24157
|
+
];
|
|
24158
|
+
}
|
|
24159
|
+
if (platform === "win32") {
|
|
24160
|
+
return [
|
|
24161
|
+
{
|
|
24162
|
+
command: "powershell.exe",
|
|
24163
|
+
args: ["-NoProfile", "-STA", "-Command", WINDOWS_FOLDER_SCRIPT]
|
|
24164
|
+
}
|
|
24165
|
+
];
|
|
23573
24166
|
}
|
|
24167
|
+
if (platform === "linux") {
|
|
24168
|
+
return [
|
|
24169
|
+
{
|
|
24170
|
+
command: "zenity",
|
|
24171
|
+
args: ["--file-selection", "--directory", "--title=Mock files folder"]
|
|
24172
|
+
},
|
|
24173
|
+
{
|
|
24174
|
+
command: "kdialog",
|
|
24175
|
+
args: ["--getexistingdirectory", "--title", "Mock files folder"]
|
|
24176
|
+
}
|
|
24177
|
+
];
|
|
24178
|
+
}
|
|
24179
|
+
return [];
|
|
24180
|
+
}
|
|
24181
|
+
var MAX_PICK_STDOUT = 4096;
|
|
24182
|
+
function runDialog(command, args) {
|
|
24183
|
+
return new Promise((resolve10) => {
|
|
24184
|
+
let settled = false;
|
|
24185
|
+
const finish2 = (result) => {
|
|
24186
|
+
if (settled) return;
|
|
24187
|
+
settled = true;
|
|
24188
|
+
resolve10(result);
|
|
24189
|
+
};
|
|
24190
|
+
const options = {
|
|
24191
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
24192
|
+
windowsHide: false
|
|
24193
|
+
};
|
|
24194
|
+
const child = spawn(command, [...args], options);
|
|
24195
|
+
const chunks = [];
|
|
24196
|
+
let size = 0;
|
|
24197
|
+
child.stdout?.on("data", (chunk) => {
|
|
24198
|
+
size += chunk.length;
|
|
24199
|
+
if (size <= MAX_PICK_STDOUT) chunks.push(chunk);
|
|
24200
|
+
});
|
|
24201
|
+
child.on("error", (error) => {
|
|
24202
|
+
finish2({ code: null, stdout: "", errorCode: error.code });
|
|
24203
|
+
});
|
|
24204
|
+
child.on("close", (code) => {
|
|
24205
|
+
finish2({
|
|
24206
|
+
code,
|
|
24207
|
+
stdout: Buffer.concat(chunks).toString("utf8"),
|
|
24208
|
+
...size > MAX_PICK_STDOUT ? { errorCode: "too-large" } : {}
|
|
24209
|
+
});
|
|
24210
|
+
});
|
|
24211
|
+
});
|
|
24212
|
+
}
|
|
24213
|
+
async function pickDirectory(run = runDialog, platform = process.platform) {
|
|
24214
|
+
const commands = directoryDialogCommands(platform);
|
|
24215
|
+
if (commands.length === 0) {
|
|
24216
|
+
return { ok: false, code: "runtime.picker-unavailable" };
|
|
24217
|
+
}
|
|
24218
|
+
for (const dialog of commands) {
|
|
24219
|
+
const result = await run(dialog.command, dialog.args);
|
|
24220
|
+
if (result.errorCode === "ENOENT") continue;
|
|
24221
|
+
if (result.errorCode !== void 0) {
|
|
24222
|
+
return { ok: false, code: "runtime.picker-unavailable" };
|
|
24223
|
+
}
|
|
24224
|
+
if (result.code === 0) {
|
|
24225
|
+
const path2 = result.stdout.trim();
|
|
24226
|
+
return { ok: true, path: path2.length === 0 ? null : path2 };
|
|
24227
|
+
}
|
|
24228
|
+
if (result.code === 1) return { ok: true, path: null };
|
|
24229
|
+
return { ok: false, code: "runtime.picker-unavailable" };
|
|
24230
|
+
}
|
|
24231
|
+
return { ok: false, code: "runtime.picker-unavailable" };
|
|
24232
|
+
}
|
|
24233
|
+
async function readMockFile(root, logicalPath, signal) {
|
|
24234
|
+
return readConfinedPathBytes(root, logicalPath, signal);
|
|
23574
24235
|
}
|
|
23575
24236
|
function mintToken() {
|
|
23576
24237
|
return randomBytes2(32).toString("hex");
|
|
23577
24238
|
}
|
|
24239
|
+
function headerName(name) {
|
|
24240
|
+
return name.toLowerCase();
|
|
24241
|
+
}
|
|
24242
|
+
function waitForDelay(delayMs, signal) {
|
|
24243
|
+
if (signal?.aborted) return Promise.resolve(failure("runtime.timeout"));
|
|
24244
|
+
if (delayMs === void 0 || delayMs <= 0) {
|
|
24245
|
+
return Promise.resolve({ ok: true, value: void 0 });
|
|
24246
|
+
}
|
|
24247
|
+
return new Promise((resolve10) => {
|
|
24248
|
+
const onAbort = () => {
|
|
24249
|
+
clearTimeout(timer);
|
|
24250
|
+
resolve10(failure("runtime.timeout"));
|
|
24251
|
+
};
|
|
24252
|
+
const timer = setTimeout(() => {
|
|
24253
|
+
signal?.removeEventListener("abort", onAbort);
|
|
24254
|
+
resolve10({ ok: true, value: void 0 });
|
|
24255
|
+
}, delayMs);
|
|
24256
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
24257
|
+
});
|
|
24258
|
+
}
|
|
23578
24259
|
async function renderMockResponse(options) {
|
|
23579
|
-
const { mock, fileRoot } = options;
|
|
23580
|
-
|
|
24260
|
+
const { mock, fileRoot, method, signal } = options;
|
|
24261
|
+
const waited = await waitForDelay(mock.delayMs, signal);
|
|
24262
|
+
if (!waited.ok) return waited;
|
|
24263
|
+
let fullBytes;
|
|
23581
24264
|
if (mock.body !== void 0) {
|
|
23582
|
-
|
|
24265
|
+
fullBytes = new TextEncoder().encode(mock.body);
|
|
23583
24266
|
} else if (mock.file !== void 0) {
|
|
23584
24267
|
if (fileRoot === void 0) return failure("runtime.file-denied");
|
|
23585
|
-
|
|
23586
|
-
|
|
23587
|
-
|
|
24268
|
+
if (!isConfinedFileSupported()) {
|
|
24269
|
+
return failure("runtime.platform-unsupported");
|
|
24270
|
+
}
|
|
24271
|
+
const read2 = await readMockFile(fileRoot, mock.file, signal);
|
|
24272
|
+
if (!read2.ok) return read2;
|
|
24273
|
+
fullBytes = read2.value;
|
|
23588
24274
|
} else {
|
|
23589
24275
|
return failure("runtime.file-denied");
|
|
23590
24276
|
}
|
|
23591
24277
|
const headers = [];
|
|
23592
24278
|
let hasContentType = false;
|
|
24279
|
+
let hasCacheControl = false;
|
|
23593
24280
|
for (const header of mock.headers ?? []) {
|
|
24281
|
+
const name = headerName(header.name);
|
|
24282
|
+
if (name === "content-length") continue;
|
|
24283
|
+
if (name === "content-type") hasContentType = true;
|
|
24284
|
+
if (name === "cache-control") hasCacheControl = true;
|
|
23594
24285
|
headers.push([header.name, header.value]);
|
|
23595
|
-
if (header.name.toLowerCase() === "content-type") hasContentType = true;
|
|
23596
24286
|
}
|
|
23597
24287
|
if (!hasContentType) {
|
|
23598
|
-
headers.push(["Content-Type", "
|
|
24288
|
+
headers.push(["Content-Type", "application/octet-stream"]);
|
|
23599
24289
|
}
|
|
23600
|
-
headers.push(["Content-Length", String(
|
|
23601
|
-
headers.push(["Cache-Control", "no-store"]);
|
|
24290
|
+
headers.push(["Content-Length", String(fullBytes.byteLength)]);
|
|
24291
|
+
if (!hasCacheControl) headers.push(["Cache-Control", "no-store"]);
|
|
23602
24292
|
return {
|
|
23603
24293
|
ok: true,
|
|
23604
24294
|
value: {
|
|
23605
24295
|
status: mock.status,
|
|
23606
24296
|
headers,
|
|
23607
|
-
bodyBytes
|
|
24297
|
+
bodyBytes: method === "HEAD" ? new Uint8Array() : fullBytes
|
|
23608
24298
|
}
|
|
23609
24299
|
};
|
|
23610
24300
|
}
|
|
24301
|
+
var MAX_MOCK_FILE_ERRORS = 64;
|
|
24302
|
+
var FILE_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
24303
|
+
"runtime.file-denied",
|
|
24304
|
+
"runtime.file-race-rejected",
|
|
24305
|
+
"runtime.size-limit",
|
|
24306
|
+
"runtime.platform-unsupported"
|
|
24307
|
+
]);
|
|
24308
|
+
function isMockFileError(code) {
|
|
24309
|
+
return FILE_ERROR_CODES.has(code);
|
|
24310
|
+
}
|
|
24311
|
+
function recordMockFileError(errors, ruleId, code) {
|
|
24312
|
+
if (!isMockFileError(code)) return;
|
|
24313
|
+
if (errors.has(ruleId)) errors.delete(ruleId);
|
|
24314
|
+
errors.set(ruleId, code);
|
|
24315
|
+
while (errors.size > MAX_MOCK_FILE_ERRORS) {
|
|
24316
|
+
const oldest = errors.keys().next().value;
|
|
24317
|
+
if (oldest === void 0) break;
|
|
24318
|
+
errors.delete(oldest);
|
|
24319
|
+
}
|
|
24320
|
+
}
|
|
24321
|
+
function clearMockFileError(errors, ruleId) {
|
|
24322
|
+
errors.delete(ruleId);
|
|
24323
|
+
}
|
|
24324
|
+
function listMockFileErrors(errors) {
|
|
24325
|
+
return [...errors.entries()].map(([ruleId, code]) => ({ ruleId, code })).sort(
|
|
24326
|
+
(left, right) => left.ruleId < right.ruleId ? -1 : left.ruleId > right.ruleId ? 1 : 0
|
|
24327
|
+
);
|
|
24328
|
+
}
|
|
23611
24329
|
function stringValue(value) {
|
|
23612
24330
|
const encoded = JSON.stringify(value);
|
|
23613
24331
|
if (encoded === void 0) throw new Error("invalid string");
|
|
@@ -23654,10 +24372,10 @@ function mockHeaderValue(header) {
|
|
|
23654
24372
|
}
|
|
23655
24373
|
function mockValue(mock) {
|
|
23656
24374
|
const headers = mock.headers === void 0 ? "" : `,"headers":[${mock.headers.map(mockHeaderValue).join(",")}]`;
|
|
23657
|
-
const
|
|
24375
|
+
const delay = mock.delayMs === void 0 ? "" : `,"delayMs":${String(mock.delayMs)}`;
|
|
23658
24376
|
const body = mock.body !== void 0 ? `,"body":${stringValue(mock.body)}` : "";
|
|
23659
24377
|
const file = mock.file !== void 0 ? `,"file":${stringValue(mock.file)}` : "";
|
|
23660
|
-
return `{"ruleId":${stringValue(mock.ruleId)},"status":${String(mock.status)}${headers}${
|
|
24378
|
+
return `{"ruleId":${stringValue(mock.ruleId)},"status":${String(mock.status)}${headers}${delay}${body}${file}}`;
|
|
23661
24379
|
}
|
|
23662
24380
|
function sortMocks(mocks) {
|
|
23663
24381
|
return [...mocks].sort(
|
|
@@ -23701,7 +24419,7 @@ function normalizeMockHeader(value) {
|
|
|
23701
24419
|
const record = value;
|
|
23702
24420
|
if (typeof record.name !== "string" || record.name.length === 0 || record.name.length > LIMITS.maxMockHeaderNameLength || hasControl(record.name) || record.name.includes(":"))
|
|
23703
24421
|
return null;
|
|
23704
|
-
if (typeof record.value !== "string" || record.value.length > LIMITS.maxMockHeaderValueLength)
|
|
24422
|
+
if (typeof record.value !== "string" || record.value.length > LIMITS.maxMockHeaderValueLength || hasControl(record.value))
|
|
23705
24423
|
return null;
|
|
23706
24424
|
return { name: record.name, value: record.value };
|
|
23707
24425
|
}
|
|
@@ -23905,6 +24623,26 @@ function makeGrant(value, matcherById) {
|
|
|
23905
24623
|
method: record.method
|
|
23906
24624
|
});
|
|
23907
24625
|
}
|
|
24626
|
+
function parseEnabledGroupIds(metadata, groupIds) {
|
|
24627
|
+
if (!hasOwn(metadata, "enabledGroupIds")) {
|
|
24628
|
+
return { ok: true, value: void 0 };
|
|
24629
|
+
}
|
|
24630
|
+
const value = metadata.enabledGroupIds;
|
|
24631
|
+
if (!Array.isArray(value) || value.length > LIMITS.maxGroups) {
|
|
24632
|
+
return failure("runtime.groups-invalid");
|
|
24633
|
+
}
|
|
24634
|
+
const known = new Set(groupIds);
|
|
24635
|
+
const enabled = /* @__PURE__ */ new Set();
|
|
24636
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
24637
|
+
if (!Object.hasOwn(value, index)) return failure("runtime.groups-invalid");
|
|
24638
|
+
const id2 = value[index];
|
|
24639
|
+
if (typeof id2 !== "string" || !ID_PATTERN2.test(id2) || !known.has(id2) || enabled.has(id2)) {
|
|
24640
|
+
return failure("runtime.groups-invalid");
|
|
24641
|
+
}
|
|
24642
|
+
enabled.add(id2);
|
|
24643
|
+
}
|
|
24644
|
+
return { ok: true, value: enabled };
|
|
24645
|
+
}
|
|
23908
24646
|
function normalizeRuntimePreset(value) {
|
|
23909
24647
|
const snapshot2 = snapshotOwnData3(value);
|
|
23910
24648
|
if (!snapshot2.valid || snapshot2.value === null || typeof snapshot2.value !== "object" || Array.isArray(snapshot2.value)) {
|
|
@@ -23991,18 +24729,41 @@ function normalizeRuntimePreset(value) {
|
|
|
23991
24729
|
});
|
|
23992
24730
|
return { ok: true, value: normalized };
|
|
23993
24731
|
}
|
|
23994
|
-
function
|
|
23995
|
-
return
|
|
24732
|
+
function matchersFromOperations(operations) {
|
|
24733
|
+
return operations.map((operation) => ({
|
|
24734
|
+
kind: "matcher",
|
|
24735
|
+
groupId: operation.groupId,
|
|
24736
|
+
ruleId: operation.ruleId,
|
|
24737
|
+
name: operation.name,
|
|
24738
|
+
redactSensitiveInLogs: operation.redactSensitiveInLogs,
|
|
24739
|
+
matcher: operation.matcher
|
|
24740
|
+
}));
|
|
23996
24741
|
}
|
|
23997
|
-
|
|
23998
|
-
|
|
23999
|
-
|
|
24742
|
+
function mocksFromOperations(operations, enabledGroupIds) {
|
|
24743
|
+
const mocks = [];
|
|
24744
|
+
for (const operation of operations) {
|
|
24745
|
+
if (operation.kind !== "mock") continue;
|
|
24746
|
+
if (enabledGroupIds !== void 0 && !enabledGroupIds.has(operation.groupId)) {
|
|
24747
|
+
continue;
|
|
24748
|
+
}
|
|
24749
|
+
const mock = operation.mock;
|
|
24750
|
+
mocks.push({
|
|
24751
|
+
ruleId: operation.ruleId,
|
|
24752
|
+
status: mock.status,
|
|
24753
|
+
...mock.headers === void 0 ? {} : { headers: mock.headers },
|
|
24754
|
+
...mock.delayMs === void 0 ? {} : { delayMs: mock.delayMs },
|
|
24755
|
+
...mock.body === void 0 ? {} : { body: mock.body },
|
|
24756
|
+
...mock.file === void 0 ? {} : { file: mock.file }
|
|
24757
|
+
});
|
|
24758
|
+
}
|
|
24759
|
+
return mocks;
|
|
24000
24760
|
}
|
|
24001
24761
|
function createNativeRuntimeController(options) {
|
|
24002
24762
|
let preset = options.preset;
|
|
24003
|
-
|
|
24004
|
-
const mockPort = options.mockPort;
|
|
24763
|
+
let fileRoot = options.fileRoot;
|
|
24005
24764
|
const clock = options.clock ?? (() => Date.now());
|
|
24765
|
+
const directoryPicker = options.directoryPicker ?? pickDirectory;
|
|
24766
|
+
const mockFileErrors = /* @__PURE__ */ new Map();
|
|
24006
24767
|
let state = "idle";
|
|
24007
24768
|
let activation;
|
|
24008
24769
|
let capability;
|
|
@@ -24028,8 +24789,8 @@ function createNativeRuntimeController(options) {
|
|
|
24028
24789
|
if (!reader) return aiConfigInForce;
|
|
24029
24790
|
let next = null;
|
|
24030
24791
|
try {
|
|
24031
|
-
const
|
|
24032
|
-
next = isUsableAIProviderConfig(
|
|
24792
|
+
const read2 = await reader();
|
|
24793
|
+
next = isUsableAIProviderConfig(read2) ? read2 : null;
|
|
24033
24794
|
} catch {
|
|
24034
24795
|
next = null;
|
|
24035
24796
|
}
|
|
@@ -24107,6 +24868,7 @@ function createNativeRuntimeController(options) {
|
|
|
24107
24868
|
}
|
|
24108
24869
|
const startedAt = clock();
|
|
24109
24870
|
capability = createCapabilityState(preset, startedAt);
|
|
24871
|
+
mockFileErrors.clear();
|
|
24110
24872
|
mockTokens.clear();
|
|
24111
24873
|
for (const mock of preset.mocks ?? []) {
|
|
24112
24874
|
mockTokens.set(mintToken(), mock);
|
|
@@ -24136,6 +24898,7 @@ function createNativeRuntimeController(options) {
|
|
|
24136
24898
|
return { state: "stopped" };
|
|
24137
24899
|
}
|
|
24138
24900
|
state = "stopping";
|
|
24901
|
+
mockFileErrors.clear();
|
|
24139
24902
|
if (options.onStop) await options.onStop();
|
|
24140
24903
|
await stopInterception();
|
|
24141
24904
|
if (capability) closeCapabilityState(capability);
|
|
@@ -24154,15 +24917,35 @@ function createNativeRuntimeController(options) {
|
|
|
24154
24917
|
getActivePolicy() {
|
|
24155
24918
|
return activePolicy;
|
|
24156
24919
|
},
|
|
24157
|
-
async serveMock(token) {
|
|
24920
|
+
async serveMock(token, options2) {
|
|
24158
24921
|
const mock = mockTokens.get(token);
|
|
24159
|
-
if (mock === void 0
|
|
24160
|
-
|
|
24161
|
-
|
|
24922
|
+
if (mock === void 0 || state !== "running" || preset === void 0) {
|
|
24923
|
+
return failure("runtime.mock-unknown");
|
|
24924
|
+
}
|
|
24925
|
+
const method = options2?.method?.toUpperCase();
|
|
24926
|
+
const matcher = preset.matchers.find(
|
|
24927
|
+
(candidate) => candidate.ruleId === mock.ruleId
|
|
24928
|
+
);
|
|
24929
|
+
if (method !== void 0) {
|
|
24930
|
+
if (matcher === void 0) return failure("runtime.mock-unknown");
|
|
24931
|
+
if (matcher.matcher.method !== void 0 && matcher.matcher.method !== method) {
|
|
24932
|
+
return failure("runtime.unsupported-method");
|
|
24933
|
+
}
|
|
24934
|
+
}
|
|
24935
|
+
const rendered = await renderMockResponse({
|
|
24162
24936
|
mock,
|
|
24163
24937
|
fileRoot,
|
|
24164
|
-
presetDigest: preset.digest
|
|
24938
|
+
presetDigest: preset.digest,
|
|
24939
|
+
...method !== void 0 ? { method } : {},
|
|
24940
|
+
...options2?.signal !== void 0 ? { signal: options2.signal } : {}
|
|
24165
24941
|
});
|
|
24942
|
+
if (!rendered.ok) {
|
|
24943
|
+
recordMockFileError(mockFileErrors, mock.ruleId, rendered.error.code);
|
|
24944
|
+
return rendered;
|
|
24945
|
+
}
|
|
24946
|
+
if (mock.file !== void 0)
|
|
24947
|
+
clearMockFileError(mockFileErrors, mock.ruleId);
|
|
24948
|
+
return rendered;
|
|
24166
24949
|
},
|
|
24167
24950
|
getBootstrapCapability() {
|
|
24168
24951
|
if (capability === void 0 || capability.consumed || capability.closed) {
|
|
@@ -24209,23 +24992,55 @@ function createNativeRuntimeController(options) {
|
|
|
24209
24992
|
}
|
|
24210
24993
|
};
|
|
24211
24994
|
}
|
|
24212
|
-
const
|
|
24213
|
-
|
|
24214
|
-
|
|
24215
|
-
|
|
24216
|
-
|
|
24217
|
-
|
|
24218
|
-
|
|
24219
|
-
|
|
24220
|
-
|
|
24221
|
-
|
|
24995
|
+
const metadata = input.metadata;
|
|
24996
|
+
if (metadata === null || typeof metadata !== "object") {
|
|
24997
|
+
return {
|
|
24998
|
+
protocol: "v1",
|
|
24999
|
+
type: "runtime.project.set",
|
|
25000
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25001
|
+
timestamp,
|
|
25002
|
+
metadata: { ok: false, error: "runtime.project-missing" }
|
|
25003
|
+
};
|
|
25004
|
+
}
|
|
25005
|
+
const enabledGroups = parseEnabledGroupIds(
|
|
25006
|
+
metadata,
|
|
25007
|
+
schemaResult.data.groups.map((group) => group.id)
|
|
25008
|
+
);
|
|
25009
|
+
if (!enabledGroups.ok) {
|
|
25010
|
+
return {
|
|
25011
|
+
protocol: "v1",
|
|
25012
|
+
type: "runtime.project.set",
|
|
25013
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25014
|
+
timestamp,
|
|
25015
|
+
metadata: { ok: false, error: enabledGroups.error.code }
|
|
25016
|
+
};
|
|
25017
|
+
}
|
|
25018
|
+
if (Object.hasOwn(metadata, "fileRoot")) {
|
|
25019
|
+
const resolvedRoot = await resolveConfinedRoot(
|
|
25020
|
+
metadata.fileRoot
|
|
25021
|
+
);
|
|
25022
|
+
if (!resolvedRoot.ok) {
|
|
25023
|
+
return {
|
|
25024
|
+
protocol: "v1",
|
|
25025
|
+
type: "runtime.project.set",
|
|
25026
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25027
|
+
timestamp,
|
|
25028
|
+
metadata: { ok: false, error: resolvedRoot.error.code }
|
|
25029
|
+
};
|
|
24222
25030
|
}
|
|
25031
|
+
fileRoot = resolvedRoot.value;
|
|
24223
25032
|
}
|
|
25033
|
+
const matcherOps = matchersFromOperations(compileResult.operations);
|
|
25034
|
+
const mocks = mocksFromOperations(
|
|
25035
|
+
compileResult.operations,
|
|
25036
|
+
enabledGroups.value
|
|
25037
|
+
);
|
|
24224
25038
|
const presetInput = {
|
|
24225
25039
|
version: 1,
|
|
24226
25040
|
limits: RUNTIME_LIMITS,
|
|
24227
25041
|
matchers: matcherOps,
|
|
24228
|
-
grants: []
|
|
25042
|
+
grants: [],
|
|
25043
|
+
...mocks.length > 0 ? { mocks } : {}
|
|
24229
25044
|
};
|
|
24230
25045
|
console.error(
|
|
24231
25046
|
"[rogatio-host] normalizeRuntimePreset input: matchers=",
|
|
@@ -24329,6 +25144,88 @@ function createNativeRuntimeController(options) {
|
|
|
24329
25144
|
metadata: { ok: true, state: "stopped" }
|
|
24330
25145
|
};
|
|
24331
25146
|
}
|
|
25147
|
+
if (input.type === "runtime.pick-directory") {
|
|
25148
|
+
const picked = await directoryPicker();
|
|
25149
|
+
if (!picked.ok) {
|
|
25150
|
+
return {
|
|
25151
|
+
protocol: "v1",
|
|
25152
|
+
type: "runtime.pick-directory",
|
|
25153
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25154
|
+
timestamp,
|
|
25155
|
+
metadata: { ok: false, error: picked.code }
|
|
25156
|
+
};
|
|
25157
|
+
}
|
|
25158
|
+
if (picked.path === null) {
|
|
25159
|
+
return {
|
|
25160
|
+
protocol: "v1",
|
|
25161
|
+
type: "runtime.pick-directory",
|
|
25162
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25163
|
+
timestamp,
|
|
25164
|
+
metadata: { ok: true, cancelled: true }
|
|
25165
|
+
};
|
|
25166
|
+
}
|
|
25167
|
+
const resolved = await resolveConfinedRoot(picked.path);
|
|
25168
|
+
return {
|
|
25169
|
+
protocol: "v1",
|
|
25170
|
+
type: "runtime.pick-directory",
|
|
25171
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25172
|
+
timestamp,
|
|
25173
|
+
metadata: resolved.ok ? { ok: true, path: resolved.value } : { ok: false, error: resolved.error.code }
|
|
25174
|
+
};
|
|
25175
|
+
}
|
|
25176
|
+
if (input.type === "runtime.set-file-root") {
|
|
25177
|
+
if (state !== "running") {
|
|
25178
|
+
return {
|
|
25179
|
+
protocol: "v1",
|
|
25180
|
+
type: "runtime.set-file-root",
|
|
25181
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25182
|
+
timestamp,
|
|
25183
|
+
metadata: { ok: false, error: "runtime.not-started" }
|
|
25184
|
+
};
|
|
25185
|
+
}
|
|
25186
|
+
const candidate = input.metadata.path;
|
|
25187
|
+
if (candidate === void 0 || candidate === null || candidate === "") {
|
|
25188
|
+
fileRoot = void 0;
|
|
25189
|
+
mockFileErrors.clear();
|
|
25190
|
+
return {
|
|
25191
|
+
protocol: "v1",
|
|
25192
|
+
type: "runtime.set-file-root",
|
|
25193
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25194
|
+
timestamp,
|
|
25195
|
+
metadata: { ok: true, cleared: true }
|
|
25196
|
+
};
|
|
25197
|
+
}
|
|
25198
|
+
const resolved = await resolveConfinedRoot(candidate);
|
|
25199
|
+
if (!resolved.ok) {
|
|
25200
|
+
return {
|
|
25201
|
+
protocol: "v1",
|
|
25202
|
+
type: "runtime.set-file-root",
|
|
25203
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25204
|
+
timestamp,
|
|
25205
|
+
metadata: { ok: false, error: resolved.error.code }
|
|
25206
|
+
};
|
|
25207
|
+
}
|
|
25208
|
+
fileRoot = resolved.value;
|
|
25209
|
+
mockFileErrors.clear();
|
|
25210
|
+
return {
|
|
25211
|
+
protocol: "v1",
|
|
25212
|
+
type: "runtime.set-file-root",
|
|
25213
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25214
|
+
timestamp,
|
|
25215
|
+
metadata: { ok: true, path: resolved.value }
|
|
25216
|
+
};
|
|
25217
|
+
}
|
|
25218
|
+
if (input.type === "runtime.check-directory") {
|
|
25219
|
+
const candidate = input.metadata.path;
|
|
25220
|
+
const resolved = await resolveConfinedRoot(candidate);
|
|
25221
|
+
return {
|
|
25222
|
+
protocol: "v1",
|
|
25223
|
+
type: "runtime.check-directory",
|
|
25224
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25225
|
+
timestamp,
|
|
25226
|
+
metadata: resolved.ok ? { ok: true, path: resolved.value } : { ok: false, error: resolved.error.code }
|
|
25227
|
+
};
|
|
25228
|
+
}
|
|
24332
25229
|
if (state !== "running" || capability === void 0) {
|
|
24333
25230
|
throw new Error("runtime not started");
|
|
24334
25231
|
}
|
|
@@ -24427,8 +25324,7 @@ function createNativeRuntimeController(options) {
|
|
|
24427
25324
|
const metadata = {
|
|
24428
25325
|
protocol: "v1",
|
|
24429
25326
|
presetDigest: preset.digest,
|
|
24430
|
-
mocks
|
|
24431
|
-
...mockPort !== void 0 ? { port: mockPort } : {}
|
|
25327
|
+
mocks
|
|
24432
25328
|
};
|
|
24433
25329
|
return {
|
|
24434
25330
|
protocol: "v1",
|
|
@@ -24438,29 +25334,6 @@ function createNativeRuntimeController(options) {
|
|
|
24438
25334
|
metadata
|
|
24439
25335
|
};
|
|
24440
25336
|
}
|
|
24441
|
-
case "mock.request": {
|
|
24442
|
-
const meta = input.metadata;
|
|
24443
|
-
const mock = mockTokens.get(meta.token);
|
|
24444
|
-
if (mock === void 0) {
|
|
24445
|
-
const body = JSON.stringify({
|
|
24446
|
-
ok: false,
|
|
24447
|
-
error: { code: "runtime.mock-unknown" }
|
|
24448
|
-
});
|
|
24449
|
-
const metadata = {
|
|
24450
|
-
status: 404,
|
|
24451
|
-
headers: [["Content-Type", "application/json"]],
|
|
24452
|
-
mockBody: base64(new TextEncoder().encode(body))
|
|
24453
|
-
};
|
|
24454
|
-
return {
|
|
24455
|
-
protocol: "v1",
|
|
24456
|
-
type: "mock.response",
|
|
24457
|
-
...requestId !== void 0 ? { requestId } : {},
|
|
24458
|
-
timestamp,
|
|
24459
|
-
metadata
|
|
24460
|
-
};
|
|
24461
|
-
}
|
|
24462
|
-
return renderMock(mock, requestId, timestamp);
|
|
24463
|
-
}
|
|
24464
25337
|
case "runtime.status": {
|
|
24465
25338
|
if (!preset) throw new Error("runtime not started");
|
|
24466
25339
|
return {
|
|
@@ -24468,7 +25341,11 @@ function createNativeRuntimeController(options) {
|
|
|
24468
25341
|
type: "runtime.status",
|
|
24469
25342
|
...requestId !== void 0 ? { requestId } : {},
|
|
24470
25343
|
timestamp,
|
|
24471
|
-
metadata: {
|
|
25344
|
+
metadata: {
|
|
25345
|
+
state,
|
|
25346
|
+
presetDigest: preset.digest,
|
|
25347
|
+
mockFileErrors: listMockFileErrors(mockFileErrors)
|
|
25348
|
+
}
|
|
24472
25349
|
};
|
|
24473
25350
|
}
|
|
24474
25351
|
case "ai.status": {
|
|
@@ -24604,49 +25481,127 @@ function createNativeRuntimeController(options) {
|
|
|
24604
25481
|
}
|
|
24605
25482
|
}
|
|
24606
25483
|
};
|
|
24607
|
-
|
|
24608
|
-
|
|
24609
|
-
|
|
24610
|
-
|
|
24611
|
-
|
|
24612
|
-
|
|
24613
|
-
|
|
24614
|
-
|
|
24615
|
-
|
|
24616
|
-
|
|
24617
|
-
|
|
24618
|
-
|
|
24619
|
-
|
|
24620
|
-
|
|
24621
|
-
|
|
24622
|
-
|
|
24623
|
-
|
|
24624
|
-
|
|
24625
|
-
|
|
24626
|
-
|
|
24627
|
-
|
|
24628
|
-
|
|
24629
|
-
|
|
24630
|
-
|
|
24631
|
-
|
|
25484
|
+
}
|
|
25485
|
+
var NATIVE_FRAME_MAX_BYTES = 64 * 1024;
|
|
25486
|
+
var NATIVE_POLICY_MAX_BYTES = 256 * 1024;
|
|
25487
|
+
var NATIVE_POLICY_MAX_FRAMES = 32;
|
|
25488
|
+
var NATIVE_POLICY_STAGE_TIMEOUT_MS = 5e3;
|
|
25489
|
+
function encodeNativeFrame(frame) {
|
|
25490
|
+
const json = JSON.stringify(frame);
|
|
25491
|
+
const bytes = new TextEncoder().encode(json);
|
|
25492
|
+
if (bytes.byteLength > NATIVE_FRAME_MAX_BYTES) {
|
|
25493
|
+
throw new Error("Frame exceeds maximum size");
|
|
25494
|
+
}
|
|
25495
|
+
const result = new Uint8Array(4 + bytes.byteLength);
|
|
25496
|
+
new DataView(result.buffer).setUint32(0, bytes.byteLength, true);
|
|
25497
|
+
result.set(bytes, 4);
|
|
25498
|
+
return result;
|
|
25499
|
+
}
|
|
25500
|
+
function decodeNativeFrame(buffer) {
|
|
25501
|
+
if (buffer.byteLength < 4) {
|
|
25502
|
+
return failure("runtime.native-frame-too-small");
|
|
25503
|
+
}
|
|
25504
|
+
const length = new DataView(buffer.buffer, buffer.byteOffset, 4).getUint32(
|
|
25505
|
+
0,
|
|
25506
|
+
true
|
|
25507
|
+
);
|
|
25508
|
+
if (length > NATIVE_FRAME_MAX_BYTES) {
|
|
25509
|
+
return failure("runtime.native-frame-too-large");
|
|
25510
|
+
}
|
|
25511
|
+
if (buffer.byteLength !== 4 + length) {
|
|
25512
|
+
return failure("runtime.native-frame-length-mismatch");
|
|
25513
|
+
}
|
|
25514
|
+
try {
|
|
25515
|
+
const json = new TextDecoder("utf-8", { fatal: true }).decode(
|
|
25516
|
+
buffer.slice(4)
|
|
25517
|
+
);
|
|
25518
|
+
const frame = JSON.parse(json);
|
|
25519
|
+
if (frame.protocol !== "v1") {
|
|
25520
|
+
return failure("runtime.native-frame-invalid-protocol");
|
|
24632
25521
|
}
|
|
24633
|
-
|
|
24634
|
-
|
|
24635
|
-
|
|
25522
|
+
return { ok: true, value: frame };
|
|
25523
|
+
} catch {
|
|
25524
|
+
return failure("runtime.native-frame-invalid-json");
|
|
25525
|
+
}
|
|
25526
|
+
}
|
|
25527
|
+
function createPolicyStageState(totalBytes, partCount, expectedDigest) {
|
|
25528
|
+
return {
|
|
25529
|
+
totalBytes,
|
|
25530
|
+
partCount,
|
|
25531
|
+
receivedParts: /* @__PURE__ */ new Map(),
|
|
25532
|
+
expectedDigest,
|
|
25533
|
+
startTime: Date.now()
|
|
25534
|
+
};
|
|
25535
|
+
}
|
|
25536
|
+
function addPolicyPart(state, index, data) {
|
|
25537
|
+
if (Date.now() - state.startTime > NATIVE_POLICY_STAGE_TIMEOUT_MS) {
|
|
25538
|
+
return failure("runtime.request-body-policy-stage-timeout");
|
|
25539
|
+
}
|
|
25540
|
+
if (index < 0 || index >= state.partCount) {
|
|
25541
|
+
return failure("runtime.request-body-policy-invalid-part-index");
|
|
25542
|
+
}
|
|
25543
|
+
if (state.receivedParts.has(index)) {
|
|
25544
|
+
return failure("runtime.request-body-policy-duplicate-part");
|
|
25545
|
+
}
|
|
25546
|
+
state.receivedParts.set(index, data);
|
|
25547
|
+
return { ok: true, value: void 0 };
|
|
25548
|
+
}
|
|
25549
|
+
function commitPolicyStage(state) {
|
|
25550
|
+
if (state.receivedParts.size !== state.partCount) {
|
|
25551
|
+
return failure("runtime.request-body-policy-incomplete");
|
|
25552
|
+
}
|
|
25553
|
+
let totalReceived = 0;
|
|
25554
|
+
for (let i = 0; i < state.partCount; i += 1) {
|
|
25555
|
+
const part = state.receivedParts.get(i);
|
|
25556
|
+
if (!part) {
|
|
25557
|
+
return failure("runtime.request-body-policy-missing-part");
|
|
24636
25558
|
}
|
|
24637
|
-
|
|
24638
|
-
|
|
24639
|
-
|
|
24640
|
-
|
|
24641
|
-
|
|
24642
|
-
|
|
24643
|
-
|
|
24644
|
-
|
|
24645
|
-
|
|
24646
|
-
|
|
24647
|
-
|
|
24648
|
-
}
|
|
25559
|
+
totalReceived += part.byteLength;
|
|
25560
|
+
}
|
|
25561
|
+
if (totalReceived !== state.totalBytes) {
|
|
25562
|
+
return failure("runtime.request-body-policy-byte-count-mismatch");
|
|
25563
|
+
}
|
|
25564
|
+
const assembled = new Uint8Array(totalReceived);
|
|
25565
|
+
let offset = 0;
|
|
25566
|
+
for (let i = 0; i < state.partCount; i += 1) {
|
|
25567
|
+
const part = state.receivedParts.get(i);
|
|
25568
|
+
if (!part) {
|
|
25569
|
+
return failure("runtime.request-body-policy-missing-part");
|
|
25570
|
+
}
|
|
25571
|
+
assembled.set(part, offset);
|
|
25572
|
+
offset += part.byteLength;
|
|
25573
|
+
}
|
|
25574
|
+
return { ok: true, value: assembled };
|
|
25575
|
+
}
|
|
25576
|
+
var DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;
|
|
25577
|
+
function isProjectStageType(type) {
|
|
25578
|
+
return type === "policy-begin" || type === "policy-part" || type === "policy-commit";
|
|
25579
|
+
}
|
|
25580
|
+
function beginProjectStage(frame) {
|
|
25581
|
+
const { totalBytes, partCount, policyDigest } = frame;
|
|
25582
|
+
if (typeof totalBytes !== "number" || !Number.isSafeInteger(totalBytes) || totalBytes < 1 || totalBytes > NATIVE_POLICY_MAX_BYTES || typeof partCount !== "number" || !Number.isSafeInteger(partCount) || partCount < 1 || partCount > NATIVE_POLICY_MAX_FRAMES || typeof policyDigest !== "string" || !DIGEST_PATTERN.test(policyDigest)) {
|
|
25583
|
+
return failure("runtime.project-stage-invalid");
|
|
25584
|
+
}
|
|
25585
|
+
return {
|
|
25586
|
+
ok: true,
|
|
25587
|
+
value: createPolicyStageState(totalBytes, partCount, policyDigest)
|
|
25588
|
+
};
|
|
25589
|
+
}
|
|
25590
|
+
function acceptProjectPart(state, frame) {
|
|
25591
|
+
if (typeof frame.index !== "number" || !Number.isSafeInteger(frame.index) || typeof frame.data !== "string") {
|
|
25592
|
+
return failure("runtime.project-stage-invalid");
|
|
25593
|
+
}
|
|
25594
|
+
const bytes = Buffer.from(frame.data, "base64");
|
|
25595
|
+
return addPolicyPart(state, frame.index, bytes);
|
|
25596
|
+
}
|
|
25597
|
+
function finishProjectStage(state) {
|
|
25598
|
+
const assembled = commitPolicyStage(state);
|
|
25599
|
+
if (!assembled.ok) return assembled;
|
|
25600
|
+
const digest = `sha256:${createHash4("sha256").update(assembled.value).digest("hex")}`;
|
|
25601
|
+
if (digest !== state.expectedDigest) {
|
|
25602
|
+
return failure("runtime.project-stage-invalid");
|
|
24649
25603
|
}
|
|
25604
|
+
return assembled;
|
|
24650
25605
|
}
|
|
24651
25606
|
var import_reflect_metadata = __toESM(require_Reflect(), 1);
|
|
24652
25607
|
var import_x509 = __toESM(require_x509_cjs(), 1);
|
|
@@ -24714,7 +25669,7 @@ function generateNativeMessagingManifest(hostPath, name, allowedOrigins, install
|
|
|
24714
25669
|
"host path must be an absolute path"
|
|
24715
25670
|
);
|
|
24716
25671
|
}
|
|
24717
|
-
const rel =
|
|
25672
|
+
const rel = relative2(installRoot, hostPath);
|
|
24718
25673
|
if (rel === "" || rel.startsWith("..") || isAbsolute3(rel)) {
|
|
24719
25674
|
throw new TrustError(
|
|
24720
25675
|
"trust.invalid-host-path",
|
|
@@ -24779,7 +25734,7 @@ async function writeFileAtomic(path2, data) {
|
|
|
24779
25734
|
}
|
|
24780
25735
|
async function existsFile(path2) {
|
|
24781
25736
|
try {
|
|
24782
|
-
return (await
|
|
25737
|
+
return (await stat(path2)).isFile();
|
|
24783
25738
|
} catch {
|
|
24784
25739
|
return false;
|
|
24785
25740
|
}
|
|
@@ -24904,7 +25859,7 @@ function createRequestBodyTrustController(options = {}) {
|
|
|
24904
25859
|
await writeFileAtomic(caCertFile, certPem);
|
|
24905
25860
|
}
|
|
24906
25861
|
if (caTrustInstaller && !installerCalled) {
|
|
24907
|
-
await caTrustInstaller(await
|
|
25862
|
+
await caTrustInstaller(await readFile2(caCertFile, "utf8"));
|
|
24908
25863
|
installerCalled = true;
|
|
24909
25864
|
}
|
|
24910
25865
|
}
|
|
@@ -24946,7 +25901,7 @@ function createRequestBodyTrustController(options = {}) {
|
|
|
24946
25901
|
async function status() {
|
|
24947
25902
|
let installed = false;
|
|
24948
25903
|
try {
|
|
24949
|
-
const raw = await
|
|
25904
|
+
const raw = await readFile2(manifestPath(), "utf8");
|
|
24950
25905
|
installed = isWellFormedManifest(JSON.parse(raw));
|
|
24951
25906
|
} catch {
|
|
24952
25907
|
installed = false;
|
|
@@ -24968,14 +25923,14 @@ function createRequestBodyTrustController(options = {}) {
|
|
|
24968
25923
|
let binaryExecutable = false;
|
|
24969
25924
|
let allowedOrigins = [];
|
|
24970
25925
|
try {
|
|
24971
|
-
const raw = await
|
|
25926
|
+
const raw = await readFile2(manifestPath(), "utf8");
|
|
24972
25927
|
manifestExists = true;
|
|
24973
25928
|
const parsed = JSON.parse(raw);
|
|
24974
25929
|
if (isWellFormedManifest(parsed)) {
|
|
24975
25930
|
manifestValid = true;
|
|
24976
25931
|
allowedOrigins = [...parsed.allowed_origins];
|
|
24977
25932
|
try {
|
|
24978
|
-
const fileStat = await
|
|
25933
|
+
const fileStat = await stat(parsed.path);
|
|
24979
25934
|
binaryExists = fileStat.isFile();
|
|
24980
25935
|
binaryExecutable = (fileStat.mode & 73) !== 0;
|
|
24981
25936
|
if (!binaryExists) reasons.push("binary-not-found");
|
|
@@ -25008,6 +25963,17 @@ function createRequestBodyTrustController(options = {}) {
|
|
|
25008
25963
|
}
|
|
25009
25964
|
return { install, uninstall, status, verify };
|
|
25010
25965
|
}
|
|
25966
|
+
function stageAck(type, requestId, ok, error) {
|
|
25967
|
+
return encodeNativeFrame({
|
|
25968
|
+
protocol: "v1",
|
|
25969
|
+
type,
|
|
25970
|
+
...requestId !== void 0 ? { requestId } : {},
|
|
25971
|
+
data: JSON.stringify({
|
|
25972
|
+
ok,
|
|
25973
|
+
...error !== void 0 ? { error } : {}
|
|
25974
|
+
})
|
|
25975
|
+
});
|
|
25976
|
+
}
|
|
25011
25977
|
function encodeEnvelopeFrame(envelope) {
|
|
25012
25978
|
const json = new TextEncoder().encode(serializeEnvelope(envelope));
|
|
25013
25979
|
const out = new Uint8Array(4 + json.byteLength);
|
|
@@ -25028,41 +25994,6 @@ function decodeEnvelopeFrame(buffer) {
|
|
|
25028
25994
|
);
|
|
25029
25995
|
return parseEnvelope(json);
|
|
25030
25996
|
}
|
|
25031
|
-
function startMockFaucet(port, controller) {
|
|
25032
|
-
const server = createServer2((req, res) => {
|
|
25033
|
-
void (async () => {
|
|
25034
|
-
try {
|
|
25035
|
-
const url = new URL(req.url ?? "", "http://localhost");
|
|
25036
|
-
const match = /^\/mock\/([a-f0-9]+)$/.exec(url.pathname);
|
|
25037
|
-
if (!match || req.method !== "GET") {
|
|
25038
|
-
res.writeHead(404);
|
|
25039
|
-
res.end();
|
|
25040
|
-
return;
|
|
25041
|
-
}
|
|
25042
|
-
const result = await controller.serveMock(match[1]);
|
|
25043
|
-
if (!result.ok) {
|
|
25044
|
-
res.writeHead(404);
|
|
25045
|
-
res.end();
|
|
25046
|
-
return;
|
|
25047
|
-
}
|
|
25048
|
-
const { status, headers, bodyBytes } = result.value;
|
|
25049
|
-
res.writeHead(
|
|
25050
|
-
status,
|
|
25051
|
-
Object.fromEntries(
|
|
25052
|
-
headers.map((h) => [h[0], h[1]])
|
|
25053
|
-
)
|
|
25054
|
-
);
|
|
25055
|
-
res.end(Buffer2.from(bodyBytes));
|
|
25056
|
-
} catch {
|
|
25057
|
-
if (!res.headersSent) res.writeHead(500);
|
|
25058
|
-
res.end();
|
|
25059
|
-
}
|
|
25060
|
-
})();
|
|
25061
|
-
});
|
|
25062
|
-
return new Promise(
|
|
25063
|
-
(resolve22) => server.listen(port, () => resolve22(server))
|
|
25064
|
-
);
|
|
25065
|
-
}
|
|
25066
25997
|
function defaultTrustRoot() {
|
|
25067
25998
|
return defaultTrustInstallRoot(process.platform);
|
|
25068
25999
|
}
|
|
@@ -25070,12 +26001,10 @@ function createNativeHost(options) {
|
|
|
25070
26001
|
const controller = createNativeRuntimeController({
|
|
25071
26002
|
preset: options.preset,
|
|
25072
26003
|
fileRoot: options.fileRoot,
|
|
25073
|
-
...options.mockPort !== void 0 ? { mockPort: options.mockPort } : {},
|
|
25074
26004
|
...options.aiProviderConfig !== void 0 ? { aiProviderConfig: options.aiProviderConfig } : {},
|
|
25075
26005
|
...options.aiConfigReader !== void 0 ? { aiConfigReader: options.aiConfigReader } : {},
|
|
25076
26006
|
...options.clock ? { clock: options.clock } : {}
|
|
25077
26007
|
});
|
|
25078
|
-
let faucet = null;
|
|
25079
26008
|
let interceptProxy = null;
|
|
25080
26009
|
let outboundWrite = null;
|
|
25081
26010
|
let hostRequestCounter = 0;
|
|
@@ -25089,12 +26018,12 @@ function createNativeHost(options) {
|
|
|
25089
26018
|
timestamp: Date.now(),
|
|
25090
26019
|
metadata
|
|
25091
26020
|
};
|
|
25092
|
-
return new Promise((
|
|
26021
|
+
return new Promise((resolve10, reject) => {
|
|
25093
26022
|
if (!outboundWrite) {
|
|
25094
26023
|
reject(new Error("host stdout not attached"));
|
|
25095
26024
|
return;
|
|
25096
26025
|
}
|
|
25097
|
-
pendingHost.set(requestId, { resolve:
|
|
26026
|
+
pendingHost.set(requestId, { resolve: resolve10, reject });
|
|
25098
26027
|
try {
|
|
25099
26028
|
outboundWrite(encodeEnvelopeFrame(envelope));
|
|
25100
26029
|
} catch (error) {
|
|
@@ -25116,7 +26045,7 @@ function createNativeHost(options) {
|
|
|
25116
26045
|
const platformAdapter = {
|
|
25117
26046
|
platform: process.platform,
|
|
25118
26047
|
detect() {
|
|
25119
|
-
const trusted =
|
|
26048
|
+
const trusted = existsSync2(caKeyFile) && existsSync2(caCertFile);
|
|
25120
26049
|
return {
|
|
25121
26050
|
supported: true,
|
|
25122
26051
|
reasons: [],
|
|
@@ -25128,7 +26057,7 @@ function createNativeHost(options) {
|
|
|
25128
26057
|
};
|
|
25129
26058
|
},
|
|
25130
26059
|
async provisionOrVerifyCa() {
|
|
25131
|
-
return
|
|
26060
|
+
return existsSync2(caKeyFile) && existsSync2(caCertFile);
|
|
25132
26061
|
},
|
|
25133
26062
|
async installPac(script) {
|
|
25134
26063
|
const response = await sendHostRequest("runtime.pac.install", {
|
|
@@ -25156,7 +26085,11 @@ function createNativeHost(options) {
|
|
|
25156
26085
|
project: policy.project,
|
|
25157
26086
|
operations: policy.operations,
|
|
25158
26087
|
presetDigest: policy.presetDigest
|
|
25159
|
-
} : null
|
|
26088
|
+
} : null,
|
|
26089
|
+
serveMock: (request) => controller.serveMock(request.token, {
|
|
26090
|
+
method: request.method,
|
|
26091
|
+
signal: request.signal
|
|
26092
|
+
})
|
|
25160
26093
|
});
|
|
25161
26094
|
return interceptProxy.endpoint;
|
|
25162
26095
|
},
|
|
@@ -25189,20 +26122,93 @@ function createNativeHost(options) {
|
|
|
25189
26122
|
await platformProvider.stop();
|
|
25190
26123
|
}
|
|
25191
26124
|
});
|
|
26125
|
+
let projectStage;
|
|
26126
|
+
async function handleProjectStage(frame) {
|
|
26127
|
+
const requestId = frame.requestId;
|
|
26128
|
+
if (frame.type === "policy-begin") {
|
|
26129
|
+
const begun = beginProjectStage(frame);
|
|
26130
|
+
if (!begun.ok) {
|
|
26131
|
+
projectStage = void 0;
|
|
26132
|
+
return stageAck(
|
|
26133
|
+
"policy-begin",
|
|
26134
|
+
requestId,
|
|
26135
|
+
false,
|
|
26136
|
+
begun.error.code
|
|
26137
|
+
);
|
|
26138
|
+
}
|
|
26139
|
+
projectStage = begun.value;
|
|
26140
|
+
return stageAck("policy-begin", requestId, true);
|
|
26141
|
+
}
|
|
26142
|
+
if (frame.type === "policy-part") {
|
|
26143
|
+
if (projectStage === void 0) {
|
|
26144
|
+
return stageAck(
|
|
26145
|
+
"policy-part",
|
|
26146
|
+
requestId,
|
|
26147
|
+
false,
|
|
26148
|
+
"runtime.project-stage-invalid"
|
|
26149
|
+
);
|
|
26150
|
+
}
|
|
26151
|
+
const accepted = acceptProjectPart(projectStage, frame);
|
|
26152
|
+
if (!accepted.ok) {
|
|
26153
|
+
projectStage = void 0;
|
|
26154
|
+
return stageAck(
|
|
26155
|
+
"policy-part",
|
|
26156
|
+
requestId,
|
|
26157
|
+
false,
|
|
26158
|
+
accepted.error.code
|
|
26159
|
+
);
|
|
26160
|
+
}
|
|
26161
|
+
return stageAck("policy-part", requestId, true);
|
|
26162
|
+
}
|
|
26163
|
+
if (projectStage === void 0) {
|
|
26164
|
+
return stageAck(
|
|
26165
|
+
"policy-commit",
|
|
26166
|
+
requestId,
|
|
26167
|
+
false,
|
|
26168
|
+
"runtime.project-stage-invalid"
|
|
26169
|
+
);
|
|
26170
|
+
}
|
|
26171
|
+
const finished = finishProjectStage(projectStage);
|
|
26172
|
+
projectStage = void 0;
|
|
26173
|
+
if (!finished.ok) {
|
|
26174
|
+
return stageAck(
|
|
26175
|
+
"policy-commit",
|
|
26176
|
+
requestId,
|
|
26177
|
+
false,
|
|
26178
|
+
finished.error.code
|
|
26179
|
+
);
|
|
26180
|
+
}
|
|
26181
|
+
try {
|
|
26182
|
+
const json = new TextDecoder("utf-8", { fatal: true }).decode(
|
|
26183
|
+
finished.value
|
|
26184
|
+
);
|
|
26185
|
+
const envelope = parseEnvelope(json);
|
|
26186
|
+
if (envelope.type !== "runtime.project.set") {
|
|
26187
|
+
return stageAck(
|
|
26188
|
+
"policy-commit",
|
|
26189
|
+
requestId,
|
|
26190
|
+
false,
|
|
26191
|
+
"runtime.project-stage-invalid"
|
|
26192
|
+
);
|
|
26193
|
+
}
|
|
26194
|
+
const response = await controller.handleEnvelope(envelope);
|
|
26195
|
+
return encodeEnvelopeFrame(response);
|
|
26196
|
+
} catch {
|
|
26197
|
+
return stageAck(
|
|
26198
|
+
"policy-commit",
|
|
26199
|
+
requestId,
|
|
26200
|
+
false,
|
|
26201
|
+
"runtime.project-stage-invalid"
|
|
26202
|
+
);
|
|
26203
|
+
}
|
|
26204
|
+
}
|
|
25192
26205
|
const handle = {
|
|
25193
26206
|
controller,
|
|
25194
|
-
mockPort: options.mockPort ?? null,
|
|
25195
26207
|
async start() {
|
|
25196
26208
|
await controller.start();
|
|
25197
|
-
if (options.mockPort !== void 0) {
|
|
25198
|
-
faucet = await startMockFaucet(options.mockPort, controller);
|
|
25199
|
-
}
|
|
25200
26209
|
},
|
|
25201
26210
|
async stop() {
|
|
25202
|
-
|
|
25203
|
-
await new Promise((resolve22) => faucet?.close(() => resolve22()));
|
|
25204
|
-
faucet = null;
|
|
25205
|
-
}
|
|
26211
|
+
projectStage = void 0;
|
|
25206
26212
|
await controller.stop();
|
|
25207
26213
|
clearSession();
|
|
25208
26214
|
if (interceptProxy) {
|
|
@@ -25211,6 +26217,10 @@ function createNativeHost(options) {
|
|
|
25211
26217
|
}
|
|
25212
26218
|
},
|
|
25213
26219
|
async processFrame(frame) {
|
|
26220
|
+
const native = decodeNativeFrame(frame);
|
|
26221
|
+
if (native.ok && isProjectStageType(native.value.type)) {
|
|
26222
|
+
return handleProjectStage(native.value);
|
|
26223
|
+
}
|
|
25214
26224
|
let envelope;
|
|
25215
26225
|
try {
|
|
25216
26226
|
envelope = decodeEnvelopeFrame(frame);
|
|
@@ -25348,16 +26358,14 @@ async function runNativeHost(options) {
|
|
|
25348
26358
|
buffer = Buffer2.concat([buffer, buf]);
|
|
25349
26359
|
pump();
|
|
25350
26360
|
});
|
|
25351
|
-
await new Promise((
|
|
26361
|
+
await new Promise((resolve10) => {
|
|
25352
26362
|
stdin.on("end", () => {
|
|
25353
|
-
void commandChain.finally(() => host.stop()).then(() =>
|
|
26363
|
+
void commandChain.finally(() => host.stop()).then(() => resolve10());
|
|
25354
26364
|
});
|
|
25355
26365
|
if (options.onReady) options.onReady();
|
|
25356
26366
|
pump();
|
|
25357
26367
|
});
|
|
25358
26368
|
}
|
|
25359
|
-
var NATIVE_FRAME_MAX_BYTES = 64 * 1024;
|
|
25360
|
-
var NATIVE_POLICY_MAX_BYTES = 256 * 1024;
|
|
25361
26369
|
var PRIVATE_RANGES = [
|
|
25362
26370
|
{ start: ipToInt("10.0.0.0"), end: ipToInt("10.255.255.255") },
|
|
25363
26371
|
{ start: ipToInt("172.16.0.0"), end: ipToInt("172.31.255.255") },
|
|
@@ -25394,12 +26402,12 @@ var darwinAdapter = {
|
|
|
25394
26402
|
reasons.push("tooling-missing");
|
|
25395
26403
|
}
|
|
25396
26404
|
try {
|
|
25397
|
-
accessSync(manifestDir,
|
|
26405
|
+
accessSync(manifestDir, constants3.W_OK);
|
|
25398
26406
|
} catch {
|
|
25399
26407
|
reasons.push("manifest-dir-unwritable");
|
|
25400
26408
|
}
|
|
25401
26409
|
try {
|
|
25402
|
-
accessSync(caDir,
|
|
26410
|
+
accessSync(caDir, constants3.W_OK);
|
|
25403
26411
|
} catch {
|
|
25404
26412
|
reasons.push("keychain-unwritable");
|
|
25405
26413
|
}
|
|
@@ -25422,8 +26430,8 @@ var darwinAdapter = {
|
|
|
25422
26430
|
]);
|
|
25423
26431
|
}
|
|
25424
26432
|
const result = await new Promise(
|
|
25425
|
-
(
|
|
25426
|
-
const child =
|
|
26433
|
+
(resolve10) => {
|
|
26434
|
+
const child = spawn2("security", [
|
|
25427
26435
|
"add-trusted-cert",
|
|
25428
26436
|
"-d",
|
|
25429
26437
|
"-r",
|
|
@@ -25436,8 +26444,8 @@ var darwinAdapter = {
|
|
|
25436
26444
|
child.stderr?.on("data", (data) => {
|
|
25437
26445
|
stderr += data.toString();
|
|
25438
26446
|
});
|
|
25439
|
-
child.on("close", (code) =>
|
|
25440
|
-
child.on("error", (err) =>
|
|
26447
|
+
child.on("close", (code) => resolve10({ code: code ?? 1, stderr }));
|
|
26448
|
+
child.on("error", (err) => resolve10({ code: 1, stderr: err.message }));
|
|
25441
26449
|
}
|
|
25442
26450
|
);
|
|
25443
26451
|
try {
|
|
@@ -25456,8 +26464,8 @@ var darwinAdapter = {
|
|
|
25456
26464
|
async caTrustRemover() {
|
|
25457
26465
|
const keychain = this.defaultCaInstallPath();
|
|
25458
26466
|
const result = await new Promise(
|
|
25459
|
-
(
|
|
25460
|
-
const child =
|
|
26467
|
+
(resolve10) => {
|
|
26468
|
+
const child = spawn2("security", [
|
|
25461
26469
|
"delete-certificate",
|
|
25462
26470
|
"-c",
|
|
25463
26471
|
"CN=Rogatio Request-Body CA",
|
|
@@ -25467,8 +26475,8 @@ var darwinAdapter = {
|
|
|
25467
26475
|
child.stderr?.on("data", (data) => {
|
|
25468
26476
|
stderr += data.toString();
|
|
25469
26477
|
});
|
|
25470
|
-
child.on("close", (code) =>
|
|
25471
|
-
child.on("error", (err) =>
|
|
26478
|
+
child.on("close", (code) => resolve10({ code: code ?? 1, stderr }));
|
|
26479
|
+
child.on("error", (err) => resolve10({ code: 1, stderr: err.message }));
|
|
25472
26480
|
}
|
|
25473
26481
|
);
|
|
25474
26482
|
if (result.code !== 0) {
|
|
@@ -25505,16 +26513,16 @@ var linuxAdapter = {
|
|
|
25505
26513
|
reasons.push("tooling-missing");
|
|
25506
26514
|
}
|
|
25507
26515
|
try {
|
|
25508
|
-
accessSync2(manifestDir,
|
|
26516
|
+
accessSync2(manifestDir, constants4.W_OK);
|
|
25509
26517
|
} catch {
|
|
25510
26518
|
reasons.push("manifest-dir-unwritable");
|
|
25511
26519
|
}
|
|
25512
26520
|
try {
|
|
25513
|
-
accessSync2(CA_DIR,
|
|
26521
|
+
accessSync2(CA_DIR, constants4.W_OK);
|
|
25514
26522
|
} catch (err) {
|
|
25515
26523
|
if (err?.code === "ENOENT") {
|
|
25516
26524
|
try {
|
|
25517
|
-
accessSync2(dirname4(CA_DIR),
|
|
26525
|
+
accessSync2(dirname4(CA_DIR), constants4.W_OK);
|
|
25518
26526
|
} catch {
|
|
25519
26527
|
if (!hasSudo()) {
|
|
25520
26528
|
reasons.push("elevation-required");
|
|
@@ -25541,8 +26549,8 @@ var linuxAdapter = {
|
|
|
25541
26549
|
]);
|
|
25542
26550
|
}
|
|
25543
26551
|
const certResult = await new Promise(
|
|
25544
|
-
(
|
|
25545
|
-
const child =
|
|
26552
|
+
(resolve10) => {
|
|
26553
|
+
const child = spawn3("sudo", [
|
|
25546
26554
|
"sh",
|
|
25547
26555
|
"-c",
|
|
25548
26556
|
`cat > "${CERT_PATH}" << 'EOF'
|
|
@@ -25553,8 +26561,8 @@ EOF`
|
|
|
25553
26561
|
child.stderr?.on("data", (data) => {
|
|
25554
26562
|
stderr += data.toString();
|
|
25555
26563
|
});
|
|
25556
|
-
child.on("close", (code) =>
|
|
25557
|
-
child.on("error", (err) =>
|
|
26564
|
+
child.on("close", (code) => resolve10({ code: code ?? 1, stderr }));
|
|
26565
|
+
child.on("error", (err) => resolve10({ code: 1, stderr: err.message }));
|
|
25558
26566
|
}
|
|
25559
26567
|
);
|
|
25560
26568
|
if (certResult.code !== 0) {
|
|
@@ -25566,14 +26574,14 @@ EOF`
|
|
|
25566
26574
|
throw new TrustError("trust.internal", reason, [reason]);
|
|
25567
26575
|
}
|
|
25568
26576
|
const result = await new Promise(
|
|
25569
|
-
(
|
|
25570
|
-
const child =
|
|
26577
|
+
(resolve10) => {
|
|
26578
|
+
const child = spawn3("sudo", ["update-ca-certificates"]);
|
|
25571
26579
|
let stderr = "";
|
|
25572
26580
|
child.stderr?.on("data", (data) => {
|
|
25573
26581
|
stderr += data.toString();
|
|
25574
26582
|
});
|
|
25575
|
-
child.on("close", (code) =>
|
|
25576
|
-
child.on("error", (err) =>
|
|
26583
|
+
child.on("close", (code) => resolve10({ code: code ?? 1, stderr }));
|
|
26584
|
+
child.on("error", (err) => resolve10({ code: 1, stderr: err.message }));
|
|
25577
26585
|
}
|
|
25578
26586
|
);
|
|
25579
26587
|
if (result.code !== 0) {
|
|
@@ -25632,7 +26640,7 @@ var win32Adapter = {
|
|
|
25632
26640
|
reasons.push("tooling-missing");
|
|
25633
26641
|
}
|
|
25634
26642
|
try {
|
|
25635
|
-
accessSync3(manifestDir,
|
|
26643
|
+
accessSync3(manifestDir, constants5.W_OK);
|
|
25636
26644
|
} catch {
|
|
25637
26645
|
reasons.push("manifest-dir-unwritable");
|
|
25638
26646
|
}
|
|
@@ -25654,14 +26662,14 @@ var win32Adapter = {
|
|
|
25654
26662
|
]);
|
|
25655
26663
|
}
|
|
25656
26664
|
const result = await new Promise(
|
|
25657
|
-
(
|
|
25658
|
-
const child =
|
|
26665
|
+
(resolve10) => {
|
|
26666
|
+
const child = spawn4("certutil", ["-addstore", "-f", "Root", tmpPath]);
|
|
25659
26667
|
let stderr = "";
|
|
25660
26668
|
child.stderr?.on("data", (data) => {
|
|
25661
26669
|
stderr += data.toString();
|
|
25662
26670
|
});
|
|
25663
|
-
child.on("close", (code) =>
|
|
25664
|
-
child.on("error", (err) =>
|
|
26671
|
+
child.on("close", (code) => resolve10({ code: code ?? 1, stderr }));
|
|
26672
|
+
child.on("error", (err) => resolve10({ code: 1, stderr: err.message }));
|
|
25665
26673
|
}
|
|
25666
26674
|
);
|
|
25667
26675
|
try {
|
|
@@ -25679,8 +26687,8 @@ var win32Adapter = {
|
|
|
25679
26687
|
},
|
|
25680
26688
|
async caTrustRemover() {
|
|
25681
26689
|
const result = await new Promise(
|
|
25682
|
-
(
|
|
25683
|
-
const child =
|
|
26690
|
+
(resolve10) => {
|
|
26691
|
+
const child = spawn4("certutil", [
|
|
25684
26692
|
"-delstore",
|
|
25685
26693
|
"Root",
|
|
25686
26694
|
"CN=Rogatio Request-Body CA"
|
|
@@ -25689,8 +26697,8 @@ var win32Adapter = {
|
|
|
25689
26697
|
child.stderr?.on("data", (data) => {
|
|
25690
26698
|
stderr += data.toString();
|
|
25691
26699
|
});
|
|
25692
|
-
child.on("close", (code) =>
|
|
25693
|
-
child.on("error", (err) =>
|
|
26700
|
+
child.on("close", (code) => resolve10({ code: code ?? 1, stderr }));
|
|
26701
|
+
child.on("error", (err) => resolve10({ code: 1, stderr: err.message }));
|
|
25694
26702
|
}
|
|
25695
26703
|
);
|
|
25696
26704
|
if (result.code !== 0) {
|
|
@@ -25786,8 +26794,10 @@ Options:
|
|
|
25786
26794
|
--extension-id Extension ID for the native messaging manifest. Release users
|
|
25787
26795
|
never need this. It is only for development (a local unpacked
|
|
25788
26796
|
build without the release key) and for forks.
|
|
25789
|
-
--root <dir> Root for confined runtime file access (host only
|
|
25790
|
-
|
|
26797
|
+
--root <dir> Root for confined runtime file access (host only). Default: the
|
|
26798
|
+
saved device-local root for that project file, otherwise the
|
|
26799
|
+
project directory. Required when the host reads a stdin
|
|
26800
|
+
project that contains a file mock.
|
|
25791
26801
|
--help, -h Show this help
|
|
25792
26802
|
|
|
25793
26803
|
Exit codes:
|
|
@@ -26103,7 +27113,7 @@ var HttpServerError = class extends Error {
|
|
|
26103
27113
|
this.code = code;
|
|
26104
27114
|
}
|
|
26105
27115
|
};
|
|
26106
|
-
function
|
|
27116
|
+
function createServer2(handler, options = {}) {
|
|
26107
27117
|
const server = createHttpServer(handler);
|
|
26108
27118
|
const preferredPort = options.port;
|
|
26109
27119
|
let port = null;
|
|
@@ -26175,7 +27185,7 @@ function createServer3(handler, options = {}) {
|
|
|
26175
27185
|
// packages/cli/src/server/routes.ts
|
|
26176
27186
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
26177
27187
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
26178
|
-
import { resolve as resolve2 } from "node:path";
|
|
27188
|
+
import { dirname as dirname6, isAbsolute as isAbsolute5, resolve as resolve2 } from "node:path";
|
|
26179
27189
|
|
|
26180
27190
|
// packages/dry-run/dist/node/index.js
|
|
26181
27191
|
function parseTestUrl(input) {
|
|
@@ -26470,6 +27480,18 @@ function dryRunProject(operations, cases, options) {
|
|
|
26470
27480
|
}
|
|
26471
27481
|
};
|
|
26472
27482
|
}
|
|
27483
|
+
function mockPreviewSummary(mock) {
|
|
27484
|
+
const parts = [];
|
|
27485
|
+
parts.push(mock.body !== void 0 ? "inline body" : "file-backed body");
|
|
27486
|
+
const headerCount = mock.headers?.length ?? 0;
|
|
27487
|
+
if (headerCount > 0) {
|
|
27488
|
+
parts.push(headerCount === 1 ? "1 header" : `${headerCount} headers`);
|
|
27489
|
+
}
|
|
27490
|
+
if (mock.delayMs !== void 0) {
|
|
27491
|
+
parts.push(`${mock.delayMs} ms delay`);
|
|
27492
|
+
}
|
|
27493
|
+
return `Mock ${mock.status} (${parts.join(", ")})`;
|
|
27494
|
+
}
|
|
26473
27495
|
function captureSubject(matcher, url) {
|
|
26474
27496
|
if (matcher.source.key === "url") return url;
|
|
26475
27497
|
try {
|
|
@@ -26517,9 +27539,82 @@ function previewRuleAction(operation, url) {
|
|
|
26517
27539
|
summary: expand(operation.responseBody.body)
|
|
26518
27540
|
};
|
|
26519
27541
|
}
|
|
27542
|
+
if (operation.kind === "mock") {
|
|
27543
|
+
return {
|
|
27544
|
+
kind: "mock",
|
|
27545
|
+
summary: mockPreviewSummary(operation.mock)
|
|
27546
|
+
};
|
|
27547
|
+
}
|
|
26520
27548
|
return null;
|
|
26521
27549
|
}
|
|
26522
27550
|
|
|
27551
|
+
// packages/cli/src/mock-root-config.ts
|
|
27552
|
+
import { mkdir as mkdir3, readFile as readFile3, realpath as realpath3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
27553
|
+
import { homedir } from "node:os";
|
|
27554
|
+
import { dirname as dirname5, isAbsolute as isAbsolute4, join as join6, resolve } from "node:path";
|
|
27555
|
+
function mockRootConfigPath(env = process.env) {
|
|
27556
|
+
const base = env.ROGATIO_CONFIG_DIR ?? join6(homedir(), ".config", "rogatio");
|
|
27557
|
+
return join6(base, "mock-roots.json");
|
|
27558
|
+
}
|
|
27559
|
+
async function canonicalProjectPath(filePath) {
|
|
27560
|
+
const absolute = resolve(filePath);
|
|
27561
|
+
try {
|
|
27562
|
+
return await realpath3(absolute);
|
|
27563
|
+
} catch {
|
|
27564
|
+
return absolute;
|
|
27565
|
+
}
|
|
27566
|
+
}
|
|
27567
|
+
async function readMap(env) {
|
|
27568
|
+
let raw;
|
|
27569
|
+
try {
|
|
27570
|
+
raw = await readFile3(mockRootConfigPath(env), "utf8");
|
|
27571
|
+
} catch {
|
|
27572
|
+
return {};
|
|
27573
|
+
}
|
|
27574
|
+
let parsed;
|
|
27575
|
+
try {
|
|
27576
|
+
parsed = JSON.parse(raw);
|
|
27577
|
+
} catch {
|
|
27578
|
+
return {};
|
|
27579
|
+
}
|
|
27580
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
27581
|
+
return {};
|
|
27582
|
+
}
|
|
27583
|
+
const projects = parsed.projects;
|
|
27584
|
+
if (typeof projects !== "object" || projects === null || Array.isArray(projects)) {
|
|
27585
|
+
return {};
|
|
27586
|
+
}
|
|
27587
|
+
const map = {};
|
|
27588
|
+
for (const key of Object.keys(projects)) {
|
|
27589
|
+
const value = projects[key];
|
|
27590
|
+
if (typeof value === "string" && isAbsolute4(value)) map[key] = value;
|
|
27591
|
+
}
|
|
27592
|
+
return map;
|
|
27593
|
+
}
|
|
27594
|
+
async function writeMap(map, env) {
|
|
27595
|
+
const path2 = mockRootConfigPath(env);
|
|
27596
|
+
await mkdir3(dirname5(path2), { recursive: true });
|
|
27597
|
+
const temporary = `${path2}.${process.pid}.tmp`;
|
|
27598
|
+
await writeFile3(
|
|
27599
|
+
temporary,
|
|
27600
|
+
`${JSON.stringify({ projects: map }, null, 2)}
|
|
27601
|
+
`,
|
|
27602
|
+
"utf8"
|
|
27603
|
+
);
|
|
27604
|
+
await rename2(temporary, path2);
|
|
27605
|
+
}
|
|
27606
|
+
async function readSavedMockRoot(filePath, env = process.env) {
|
|
27607
|
+
const key = await canonicalProjectPath(filePath);
|
|
27608
|
+
return (await readMap(env))[key];
|
|
27609
|
+
}
|
|
27610
|
+
async function writeSavedMockRoot(filePath, root, env = process.env) {
|
|
27611
|
+
const key = await canonicalProjectPath(filePath);
|
|
27612
|
+
const map = await readMap(env);
|
|
27613
|
+
if (root === null || root.length === 0) delete map[key];
|
|
27614
|
+
else map[key] = root;
|
|
27615
|
+
await writeMap(map, env);
|
|
27616
|
+
}
|
|
27617
|
+
|
|
26523
27618
|
// packages/cli/src/server/routes.ts
|
|
26524
27619
|
function generateCsrfToken() {
|
|
26525
27620
|
return randomBytes3(16).toString("hex");
|
|
@@ -26758,6 +27853,60 @@ function createRoutes(context) {
|
|
|
26758
27853
|
res.end(JSON.stringify({ diagnostics }));
|
|
26759
27854
|
return;
|
|
26760
27855
|
}
|
|
27856
|
+
if (pathname === "/api/mock-root" && method === "GET") {
|
|
27857
|
+
const saved = await readSavedMockRoot(context.filePath);
|
|
27858
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
27859
|
+
res.end(
|
|
27860
|
+
JSON.stringify({
|
|
27861
|
+
root: saved ?? dirname6(context.filePath),
|
|
27862
|
+
saved: saved !== void 0
|
|
27863
|
+
})
|
|
27864
|
+
);
|
|
27865
|
+
return;
|
|
27866
|
+
}
|
|
27867
|
+
if (pathname === "/api/mock-root" && method === "POST") {
|
|
27868
|
+
if (!validateCsrf(req, context.csrfToken)) {
|
|
27869
|
+
res.writeHead(403, { "Content-Type": "application/json" });
|
|
27870
|
+
res.end(
|
|
27871
|
+
JSON.stringify({
|
|
27872
|
+
code: "csrf-invalid",
|
|
27873
|
+
message: "Invalid CSRF token"
|
|
27874
|
+
})
|
|
27875
|
+
);
|
|
27876
|
+
return;
|
|
27877
|
+
}
|
|
27878
|
+
let body;
|
|
27879
|
+
try {
|
|
27880
|
+
body = JSON.parse(await getRequestBody(req));
|
|
27881
|
+
} catch (error) {
|
|
27882
|
+
const failure2 = bodyErrorResponse(error);
|
|
27883
|
+
res.writeHead(failure2.status, { "Content-Type": "application/json" });
|
|
27884
|
+
res.end(JSON.stringify(failure2.body));
|
|
27885
|
+
return;
|
|
27886
|
+
}
|
|
27887
|
+
const root = typeof body === "object" && body !== null && "root" in body ? body.root : void 0;
|
|
27888
|
+
if (root !== null && (typeof root !== "string" || root !== "" && !isAbsolute5(root))) {
|
|
27889
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
27890
|
+
res.end(
|
|
27891
|
+
JSON.stringify({
|
|
27892
|
+
code: "invalid-root",
|
|
27893
|
+
message: "Mock file root must be an absolute path or null"
|
|
27894
|
+
})
|
|
27895
|
+
);
|
|
27896
|
+
return;
|
|
27897
|
+
}
|
|
27898
|
+
await writeSavedMockRoot(context.filePath, root);
|
|
27899
|
+
const saved = await readSavedMockRoot(context.filePath);
|
|
27900
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
27901
|
+
res.end(
|
|
27902
|
+
JSON.stringify({
|
|
27903
|
+
ok: true,
|
|
27904
|
+
root: saved ?? dirname6(context.filePath),
|
|
27905
|
+
saved: saved !== void 0
|
|
27906
|
+
})
|
|
27907
|
+
);
|
|
27908
|
+
return;
|
|
27909
|
+
}
|
|
26761
27910
|
if (pathname === "/api/save" && method === "POST") {
|
|
26762
27911
|
if (!validateCsrf(req, context.csrfToken)) {
|
|
26763
27912
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
@@ -27119,12 +28268,12 @@ function createRoutes(context) {
|
|
|
27119
28268
|
}
|
|
27120
28269
|
|
|
27121
28270
|
// packages/cli/src/utils/asset-paths.ts
|
|
27122
|
-
import { dirname as
|
|
28271
|
+
import { dirname as dirname7, resolve as resolve3 } from "node:path";
|
|
27123
28272
|
import { fileURLToPath } from "node:url";
|
|
27124
|
-
function isDistBuild(here =
|
|
28273
|
+
function isDistBuild(here = dirname7(fileURLToPath(import.meta.url))) {
|
|
27125
28274
|
return here.includes("/dist/") || here.includes("\\dist\\");
|
|
27126
28275
|
}
|
|
27127
|
-
function editorAssetPaths(here =
|
|
28276
|
+
function editorAssetPaths(here = dirname7(fileURLToPath(import.meta.url))) {
|
|
27128
28277
|
const editorRoot = isDistBuild(here) ? resolve3(here, "..", "editor") : resolve3(here, "..", "..", "..", "editor", "dist", "browser");
|
|
27129
28278
|
return {
|
|
27130
28279
|
bundle: resolve3(editorRoot, "index.js"),
|
|
@@ -27134,7 +28283,7 @@ function editorAssetPaths(here = dirname5(fileURLToPath(import.meta.url))) {
|
|
|
27134
28283
|
}
|
|
27135
28284
|
|
|
27136
28285
|
// packages/cli/src/utils/browser.ts
|
|
27137
|
-
import { spawn as
|
|
28286
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
27138
28287
|
var BrowserLaunchError = class extends Error {
|
|
27139
28288
|
platform;
|
|
27140
28289
|
constructor(platform, message) {
|
|
@@ -27170,7 +28319,7 @@ async function launchBrowser(url) {
|
|
|
27170
28319
|
);
|
|
27171
28320
|
}
|
|
27172
28321
|
return new Promise((resolve10) => {
|
|
27173
|
-
const child =
|
|
28322
|
+
const child = spawn5(command, args, {
|
|
27174
28323
|
detached: true,
|
|
27175
28324
|
stdio: "ignore"
|
|
27176
28325
|
});
|
|
@@ -27192,15 +28341,15 @@ async function launchBrowser(url) {
|
|
|
27192
28341
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
27193
28342
|
import {
|
|
27194
28343
|
access,
|
|
27195
|
-
mkdir as
|
|
28344
|
+
mkdir as mkdir4,
|
|
27196
28345
|
readdir,
|
|
27197
28346
|
readFile as readFile5,
|
|
27198
|
-
rename as
|
|
27199
|
-
stat as
|
|
28347
|
+
rename as rename3,
|
|
28348
|
+
stat as stat2,
|
|
27200
28349
|
unlink as unlink2,
|
|
27201
|
-
writeFile as
|
|
28350
|
+
writeFile as writeFile4
|
|
27202
28351
|
} from "node:fs/promises";
|
|
27203
|
-
import { basename as basename2, dirname as
|
|
28352
|
+
import { basename as basename2, dirname as dirname8, join as join7 } from "node:path";
|
|
27204
28353
|
var ProjectStorageError = class extends Error {
|
|
27205
28354
|
code;
|
|
27206
28355
|
id;
|
|
@@ -27398,14 +28547,14 @@ async function readDocument(id2) {
|
|
|
27398
28547
|
}
|
|
27399
28548
|
async function isDirectoryPath(id2) {
|
|
27400
28549
|
try {
|
|
27401
|
-
return (await
|
|
28550
|
+
return (await stat2(id2)).isDirectory();
|
|
27402
28551
|
} catch {
|
|
27403
28552
|
return false;
|
|
27404
28553
|
}
|
|
27405
28554
|
}
|
|
27406
28555
|
async function writeDocument(id2, data) {
|
|
27407
|
-
const tempName = `.${basename2(
|
|
27408
|
-
const tempPath =
|
|
28556
|
+
const tempName = `.${basename2(dirname8(id2))}.${randomBytes4(8).toString("hex")}.tmp`;
|
|
28557
|
+
const tempPath = join7(dirname8(id2), tempName);
|
|
27409
28558
|
try {
|
|
27410
28559
|
if (await isDirectoryPath(id2)) {
|
|
27411
28560
|
throw new ProjectFileError(
|
|
@@ -27414,9 +28563,9 @@ async function writeDocument(id2, data) {
|
|
|
27414
28563
|
"Target path is a directory"
|
|
27415
28564
|
);
|
|
27416
28565
|
}
|
|
27417
|
-
await
|
|
27418
|
-
await
|
|
27419
|
-
await
|
|
28566
|
+
await mkdir4(dirname8(id2), { recursive: true });
|
|
28567
|
+
await writeFile4(tempPath, JSON.stringify(data, null, 2), "utf-8");
|
|
28568
|
+
await rename3(tempPath, id2);
|
|
27420
28569
|
} catch (e) {
|
|
27421
28570
|
if (e instanceof ProjectFileError) throw e;
|
|
27422
28571
|
try {
|
|
@@ -27464,7 +28613,7 @@ function createJsonFileProjectStorage() {
|
|
|
27464
28613
|
if (entry.isDirectory()) continue;
|
|
27465
28614
|
const named = isRogatioProjectFilename(entry.name);
|
|
27466
28615
|
if (!named && !isJsonFilename(entry.name)) continue;
|
|
27467
|
-
const id2 =
|
|
28616
|
+
const id2 = join7(scope, entry.name);
|
|
27468
28617
|
if (!named && !await isDiscoverableProjectFile(id2)) continue;
|
|
27469
28618
|
let name = "";
|
|
27470
28619
|
try {
|
|
@@ -27597,10 +28746,10 @@ async function editCommand(args, options = {}) {
|
|
|
27597
28746
|
filePath = resolve4(process.cwd(), ".rogatio.json");
|
|
27598
28747
|
}
|
|
27599
28748
|
try {
|
|
27600
|
-
const
|
|
28749
|
+
const stat3 = await import("node:fs/promises").then(
|
|
27601
28750
|
(fs2) => fs2.stat(filePath)
|
|
27602
28751
|
);
|
|
27603
|
-
if (
|
|
28752
|
+
if (stat3.isDirectory()) {
|
|
27604
28753
|
console.error("Error: Path is a directory");
|
|
27605
28754
|
return { exitCode: Promise.resolve(2), shutdown: () => {
|
|
27606
28755
|
} };
|
|
@@ -27665,7 +28814,7 @@ async function editCommand(args, options = {}) {
|
|
|
27665
28814
|
};
|
|
27666
28815
|
let server;
|
|
27667
28816
|
try {
|
|
27668
|
-
server =
|
|
28817
|
+
server = createServer2(
|
|
27669
28818
|
createRoutes(context),
|
|
27670
28819
|
port !== void 0 ? { port } : {}
|
|
27671
28820
|
);
|
|
@@ -27951,8 +29100,30 @@ function generateEditorHtml(apiBase, csrfToken, filePath, aiConfigured) {
|
|
|
27951
29100
|
onCancel: () => {
|
|
27952
29101
|
cancel();
|
|
27953
29102
|
},
|
|
29103
|
+
projectActions: [
|
|
29104
|
+
{ command: 'set-mock-root', label: 'Set mock file root' },
|
|
29105
|
+
{ command: 'clear-mock-root', label: 'Clear mock file root' },
|
|
29106
|
+
],
|
|
27954
29107
|
${aiAssistHandler}
|
|
27955
29108
|
});
|
|
29109
|
+
document.addEventListener('click', (event) => {
|
|
29110
|
+
const target = event.target;
|
|
29111
|
+
if (!(target instanceof Element)) return;
|
|
29112
|
+
const command = target.closest('[data-command]')?.getAttribute('data-command');
|
|
29113
|
+
if (command !== 'set-mock-root' && command !== 'clear-mock-root') return;
|
|
29114
|
+
const root = command === 'clear-mock-root'
|
|
29115
|
+
? null
|
|
29116
|
+
: window.prompt('Mock file root');
|
|
29117
|
+
if (command === 'set-mock-root' && root === null) return;
|
|
29118
|
+
void fetch(apiBase + '/api/mock-root', {
|
|
29119
|
+
method: 'POST',
|
|
29120
|
+
headers: {
|
|
29121
|
+
'Content-Type': 'application/json',
|
|
29122
|
+
'X-CSRF-Token': csrfToken,
|
|
29123
|
+
},
|
|
29124
|
+
body: JSON.stringify({ root }),
|
|
29125
|
+
});
|
|
29126
|
+
});
|
|
27956
29127
|
void editor;
|
|
27957
29128
|
} catch (error) {
|
|
27958
29129
|
const parts = [];
|
|
@@ -28064,16 +29235,16 @@ function readFilters(source) {
|
|
|
28064
29235
|
};
|
|
28065
29236
|
}
|
|
28066
29237
|
if (Object.hasOwn(entry, "resourceType")) {
|
|
28067
|
-
const
|
|
28068
|
-
if (!
|
|
28069
|
-
resourceTypes = intersect(resourceTypes,
|
|
28070
|
-
changes.push(...
|
|
29238
|
+
const read2 = readResourceTypes(entry.resourceType);
|
|
29239
|
+
if (!read2.ok) return read2;
|
|
29240
|
+
resourceTypes = intersect(resourceTypes, read2.values);
|
|
29241
|
+
changes.push(...read2.changes);
|
|
28071
29242
|
}
|
|
28072
29243
|
if (Object.hasOwn(entry, "requestMethod")) {
|
|
28073
|
-
const
|
|
28074
|
-
if (!
|
|
28075
|
-
methods = intersect(methods,
|
|
28076
|
-
changes.push(...
|
|
29244
|
+
const read2 = readMethods(entry.requestMethod);
|
|
29245
|
+
if (!read2.ok) return read2;
|
|
29246
|
+
methods = intersect(methods, read2.values);
|
|
29247
|
+
changes.push(...read2.changes);
|
|
28077
29248
|
}
|
|
28078
29249
|
}
|
|
28079
29250
|
if (resourceTypes !== void 0 && resourceTypes.length === 0) {
|
|
@@ -30019,20 +31190,8 @@ function errorMessage(error) {
|
|
|
30019
31190
|
}
|
|
30020
31191
|
|
|
30021
31192
|
// packages/cli/src/commands/runtime.ts
|
|
30022
|
-
import { chmod, mkdir as
|
|
30023
|
-
import { dirname as
|
|
30024
|
-
function toMatcherOperations(operations) {
|
|
30025
|
-
return operations.map(
|
|
30026
|
-
({ groupId, ruleId, name, matcher, redactSensitiveInLogs }) => ({
|
|
30027
|
-
kind: "matcher",
|
|
30028
|
-
groupId,
|
|
30029
|
-
ruleId,
|
|
30030
|
-
name,
|
|
30031
|
-
matcher,
|
|
30032
|
-
redactSensitiveInLogs
|
|
30033
|
-
})
|
|
30034
|
-
);
|
|
30035
|
-
}
|
|
31193
|
+
import { chmod, mkdir as mkdir5, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
|
|
31194
|
+
import { dirname as dirname9, join as join8, resolve as resolve6 } from "node:path";
|
|
30036
31195
|
function generateHostWrapper(rogatioCommand, logPath) {
|
|
30037
31196
|
const parts = rogatioCommand.split(" ");
|
|
30038
31197
|
const nodeBin = parts[0] ?? "node";
|
|
@@ -30046,13 +31205,13 @@ exec "${nodeBin}" "${cliScript}" runtime host 2>>"${logPath}"
|
|
|
30046
31205
|
`;
|
|
30047
31206
|
}
|
|
30048
31207
|
async function writeHostWrapper(hostPath, installRoot) {
|
|
30049
|
-
await
|
|
30050
|
-
const logPath =
|
|
31208
|
+
await mkdir5(installRoot, { recursive: true });
|
|
31209
|
+
const logPath = join8(installRoot, "runtime-host.log");
|
|
30051
31210
|
const script = generateHostWrapper(
|
|
30052
31211
|
`${process.execPath} ${process.argv[1] ?? "rogatio"}`,
|
|
30053
31212
|
logPath
|
|
30054
31213
|
);
|
|
30055
|
-
await
|
|
31214
|
+
await writeFile5(hostPath, script, "utf8");
|
|
30056
31215
|
await chmod(hostPath, 493);
|
|
30057
31216
|
}
|
|
30058
31217
|
function makeTrustController() {
|
|
@@ -30062,7 +31221,7 @@ function makeTrustController() {
|
|
|
30062
31221
|
return createRequestBodyTrustController({
|
|
30063
31222
|
platform,
|
|
30064
31223
|
installRoot,
|
|
30065
|
-
hostPath:
|
|
31224
|
+
hostPath: join8(installRoot, "runtime-host"),
|
|
30066
31225
|
hostName: "com.rogatio.runtime",
|
|
30067
31226
|
allowedOrigins: [],
|
|
30068
31227
|
manifestDir: adapter.defaultManifestDir(),
|
|
@@ -30131,7 +31290,7 @@ async function trustRuntimeCommand(args) {
|
|
|
30131
31290
|
}
|
|
30132
31291
|
const controller = makeTrustController();
|
|
30133
31292
|
const installRoot = defaultTrustInstallRoot(process.platform);
|
|
30134
|
-
const hostPath =
|
|
31293
|
+
const hostPath = join8(installRoot, "runtime-host");
|
|
30135
31294
|
switch (subcommand) {
|
|
30136
31295
|
case "install": {
|
|
30137
31296
|
const installResult = await controller.install(extensionId);
|
|
@@ -30159,7 +31318,7 @@ Note: reload the extension at chrome://extensions for the native host to be dete
|
|
|
30159
31318
|
} catch {
|
|
30160
31319
|
}
|
|
30161
31320
|
try {
|
|
30162
|
-
await rm2(
|
|
31321
|
+
await rm2(join8(installRoot, "runtime-host.log"), { force: true });
|
|
30163
31322
|
} catch {
|
|
30164
31323
|
}
|
|
30165
31324
|
return reportTrust(
|
|
@@ -30229,7 +31388,6 @@ allowed_origins includes chrome-extension://${extensionId}/`
|
|
|
30229
31388
|
}
|
|
30230
31389
|
async function runtimeHostCommand(args, options = {}) {
|
|
30231
31390
|
let root;
|
|
30232
|
-
let mockPort;
|
|
30233
31391
|
const positional = [];
|
|
30234
31392
|
let argumentError;
|
|
30235
31393
|
for (let index = 0; index < args.length; index += 1) {
|
|
@@ -30238,15 +31396,6 @@ async function runtimeHostCommand(args, options = {}) {
|
|
|
30238
31396
|
root = resolve6(args[++index]);
|
|
30239
31397
|
} else if (arg === "--root") {
|
|
30240
31398
|
argumentError = "--root requires a value";
|
|
30241
|
-
} else if (arg === "--mock-port" && index + 1 < args.length) {
|
|
30242
|
-
const parsed = Number(args[++index]);
|
|
30243
|
-
if (!Number.isInteger(parsed) || parsed <= 0 || parsed > 65535) {
|
|
30244
|
-
argumentError = "--mock-port must be an integer port in 1..65535";
|
|
30245
|
-
} else {
|
|
30246
|
-
mockPort = parsed;
|
|
30247
|
-
}
|
|
30248
|
-
} else if (arg === "--mock-port") {
|
|
30249
|
-
argumentError = "--mock-port requires a value";
|
|
30250
31399
|
} else if (arg === "-" || !arg.startsWith("-")) {
|
|
30251
31400
|
positional.push(arg);
|
|
30252
31401
|
} else {
|
|
@@ -30262,7 +31411,6 @@ async function runtimeHostCommand(args, options = {}) {
|
|
|
30262
31411
|
const aiProviderConfig2 = await readProviderConfig();
|
|
30263
31412
|
await runNativeHost({
|
|
30264
31413
|
fileRoot: root,
|
|
30265
|
-
...mockPort !== void 0 ? { mockPort } : {},
|
|
30266
31414
|
...aiProviderConfig2 !== null ? { aiProviderConfig: aiProviderConfig2 } : {},
|
|
30267
31415
|
aiConfigReader: readProviderConfig,
|
|
30268
31416
|
onReady: () => console.error(
|
|
@@ -30276,12 +31424,18 @@ async function runtimeHostCommand(args, options = {}) {
|
|
|
30276
31424
|
const storage = options.storage ?? createJsonFileProjectStorage();
|
|
30277
31425
|
try {
|
|
30278
31426
|
if (inputPath === "-") {
|
|
30279
|
-
const chunks = [];
|
|
30280
|
-
for await (const chunk of process.stdin) {
|
|
30281
|
-
chunks.push(typeof chunk === "string" ? chunk : chunk.toString("utf8"));
|
|
30282
|
-
}
|
|
30283
31427
|
filePath = "<stdin>";
|
|
30284
|
-
|
|
31428
|
+
if (options.stdinInput !== void 0) {
|
|
31429
|
+
projectData = JSON.parse(options.stdinInput);
|
|
31430
|
+
} else {
|
|
31431
|
+
const chunks = [];
|
|
31432
|
+
for await (const chunk of process.stdin) {
|
|
31433
|
+
chunks.push(
|
|
31434
|
+
typeof chunk === "string" ? chunk : chunk.toString("utf8")
|
|
31435
|
+
);
|
|
31436
|
+
}
|
|
31437
|
+
projectData = JSON.parse(chunks.join(""));
|
|
31438
|
+
}
|
|
30285
31439
|
} else {
|
|
30286
31440
|
filePath = resolve6(inputPath);
|
|
30287
31441
|
projectData = await storage.get(filePath);
|
|
@@ -30309,12 +31463,22 @@ async function runtimeHostCommand(args, options = {}) {
|
|
|
30309
31463
|
}
|
|
30310
31464
|
return 1;
|
|
30311
31465
|
}
|
|
30312
|
-
const
|
|
31466
|
+
const fileMock = compileResult.operations.some(
|
|
31467
|
+
(operation) => operation.kind === "mock" && operation.mock.file !== void 0
|
|
31468
|
+
);
|
|
31469
|
+
if (inputPath === "-" && fileMock && root === void 0) {
|
|
31470
|
+
console.error("Error: runtime.root-required");
|
|
31471
|
+
return 2;
|
|
31472
|
+
}
|
|
31473
|
+
const savedRoot = root === void 0 && inputPath !== "-" ? await readSavedMockRoot(filePath) : void 0;
|
|
31474
|
+
const rootDir = root ?? savedRoot ?? (inputPath === "-" ? void 0 : dirname9(filePath));
|
|
31475
|
+
const mocks = mocksFromOperations(compileResult.operations, void 0);
|
|
30313
31476
|
const normalized = normalizeRuntimePreset({
|
|
30314
31477
|
version: 1,
|
|
30315
31478
|
limits: RUNTIME_LIMITS,
|
|
30316
|
-
matchers:
|
|
30317
|
-
grants: []
|
|
31479
|
+
matchers: matchersFromOperations(compileResult.operations),
|
|
31480
|
+
grants: [],
|
|
31481
|
+
...mocks.length > 0 ? { mocks } : {}
|
|
30318
31482
|
});
|
|
30319
31483
|
if (!normalized.ok) {
|
|
30320
31484
|
console.error("Error: Failed to build runtime preset");
|
|
@@ -30323,8 +31487,7 @@ async function runtimeHostCommand(args, options = {}) {
|
|
|
30323
31487
|
const aiProviderConfig = await readProviderConfig();
|
|
30324
31488
|
await runNativeHost({
|
|
30325
31489
|
preset: normalized.value,
|
|
30326
|
-
fileRoot: rootDir,
|
|
30327
|
-
...mockPort !== void 0 ? { mockPort } : {},
|
|
31490
|
+
...rootDir !== void 0 ? { fileRoot: rootDir } : {},
|
|
30328
31491
|
...aiProviderConfig !== null ? { aiProviderConfig } : {},
|
|
30329
31492
|
aiConfigReader: readProviderConfig,
|
|
30330
31493
|
onReady: () => console.error("rogatio runtime-host active")
|
|
@@ -30754,7 +31917,7 @@ async function verifyCommand(args, stdinInput, captureOutput = false, options =
|
|
|
30754
31917
|
}
|
|
30755
31918
|
|
|
30756
31919
|
// packages/cli/src/index.ts
|
|
30757
|
-
var __dirname =
|
|
31920
|
+
var __dirname = dirname10(fileURLToPath2(import.meta.url));
|
|
30758
31921
|
var packageJsonPath = resolve9(
|
|
30759
31922
|
__dirname,
|
|
30760
31923
|
isDistBuild(__dirname) ? "../../package.json" : "../package.json"
|