@rogatio/cli 1.8.2 → 1.9.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.
@@ -14,6 +14,1160 @@ var __export = (target, all) => {
14
14
  __defProp(target, name, { get: all[name], enumerable: true });
15
15
  };
16
16
 
17
+ // packages/schema/dist/node/index.js
18
+ import { Ajv2020 } from "ajv/dist/2020.js";
19
+ function hasControl(value) {
20
+ for (let index = 0; index < value.length; index += 1) {
21
+ const code = value.charCodeAt(index);
22
+ if (code <= 31 || code === 127) return true;
23
+ }
24
+ return false;
25
+ }
26
+ function formatSha256(hex) {
27
+ return `sha256:${hex}`;
28
+ }
29
+ function isSha256Digest(value) {
30
+ return /^sha256:[0-9a-f]{64}$/.test(value);
31
+ }
32
+ function isForbiddenHeader(name, direction) {
33
+ const normalized = name.toLowerCase();
34
+ const forbidden = direction === "request" ? FORBIDDEN_REQUEST_HEADERS : FORBIDDEN_RESPONSE_HEADERS;
35
+ return forbidden.includes(normalized) || direction === "request" && FORBIDDEN_REQUEST_PREFIXES.some(
36
+ (prefix) => normalized.startsWith(prefix)
37
+ );
38
+ }
39
+ function normalizeSiteOrigin(value) {
40
+ if (typeof value !== "string" || value.length === 0 || value.trim() !== value)
41
+ return null;
42
+ if (value.includes("?") || value.includes("#")) return null;
43
+ const match = /^(https?):\/\/([^/?#\\\s]+)(\/)?$/i.exec(value);
44
+ if (!match || match[2].includes("@")) return null;
45
+ let url;
46
+ try {
47
+ url = new URL(value);
48
+ } catch {
49
+ return null;
50
+ }
51
+ if (url.protocol !== "http:" && url.protocol !== "https:") return null;
52
+ if (url.origin === "null" || url.hostname.length === 0) return null;
53
+ if (url.username.length > 0 || url.password.length > 0) return null;
54
+ if (url.hostname.includes("*")) return null;
55
+ if (url.hostname.endsWith(".")) return null;
56
+ if (url.pathname !== "/") return null;
57
+ return url.origin;
58
+ }
59
+ function isSiteOrigin(value) {
60
+ return typeof value === "string" && normalizeSiteOrigin(value) !== null;
61
+ }
62
+ function compileUrlRegex(value) {
63
+ if (typeof value !== "string" || value.length === 0 || value.length > LIMITS.maxUrlRegexLength)
64
+ return null;
65
+ try {
66
+ return new RegExp(value);
67
+ } catch {
68
+ return null;
69
+ }
70
+ }
71
+ function ajvIssues(errors) {
72
+ return (errors ?? []).map((error) => ({
73
+ instancePath: error.instancePath,
74
+ keyword: error.keyword,
75
+ message: error.message ?? "validation failed",
76
+ params: error.params
77
+ }));
78
+ }
79
+ function snapshotOwnData(value, ancestors = /* @__PURE__ */ new WeakSet()) {
80
+ if (value === null || typeof value !== "object") {
81
+ return { valid: true, value };
82
+ }
83
+ if (ancestors.has(value)) return { valid: false };
84
+ ancestors.add(value);
85
+ try {
86
+ if (Object.getOwnPropertySymbols(value).length > 0) {
87
+ return { valid: false };
88
+ }
89
+ if (Array.isArray(value)) {
90
+ const lengthDescriptor = Object.getOwnPropertyDescriptor(value, "length");
91
+ if (lengthDescriptor === void 0 || !("value" in lengthDescriptor) || !Number.isSafeInteger(lengthDescriptor.value) || lengthDescriptor.value < 0 || lengthDescriptor.value > LIMITS.maxRulesPerProject) {
92
+ return { valid: false };
93
+ }
94
+ const length = lengthDescriptor.value;
95
+ for (const propertyName of Object.getOwnPropertyNames(value)) {
96
+ if (propertyName === "length") continue;
97
+ const index = Number(propertyName);
98
+ if (!Number.isInteger(index) || index < 0 || index >= length || String(index) !== propertyName) {
99
+ return { valid: false };
100
+ }
101
+ }
102
+ const snapshot2 = new Array(length);
103
+ for (let index = 0; index < length; index += 1) {
104
+ const descriptor = Object.getOwnPropertyDescriptor(
105
+ value,
106
+ String(index)
107
+ );
108
+ if (descriptor === void 0 || !("value" in descriptor) || !descriptor.enumerable) {
109
+ return { valid: false };
110
+ }
111
+ const child = snapshotOwnData(descriptor.value, ancestors);
112
+ if (!child.valid) return child;
113
+ snapshot2[index] = child.value;
114
+ }
115
+ return { valid: true, value: snapshot2 };
116
+ }
117
+ const snapshot = /* @__PURE__ */ Object.create(null);
118
+ for (const key of Object.getOwnPropertyNames(value)) {
119
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
120
+ if (descriptor === void 0 || !("value" in descriptor) || !descriptor.enumerable) {
121
+ return { valid: false };
122
+ }
123
+ const child = snapshotOwnData(descriptor.value, ancestors);
124
+ if (!child.valid) return child;
125
+ Object.defineProperty(snapshot, key, {
126
+ configurable: true,
127
+ enumerable: true,
128
+ value: child.value,
129
+ writable: true
130
+ });
131
+ }
132
+ return { valid: true, value: snapshot };
133
+ } catch {
134
+ return { valid: false };
135
+ } finally {
136
+ ancestors.delete(value);
137
+ }
138
+ }
139
+ function semanticIssues(project) {
140
+ const issues = [];
141
+ const ids = /* @__PURE__ */ new Map();
142
+ let ruleCount = 0;
143
+ for (let groupIndex = 0; groupIndex < project.groups.length; groupIndex += 1) {
144
+ const group = project.groups[groupIndex];
145
+ const groupPath = `/groups/${groupIndex}`;
146
+ const existingGroup = ids.get(group.id);
147
+ if (existingGroup) {
148
+ issues.push({
149
+ instancePath: `${groupPath}/id`,
150
+ keyword: "uniqueId",
151
+ message: `must be unique; already used at ${existingGroup}`,
152
+ params: { previousPath: existingGroup }
153
+ });
154
+ } else {
155
+ ids.set(group.id, `${groupPath}/id`);
156
+ }
157
+ for (let ruleIndex = 0; ruleIndex < group.rules.length; ruleIndex += 1) {
158
+ let hasLoneSurrogate22 = function(value) {
159
+ for (let i = 0; i < value.length; i += 1) {
160
+ const code = value.charCodeAt(i);
161
+ if (code >= 55296 && code <= 56319) {
162
+ if (i + 1 >= value.length) return true;
163
+ const next = value.charCodeAt(i + 1);
164
+ if (next < 56320 || next > 57343) return true;
165
+ } else if (code >= 56320 && code <= 57343) {
166
+ if (i === 0) return true;
167
+ const prev = value.charCodeAt(i - 1);
168
+ if (prev < 55296 || prev > 56319) return true;
169
+ }
170
+ }
171
+ return false;
172
+ };
173
+ var hasLoneSurrogate3 = hasLoneSurrogate22;
174
+ const rule = group.rules[ruleIndex];
175
+ ruleCount += 1;
176
+ const rulePath = `${groupPath}/rules/${ruleIndex}`;
177
+ const existingRule = ids.get(rule.id);
178
+ if (existingRule) {
179
+ issues.push({
180
+ instancePath: `${rulePath}/id`,
181
+ keyword: "uniqueId",
182
+ message: `must be unique; already used at ${existingRule}`,
183
+ params: { previousPath: existingRule }
184
+ });
185
+ } else {
186
+ ids.set(rule.id, `${rulePath}/id`);
187
+ }
188
+ if (rule.type !== void 0 && rule.type !== "redirect" && rule.type !== "query" && rule.type !== "header" && rule.type !== "mock" && rule.type !== "response-body" && rule.type !== "request-body") {
189
+ issues.push({
190
+ instancePath: `${rulePath}/type`,
191
+ keyword: "enum",
192
+ message: 'must be "redirect", "query", "header", "mock", "response-body", or "request-body"',
193
+ params: {
194
+ allowedValues: [
195
+ "redirect",
196
+ "query",
197
+ "header",
198
+ "mock",
199
+ "response-body",
200
+ "request-body"
201
+ ]
202
+ }
203
+ });
204
+ }
205
+ if (rule.type === "redirect") {
206
+ const destination = rule.redirect !== void 0 ? rule.redirect.destination : void 0;
207
+ if (rule.redirect === void 0 || typeof destination !== "string") {
208
+ issues.push({
209
+ instancePath: `${rulePath}/redirect/destination`,
210
+ keyword: "required",
211
+ message: "Redirect rules require a destination string.",
212
+ params: {}
213
+ });
214
+ } else {
215
+ for (const issue of validateRedirectDestination(
216
+ destination,
217
+ rule.urlRegex
218
+ )) {
219
+ issues.push({
220
+ instancePath: `${rulePath}/redirect/destination`,
221
+ keyword: issue.code,
222
+ message: issue.message,
223
+ params: {}
224
+ });
225
+ }
226
+ }
227
+ }
228
+ const effectiveOrigins = /* @__PURE__ */ new Set();
229
+ for (let originIndex = 0; originIndex < group.origins.length; originIndex += 1) {
230
+ const origin = normalizeSiteOrigin(group.origins[originIndex]);
231
+ if (origin !== null) effectiveOrigins.add(origin);
232
+ }
233
+ for (let originIndex = 0; originIndex < rule.origins.length; originIndex += 1) {
234
+ const origin = normalizeSiteOrigin(rule.origins[originIndex]);
235
+ if (origin !== null) effectiveOrigins.add(origin);
236
+ }
237
+ if (effectiveOrigins.size === 0) {
238
+ issues.push({
239
+ instancePath: `${rulePath}/origins`,
240
+ keyword: "effectiveOrigin",
241
+ message: "must combine with group origins to contain at least one origin",
242
+ params: {}
243
+ });
244
+ }
245
+ const action = rule.action;
246
+ if (action && "type" in action && action.type === "query") {
247
+ const seenNames = /* @__PURE__ */ new Set();
248
+ for (let p = 0; p < action.params.length; p += 1) {
249
+ const param = action.params[p];
250
+ if (!param) continue;
251
+ const paramName = param.name;
252
+ if (seenNames.has(paramName)) {
253
+ issues.push({
254
+ instancePath: `${rulePath}/action/params/${p}/name`,
255
+ keyword: "uniqueQueryParamName",
256
+ message: `query param name must be unique; duplicate "${paramName}"`,
257
+ params: { name: paramName }
258
+ });
259
+ } else {
260
+ seenNames.add(paramName);
261
+ }
262
+ }
263
+ }
264
+ if (rule.type === "header" && rule.headerName !== void 0) {
265
+ const direction = rule.headerDirection ?? "request";
266
+ if (isForbiddenHeader(rule.headerName, direction)) {
267
+ issues.push({
268
+ instancePath: `${rulePath}/headerName`,
269
+ keyword: "forbiddenHeader",
270
+ message: `Header "${rule.headerName}" is forbidden for ${direction} headers.`,
271
+ params: {
272
+ headerName: rule.headerName,
273
+ headerDirection: direction
274
+ }
275
+ });
276
+ }
277
+ }
278
+ if (rule.type === "response-body") {
279
+ const action2 = rule.responseBody;
280
+ const actionPath = `${rulePath}/responseBody`;
281
+ if (!action2 || !Array.isArray(action2.replacements) || action2.replacements.length === 0) {
282
+ issues.push({
283
+ instancePath: `${actionPath}/replacements`,
284
+ keyword: "response-body-replacements",
285
+ message: "A response-body rule must define at least one replacement.",
286
+ params: {}
287
+ });
288
+ } else {
289
+ for (let index = 0; index < action2.replacements.length; index += 1) {
290
+ const replacement = action2.replacements[index];
291
+ if (compileUrlRegex(replacement.pattern) === null) {
292
+ issues.push({
293
+ instancePath: `${actionPath}/replacements/${index}/pattern`,
294
+ keyword: "response-body-pattern",
295
+ message: "Response-body replacement patterns must be valid regular expressions.",
296
+ params: {}
297
+ });
298
+ }
299
+ }
300
+ }
301
+ }
302
+ if (rule.type === "request-body") {
303
+ const action2 = rule.requestBody;
304
+ const actionPath = `${rulePath}/requestBody`;
305
+ if (!action2) {
306
+ issues.push({
307
+ instancePath: actionPath,
308
+ keyword: "request-body-action",
309
+ message: "A request-body rule must define a requestBody action.",
310
+ params: {}
311
+ });
312
+ } else {
313
+ const mode = action2.mode;
314
+ if (mode !== "replace" && mode !== "regex") {
315
+ issues.push({
316
+ instancePath: `${actionPath}/mode`,
317
+ keyword: "request-body-mode",
318
+ message: 'requestBody.mode must be "replace" or "regex"',
319
+ params: { mode }
320
+ });
321
+ }
322
+ if (action2.mode === "replace") {
323
+ if (typeof action2.body !== "string") {
324
+ issues.push({
325
+ instancePath: `${actionPath}/body`,
326
+ keyword: "request-body-replace-body",
327
+ message: "Replace mode requires a body string.",
328
+ params: {}
329
+ });
330
+ } else if (action2.body.length > LIMITS.maxRequestBodyBytes) {
331
+ issues.push({
332
+ instancePath: `${actionPath}/body`,
333
+ keyword: "request-body-replace-body",
334
+ message: `Replace body exceeds the maximum size of ${LIMITS.maxRequestBodyBytes} bytes.`,
335
+ params: { limit: LIMITS.maxRequestBodyBytes }
336
+ });
337
+ } else if (hasLoneSurrogate22(action2.body)) {
338
+ issues.push({
339
+ instancePath: `${actionPath}/body`,
340
+ keyword: "request-body-lone-surrogate",
341
+ message: "Replace body must not contain lone UTF-16 surrogates.",
342
+ params: {}
343
+ });
344
+ }
345
+ }
346
+ if (action2.mode === "regex") {
347
+ if (typeof action2.pattern !== "string" || action2.pattern.length === 0) {
348
+ issues.push({
349
+ instancePath: `${actionPath}/pattern`,
350
+ keyword: "request-body-pattern",
351
+ message: "Regex mode requires a non-empty pattern string.",
352
+ params: {}
353
+ });
354
+ } else if (action2.pattern.length > LIMITS.maxRequestBodyPatternLength) {
355
+ issues.push({
356
+ instancePath: `${actionPath}/pattern`,
357
+ keyword: "request-body-pattern",
358
+ message: `Regex pattern exceeds the maximum length of ${LIMITS.maxRequestBodyPatternLength} characters.`,
359
+ params: { limit: LIMITS.maxRequestBodyPatternLength }
360
+ });
361
+ } else if (compileUrlRegex(action2.pattern) === null) {
362
+ issues.push({
363
+ instancePath: `${actionPath}/pattern`,
364
+ keyword: "request-body-pattern",
365
+ message: "Regex pattern must be a valid regular expression.",
366
+ params: {}
367
+ });
368
+ }
369
+ if (typeof action2.replacement !== "string" || action2.replacement.length > LIMITS.maxRequestBodyReplacementLength) {
370
+ issues.push({
371
+ instancePath: `${actionPath}/replacement`,
372
+ keyword: "request-body-replacement",
373
+ message: `Regex replacement exceeds the maximum length of ${LIMITS.maxRequestBodyReplacementLength} characters.`,
374
+ params: { limit: LIMITS.maxRequestBodyReplacementLength }
375
+ });
376
+ } else if (hasLoneSurrogate22(action2.pattern)) {
377
+ issues.push({
378
+ instancePath: `${actionPath}/pattern`,
379
+ keyword: "request-body-lone-surrogate",
380
+ message: "Regex pattern must not contain lone UTF-16 surrogates.",
381
+ params: {}
382
+ });
383
+ } else if (hasLoneSurrogate22(action2.replacement)) {
384
+ issues.push({
385
+ instancePath: `${actionPath}/replacement`,
386
+ keyword: "request-body-lone-surrogate",
387
+ message: "Regex replacement must not contain lone UTF-16 surrogates.",
388
+ params: {}
389
+ });
390
+ }
391
+ }
392
+ }
393
+ if (rule.method !== "POST" && rule.method !== "PUT" && rule.method !== "PATCH") {
394
+ issues.push({
395
+ instancePath: `${rulePath}/method`,
396
+ keyword: "request-body-method",
397
+ message: 'Request-body rules require method "POST", "PUT", or "PATCH".',
398
+ params: { method: rule.method }
399
+ });
400
+ }
401
+ const resourceTypes = rule.resourceTypes;
402
+ if (!Array.isArray(resourceTypes) || resourceTypes.length !== 1 || resourceTypes[0] !== "xmlhttprequest") {
403
+ issues.push({
404
+ instancePath: `${rulePath}/resourceTypes`,
405
+ keyword: "request-body-resource-types",
406
+ message: 'Request-body rules require exactly one resource type: "xmlhttprequest".',
407
+ params: { resourceTypes }
408
+ });
409
+ }
410
+ }
411
+ if (rule.type === "mock") {
412
+ const mock = rule.mock;
413
+ const mockPath = `${rulePath}/mock`;
414
+ const bodySet = mock?.body !== void 0;
415
+ const fileSet = mock?.file !== void 0;
416
+ if (bodySet === fileSet) {
417
+ issues.push({
418
+ instancePath: mockPath,
419
+ keyword: "mock-body-source",
420
+ message: "A mock rule must set exactly one of body or file.",
421
+ params: {}
422
+ });
423
+ }
424
+ if (mock?.headers !== void 0) {
425
+ for (let h = 0; h < mock.headers.length; h += 1) {
426
+ const header = mock.headers[h];
427
+ if (header === void 0) continue;
428
+ if (hasControl(header.name) || header.name.includes(":")) {
429
+ issues.push({
430
+ instancePath: `${mockPath}/headers/${h}/name`,
431
+ keyword: "mock-header-name",
432
+ message: "Mock header names must not contain control characters or ':'.",
433
+ params: {}
434
+ });
435
+ }
436
+ }
437
+ }
438
+ if (mock?.file !== void 0 && hasControl(mock.file)) {
439
+ issues.push({
440
+ instancePath: `${mockPath}/file`,
441
+ keyword: "mock-file-path",
442
+ message: "Mock file paths must not contain control characters.",
443
+ params: {}
444
+ });
445
+ }
446
+ }
447
+ }
448
+ }
449
+ if (project.requestBodyPolicy !== void 0) {
450
+ const policy = project.requestBodyPolicy;
451
+ if (typeof policy.localOrigins !== "undefined") {
452
+ if (!Array.isArray(policy.localOrigins)) {
453
+ issues.push({
454
+ instancePath: "/requestBodyPolicy/localOrigins",
455
+ keyword: "request-body-policy-local-origins",
456
+ message: "localOrigins must be an array.",
457
+ params: {}
458
+ });
459
+ } else {
460
+ const seen = /* @__PURE__ */ new Set();
461
+ for (let i = 0; i < policy.localOrigins.length; i += 1) {
462
+ const origin = policy.localOrigins[i];
463
+ if (typeof origin !== "string") {
464
+ issues.push({
465
+ instancePath: `/requestBodyPolicy/localOrigins/${i}`,
466
+ keyword: "request-body-policy-local-origin",
467
+ message: "Each local origin must be a string.",
468
+ params: {}
469
+ });
470
+ continue;
471
+ }
472
+ const normalized = normalizeSiteOrigin(origin);
473
+ if (normalized === null) {
474
+ issues.push({
475
+ instancePath: `/requestBodyPolicy/localOrigins/${i}`,
476
+ keyword: "request-body-policy-local-origin",
477
+ message: "Each local origin must be a valid exact HTTP(S) origin with no credentials, path, query, fragment, wildcard, backslash, invalid port, or trailing-dot hostname.",
478
+ params: { origin }
479
+ });
480
+ } else if (seen.has(normalized)) {
481
+ issues.push({
482
+ instancePath: `/requestBodyPolicy/localOrigins/${i}`,
483
+ keyword: "request-body-policy-local-origin",
484
+ message: "Local origins must be unique.",
485
+ params: { origin: normalized }
486
+ });
487
+ } else {
488
+ seen.add(normalized);
489
+ }
490
+ }
491
+ if (policy.localOrigins.length > LIMITS.maxLocalOrigins) {
492
+ issues.push({
493
+ instancePath: "/requestBodyPolicy/localOrigins",
494
+ keyword: "request-body-policy-local-origins",
495
+ message: `localOrigins must contain at most ${LIMITS.maxLocalOrigins} entries.`,
496
+ params: { limit: LIMITS.maxLocalOrigins }
497
+ });
498
+ }
499
+ }
500
+ }
501
+ }
502
+ if (ruleCount > LIMITS.maxRulesPerProject) {
503
+ issues.push({
504
+ instancePath: "/groups",
505
+ keyword: "maxRulesPerProject",
506
+ message: `must contain at most ${LIMITS.maxRulesPerProject} rules in total`,
507
+ params: { limit: LIMITS.maxRulesPerProject, actual: ruleCount }
508
+ });
509
+ }
510
+ return issues;
511
+ }
512
+ function skipBalancedGroup(source, start) {
513
+ let depth = 0;
514
+ let index = start;
515
+ const length = source.length;
516
+ while (index < length) {
517
+ const char = source[index];
518
+ if (char === "\\") {
519
+ index += 2;
520
+ continue;
521
+ }
522
+ if (char === "(") {
523
+ depth += 1;
524
+ } else if (char === ")") {
525
+ depth -= 1;
526
+ if (depth === 0) return index;
527
+ }
528
+ index += 1;
529
+ }
530
+ return length;
531
+ }
532
+ function countCapturingGroups(urlRegex) {
533
+ let count = 0;
534
+ let index = 0;
535
+ const length = urlRegex.length;
536
+ while (index < length) {
537
+ const char = urlRegex[index];
538
+ if (char === "\\") {
539
+ index += 2;
540
+ continue;
541
+ }
542
+ if (char === "(") {
543
+ if (urlRegex[index + 1] === "?") {
544
+ index = skipBalancedGroup(urlRegex, index);
545
+ continue;
546
+ }
547
+ count += 1;
548
+ }
549
+ index += 1;
550
+ }
551
+ return count;
552
+ }
553
+ function validateRedirectDestination(destination, urlRegex) {
554
+ const issues = [];
555
+ if (typeof destination !== "string" || destination.length === 0) {
556
+ issues.push({
557
+ code: "schema.required",
558
+ message: "Redirect destination must be a non-empty string."
559
+ });
560
+ return issues;
561
+ }
562
+ if (destination.length > LIMITS.maxRedirectDestinationLength) {
563
+ issues.push({
564
+ code: "schema.out-of-range",
565
+ message: `Redirect destination must be at most ${LIMITS.maxRedirectDestinationLength} characters.`
566
+ });
567
+ return issues;
568
+ }
569
+ let url;
570
+ try {
571
+ url = new URL(destination);
572
+ } catch {
573
+ issues.push({
574
+ code: "schema.invalid-format",
575
+ message: "Redirect destination must be an absolute URL."
576
+ });
577
+ return issues;
578
+ }
579
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
580
+ issues.push({
581
+ code: "schema.invalid-value",
582
+ message: "Redirect destination must use the http or https scheme."
583
+ });
584
+ return issues;
585
+ }
586
+ if (url.username.length > 0 || url.password.length > 0) {
587
+ issues.push({
588
+ code: "schema.invalid-value",
589
+ message: "Redirect destination must not contain credentials."
590
+ });
591
+ return issues;
592
+ }
593
+ if (url.hostname.length === 0 || url.hostname.includes("*")) {
594
+ issues.push({
595
+ code: "schema.invalid-format",
596
+ message: "Redirect destination must have a valid host."
597
+ });
598
+ return issues;
599
+ }
600
+ const groups = countCapturingGroups(urlRegex);
601
+ const backreference = /\\([1-9])/g;
602
+ let match = backreference.exec(destination);
603
+ while (match !== null) {
604
+ const referenced = Number(match[1]);
605
+ if (referenced > groups) {
606
+ issues.push({
607
+ code: "schema.invalid-value",
608
+ message: `Redirect destination references capture group ${referenced} but the URL pattern defines ${groups}.`
609
+ });
610
+ }
611
+ match = backreference.exec(destination);
612
+ }
613
+ return issues;
614
+ }
615
+ function validateProjectDetailed(value) {
616
+ const snapshot = snapshotOwnData(value);
617
+ if (!snapshot.valid) {
618
+ return {
619
+ valid: false,
620
+ errors: [
621
+ {
622
+ instancePath: "",
623
+ keyword: "ownProperties",
624
+ message: "must contain only own array entries",
625
+ params: {}
626
+ }
627
+ ]
628
+ };
629
+ }
630
+ if (!projectValidator(snapshot.value)) {
631
+ return { valid: false, errors: ajvIssues(projectValidator.errors) };
632
+ }
633
+ const errors = semanticIssues(snapshot.value);
634
+ return errors.length > 0 ? { valid: false, errors } : { valid: true, data: value };
635
+ }
636
+ var FORBIDDEN_REQUEST_HEADERS, FORBIDDEN_RESPONSE_HEADERS, FORBIDDEN_REQUEST_PREFIXES, LIMITS, PROJECT_VERSION, RESOURCE_TYPES, HTTP_METHODS, label, id, projectSchemaDefinition, projectSchema, ajv, compiledProjectValidator, ownArrayEntriesError, guardedProjectValidator, projectValidator;
637
+ var init_node = __esm({
638
+ "packages/schema/dist/node/index.js"() {
639
+ "use strict";
640
+ FORBIDDEN_REQUEST_HEADERS = Object.freeze([
641
+ "accept-charset",
642
+ "accept-encoding",
643
+ "access-control-request-headers",
644
+ "access-control-request-method",
645
+ "connection",
646
+ "content-length",
647
+ "cookie",
648
+ "cookie2",
649
+ "date",
650
+ "dnt",
651
+ "expect",
652
+ "host",
653
+ "keep-alive",
654
+ "origin",
655
+ "proxy-authenticate",
656
+ "proxy-authorization",
657
+ "te",
658
+ "trailer",
659
+ "transfer-encoding",
660
+ "upgrade",
661
+ "via"
662
+ ]);
663
+ FORBIDDEN_RESPONSE_HEADERS = Object.freeze([
664
+ "connection",
665
+ "content-encoding",
666
+ "content-length",
667
+ "date",
668
+ "keep-alive",
669
+ "proxy-authenticate",
670
+ "proxy-authorization",
671
+ "set-cookie",
672
+ "set-cookie2",
673
+ "te",
674
+ "trailer",
675
+ "transfer-encoding",
676
+ "upgrade",
677
+ "via"
678
+ ]);
679
+ FORBIDDEN_REQUEST_PREFIXES = Object.freeze(["proxy-", "sec-"]);
680
+ LIMITS = Object.freeze({
681
+ maxGroups: 64,
682
+ maxRulesPerGroup: 256,
683
+ maxRulesPerProject: 4096,
684
+ maxOriginsPerScope: 32,
685
+ maxIdLength: 64,
686
+ maxLabelLength: 100,
687
+ maxDescriptionLength: 1e3,
688
+ maxUrlRegexLength: 2048,
689
+ maxResourceTypesPerRule: 16,
690
+ minPriority: 1,
691
+ maxPriority: 1e3,
692
+ maxRedirectDestinationLength: 2048,
693
+ maxCaptureGroups: 9,
694
+ maxQueryParamsPerRule: 64,
695
+ maxQueryNameLength: 256,
696
+ maxQueryValueLength: 2048,
697
+ maxHeaderNameLength: 256,
698
+ maxHeaderValueLength: 4096,
699
+ minMockStatus: 200,
700
+ maxMockStatus: 599,
701
+ maxMockHeadersPerRule: 32,
702
+ maxMockHeaderNameLength: 256,
703
+ maxMockHeaderValueLength: 4096,
704
+ maxMockInlineBodyLength: 65536,
705
+ maxMockDelayMs: 3e4,
706
+ maxMockFilePathLength: 2048,
707
+ maxResponseBodyReplacements: 64,
708
+ maxResponseBodyPatternLength: 2048,
709
+ maxResponseBodyReplacementLength: 4096,
710
+ maxRequestBodyBytes: 4 * 1024 * 1024,
711
+ maxRequestBodyPatternLength: 2048,
712
+ maxRequestBodyReplacementLength: 4096,
713
+ maxRequestBodyOperations: 32,
714
+ maxLocalOrigins: 32
715
+ });
716
+ PROJECT_VERSION = 1;
717
+ RESOURCE_TYPES = Object.freeze([
718
+ "main_frame",
719
+ "sub_frame",
720
+ "stylesheet",
721
+ "script",
722
+ "image",
723
+ "font",
724
+ "object",
725
+ "media",
726
+ "xmlhttprequest",
727
+ "ping",
728
+ "csp_report",
729
+ "websocket",
730
+ "webtransport",
731
+ "webbundle",
732
+ "other"
733
+ ]);
734
+ HTTP_METHODS = Object.freeze([
735
+ "GET",
736
+ "POST",
737
+ "PUT",
738
+ "PATCH",
739
+ "DELETE",
740
+ "HEAD",
741
+ "OPTIONS",
742
+ "CONNECT",
743
+ "TRACE"
744
+ ]);
745
+ label = {
746
+ type: "string",
747
+ minLength: 1,
748
+ maxLength: LIMITS.maxLabelLength,
749
+ pattern: "\\S"
750
+ };
751
+ id = {
752
+ type: "string",
753
+ minLength: 1,
754
+ maxLength: LIMITS.maxIdLength,
755
+ pattern: "^[A-Za-z0-9][A-Za-z0-9._-]*$"
756
+ };
757
+ projectSchemaDefinition = {
758
+ $schema: "https://json-schema.org/draft/2020-12/schema",
759
+ $id: "https://rogatio.dev/schema/project-v1.json",
760
+ type: "object",
761
+ additionalProperties: false,
762
+ required: ["version", "name", "groups"],
763
+ properties: {
764
+ version: { type: "integer", const: PROJECT_VERSION },
765
+ name: label,
766
+ description: {
767
+ type: "string",
768
+ maxLength: LIMITS.maxDescriptionLength
769
+ },
770
+ groups: {
771
+ type: "array",
772
+ maxItems: LIMITS.maxGroups,
773
+ items: { $ref: "#/$defs/group" }
774
+ },
775
+ requestBodyPolicy: { $ref: "#/$defs/requestBodyPolicyConfig" }
776
+ },
777
+ $defs: {
778
+ group: {
779
+ type: "object",
780
+ additionalProperties: false,
781
+ required: ["id", "name", "origins", "rules"],
782
+ properties: {
783
+ id,
784
+ name: label,
785
+ origins: {
786
+ type: "array",
787
+ maxItems: LIMITS.maxOriginsPerScope,
788
+ uniqueItems: true,
789
+ items: { type: "string", format: "rogatio-origin" }
790
+ },
791
+ rules: {
792
+ type: "array",
793
+ maxItems: LIMITS.maxRulesPerGroup,
794
+ items: { $ref: "#/$defs/rule" }
795
+ }
796
+ }
797
+ },
798
+ rule: {
799
+ type: "object",
800
+ additionalProperties: false,
801
+ required: [
802
+ "id",
803
+ "name",
804
+ "urlRegex",
805
+ "origins",
806
+ "resourceTypes",
807
+ "priority"
808
+ ],
809
+ properties: {
810
+ id,
811
+ name: label,
812
+ urlRegex: {
813
+ type: "string",
814
+ minLength: 1,
815
+ maxLength: LIMITS.maxUrlRegexLength,
816
+ format: "rogatio-url-regex"
817
+ },
818
+ origins: {
819
+ type: "array",
820
+ maxItems: LIMITS.maxOriginsPerScope,
821
+ uniqueItems: true,
822
+ items: { type: "string", format: "rogatio-origin" }
823
+ },
824
+ resourceTypes: {
825
+ type: "array",
826
+ minItems: 1,
827
+ maxItems: LIMITS.maxResourceTypesPerRule,
828
+ uniqueItems: true,
829
+ items: { type: "string", enum: [...RESOURCE_TYPES] }
830
+ },
831
+ priority: {
832
+ type: "integer",
833
+ minimum: LIMITS.minPriority,
834
+ maximum: LIMITS.maxPriority
835
+ },
836
+ method: { type: "string", enum: [...HTTP_METHODS] },
837
+ type: {
838
+ type: "string",
839
+ enum: [
840
+ "redirect",
841
+ "query",
842
+ "header",
843
+ "mock",
844
+ "response-body",
845
+ "request-body"
846
+ ]
847
+ },
848
+ redirect: {
849
+ type: "object",
850
+ additionalProperties: false,
851
+ required: ["destination"],
852
+ properties: {
853
+ destination: { type: "string" }
854
+ }
855
+ },
856
+ action: { $ref: "#/$defs/queryAction" },
857
+ headerDirection: { type: "string", enum: ["request", "response"] },
858
+ headerOperation: { type: "string", enum: ["set", "append", "remove"] },
859
+ headerName: {
860
+ type: "string",
861
+ minLength: 1,
862
+ maxLength: LIMITS.maxHeaderNameLength
863
+ },
864
+ headerValue: {
865
+ type: "string",
866
+ maxLength: LIMITS.maxHeaderValueLength
867
+ },
868
+ mock: { $ref: "#/$defs/mockAction" },
869
+ responseBody: { $ref: "#/$defs/responseBodyAction" },
870
+ requestBody: { $ref: "#/$defs/requestBodyAction" }
871
+ },
872
+ allOf: [
873
+ {
874
+ if: {
875
+ required: ["type"],
876
+ properties: { type: { const: "redirect" } }
877
+ },
878
+ // biome-ignore lint/suspicious/noThenProperty: AJV conditional schema keyword
879
+ then: {
880
+ required: ["redirect"]
881
+ }
882
+ },
883
+ {
884
+ if: {
885
+ required: ["type"],
886
+ properties: { type: { const: "query" } }
887
+ },
888
+ // biome-ignore lint/suspicious/noThenProperty: AJV conditional schema keyword
889
+ then: {
890
+ required: ["action"]
891
+ }
892
+ },
893
+ {
894
+ if: {
895
+ required: ["type"],
896
+ properties: { type: { const: "header" } }
897
+ },
898
+ // biome-ignore lint/suspicious/noThenProperty: AJV conditional schema keyword
899
+ then: {
900
+ required: ["headerDirection", "headerOperation", "headerName"]
901
+ }
902
+ },
903
+ {
904
+ if: {
905
+ required: ["type"],
906
+ properties: { type: { const: "mock" } }
907
+ },
908
+ // biome-ignore lint/suspicious/noThenProperty: AJV conditional schema keyword
909
+ then: {
910
+ required: ["mock"]
911
+ }
912
+ },
913
+ {
914
+ if: {
915
+ required: ["type"],
916
+ properties: { type: { const: "response-body" } }
917
+ },
918
+ // biome-ignore lint/suspicious/noThenProperty: AJV conditional schema keyword
919
+ then: {
920
+ required: ["responseBody"]
921
+ }
922
+ },
923
+ {
924
+ if: {
925
+ required: ["headerOperation"],
926
+ properties: { headerOperation: { const: "set" } }
927
+ },
928
+ // biome-ignore lint/suspicious/noThenProperty: AJV conditional schema keyword
929
+ then: {
930
+ required: ["headerValue"]
931
+ }
932
+ },
933
+ {
934
+ if: {
935
+ required: ["headerOperation"],
936
+ properties: { headerOperation: { const: "append" } }
937
+ },
938
+ // biome-ignore lint/suspicious/noThenProperty: AJV conditional schema keyword
939
+ then: {
940
+ required: ["headerValue"]
941
+ }
942
+ },
943
+ {
944
+ if: {
945
+ required: ["type"],
946
+ properties: { type: { const: "response-body" } }
947
+ },
948
+ // biome-ignore lint/suspicious/noThenProperty: AJV conditional schema keyword
949
+ then: {
950
+ required: ["responseBody"]
951
+ }
952
+ },
953
+ {
954
+ if: {
955
+ required: ["type"],
956
+ properties: { type: { const: "request-body" } }
957
+ },
958
+ // biome-ignore lint/suspicious/noThenProperty: AJV conditional schema keyword
959
+ then: {
960
+ required: ["requestBody", "method", "resourceTypes"]
961
+ }
962
+ }
963
+ ]
964
+ },
965
+ queryParam: {
966
+ type: "object",
967
+ additionalProperties: false,
968
+ required: ["name", "value"],
969
+ properties: {
970
+ name: {
971
+ type: "string",
972
+ minLength: 1,
973
+ maxLength: LIMITS.maxQueryNameLength
974
+ },
975
+ value: {
976
+ type: "string",
977
+ minLength: 1,
978
+ maxLength: LIMITS.maxQueryValueLength
979
+ }
980
+ }
981
+ },
982
+ queryAction: {
983
+ type: "object",
984
+ additionalProperties: false,
985
+ required: ["type", "params"],
986
+ properties: {
987
+ type: { const: "query" },
988
+ params: {
989
+ type: "array",
990
+ minItems: 1,
991
+ maxItems: LIMITS.maxQueryParamsPerRule,
992
+ items: { $ref: "#/$defs/queryParam" }
993
+ }
994
+ }
995
+ },
996
+ mockHeader: {
997
+ type: "object",
998
+ additionalProperties: false,
999
+ required: ["name", "value"],
1000
+ properties: {
1001
+ name: {
1002
+ type: "string",
1003
+ minLength: 1,
1004
+ maxLength: LIMITS.maxMockHeaderNameLength
1005
+ },
1006
+ value: {
1007
+ type: "string",
1008
+ maxLength: LIMITS.maxMockHeaderValueLength
1009
+ }
1010
+ }
1011
+ },
1012
+ mockAction: {
1013
+ type: "object",
1014
+ additionalProperties: false,
1015
+ required: ["status"],
1016
+ properties: {
1017
+ status: {
1018
+ type: "integer",
1019
+ minimum: LIMITS.minMockStatus,
1020
+ maximum: LIMITS.maxMockStatus
1021
+ },
1022
+ headers: {
1023
+ type: "array",
1024
+ maxItems: LIMITS.maxMockHeadersPerRule,
1025
+ items: { $ref: "#/$defs/mockHeader" }
1026
+ },
1027
+ delayMs: {
1028
+ type: "integer",
1029
+ minimum: 0,
1030
+ maximum: LIMITS.maxMockDelayMs
1031
+ },
1032
+ body: {
1033
+ type: "string",
1034
+ maxLength: LIMITS.maxMockInlineBodyLength
1035
+ },
1036
+ file: {
1037
+ type: "string",
1038
+ minLength: 1,
1039
+ maxLength: LIMITS.maxMockFilePathLength
1040
+ }
1041
+ }
1042
+ },
1043
+ responseBodyReplacement: {
1044
+ type: "object",
1045
+ additionalProperties: false,
1046
+ required: ["pattern", "replacement"],
1047
+ properties: {
1048
+ pattern: {
1049
+ type: "string",
1050
+ minLength: 1,
1051
+ maxLength: LIMITS.maxResponseBodyPatternLength,
1052
+ format: "rogatio-url-regex"
1053
+ },
1054
+ replacement: {
1055
+ type: "string",
1056
+ maxLength: LIMITS.maxResponseBodyReplacementLength
1057
+ }
1058
+ }
1059
+ },
1060
+ responseBodyAction: {
1061
+ type: "object",
1062
+ additionalProperties: false,
1063
+ required: ["replacements"],
1064
+ properties: {
1065
+ replacements: {
1066
+ type: "array",
1067
+ minItems: 1,
1068
+ maxItems: LIMITS.maxResponseBodyReplacements,
1069
+ items: { $ref: "#/$defs/responseBodyReplacement" }
1070
+ }
1071
+ }
1072
+ },
1073
+ requestBodyReplaceAction: {
1074
+ type: "object",
1075
+ additionalProperties: false,
1076
+ required: ["mode", "body"],
1077
+ properties: {
1078
+ mode: { const: "replace" },
1079
+ body: {
1080
+ type: "string",
1081
+ maxLength: LIMITS.maxRequestBodyBytes
1082
+ }
1083
+ }
1084
+ },
1085
+ requestBodyRegexAction: {
1086
+ type: "object",
1087
+ additionalProperties: false,
1088
+ required: ["mode", "pattern", "replacement"],
1089
+ properties: {
1090
+ mode: { const: "regex" },
1091
+ pattern: {
1092
+ type: "string",
1093
+ minLength: 1,
1094
+ maxLength: LIMITS.maxRequestBodyPatternLength,
1095
+ format: "rogatio-url-regex"
1096
+ },
1097
+ replacement: {
1098
+ type: "string",
1099
+ maxLength: LIMITS.maxRequestBodyReplacementLength
1100
+ }
1101
+ }
1102
+ },
1103
+ requestBodyAction: {
1104
+ oneOf: [
1105
+ { $ref: "#/$defs/requestBodyReplaceAction" },
1106
+ { $ref: "#/$defs/requestBodyRegexAction" }
1107
+ ]
1108
+ },
1109
+ requestBodyPolicyConfig: {
1110
+ type: "object",
1111
+ additionalProperties: false,
1112
+ properties: {
1113
+ localOrigins: {
1114
+ type: "array",
1115
+ maxItems: LIMITS.maxLocalOrigins,
1116
+ uniqueItems: true,
1117
+ items: { type: "string", format: "rogatio-origin" }
1118
+ }
1119
+ }
1120
+ }
1121
+ }
1122
+ };
1123
+ projectSchema = projectSchemaDefinition;
1124
+ ajv = new Ajv2020({
1125
+ allErrors: true,
1126
+ coerceTypes: false,
1127
+ removeAdditional: false,
1128
+ useDefaults: false,
1129
+ ownProperties: true,
1130
+ // The redirect `then` clause requires `redirect` via `if/then` while the
1131
+ // property is declared on the enclosing rule, which strictRequired forbids.
1132
+ strictRequired: false
1133
+ });
1134
+ ajv.addFormat("rogatio-origin", {
1135
+ type: "string",
1136
+ validate: isSiteOrigin
1137
+ });
1138
+ ajv.addFormat("rogatio-url-regex", {
1139
+ type: "string",
1140
+ validate: (value) => compileUrlRegex(value) !== null
1141
+ });
1142
+ compiledProjectValidator = ajv.compile(projectSchema);
1143
+ ownArrayEntriesError = {
1144
+ instancePath: "",
1145
+ keyword: "ownProperties",
1146
+ message: "must contain only own array entries",
1147
+ params: {},
1148
+ schemaPath: ""
1149
+ };
1150
+ guardedProjectValidator = Object.assign(
1151
+ (value) => {
1152
+ const snapshot = snapshotOwnData(value);
1153
+ if (!snapshot.valid) {
1154
+ guardedProjectValidator.errors = [ownArrayEntriesError];
1155
+ return false;
1156
+ }
1157
+ const valid = compiledProjectValidator(snapshot.value);
1158
+ guardedProjectValidator.errors = compiledProjectValidator.errors ?? null;
1159
+ return valid;
1160
+ },
1161
+ {
1162
+ errors: null,
1163
+ schema: compiledProjectValidator.schema,
1164
+ schemaEnv: compiledProjectValidator.schemaEnv
1165
+ }
1166
+ );
1167
+ projectValidator = guardedProjectValidator;
1168
+ }
1169
+ });
1170
+
17
1171
  // packages/runtime/dist/node/index.js
18
1172
  var node_exports = {};
19
1173
  __export(node_exports, {
@@ -88,42 +1242,22 @@ __export(node_exports, {
88
1242
  verifyMarker: () => verifyMarker
89
1243
  });
90
1244
  import { isIP } from "node:net";
91
- import { HTTP_METHODS as HTTP_METHODS2 } from "@rogatio/schema";
92
- import { hasControl } from "@rogatio/schema";
93
1245
  import { isIP as isIP2 } from "node:net";
94
- import { hasControl as hasControl2, normalizeSiteOrigin } from "@rogatio/schema";
95
1246
  import { constants } from "node:fs";
96
1247
  import { realpath } from "node:fs/promises";
97
1248
  import { isAbsolute, relative } from "node:path";
98
1249
  import { Buffer as Buffer2 } from "node:buffer";
99
1250
  import { createServer as createServer2 } from "node:http";
100
1251
  import { createHash, randomBytes as randomBytes3, timingSafeEqual } from "node:crypto";
101
- import { isSha256Digest } from "@rogatio/schema";
102
- import { normalizeSiteOrigin as normalizeSiteOrigin2 } from "@rogatio/schema";
103
1252
  import { randomBytes as randomBytes22 } from "node:crypto";
104
1253
  import { readFile as readFile3, realpath as realpath2, stat } from "node:fs/promises";
105
- import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve3, sep } from "node:path";
1254
+ import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve4, sep } from "node:path";
106
1255
  import { lookup as dnsLookup } from "node:dns/promises";
107
1256
  import { request as httpRequest } from "node:http";
108
1257
  import { request as httpsRequest } from "node:https";
109
1258
  import { createHash as createHash2 } from "node:crypto";
110
- import {
111
- compileUrlRegex as compileUrlRegex2,
112
- HTTP_METHODS as HTTP_METHODS22,
113
- hasControl as hasControl3,
114
- LIMITS,
115
- normalizeSiteOrigin as normalizeSiteOrigin3,
116
- RESOURCE_TYPES as RESOURCE_TYPES2
117
- } from "@rogatio/schema";
118
1259
  import { createHash as createHash3 } from "node:crypto";
119
- import { formatSha256 } from "@rogatio/schema";
120
1260
  import { Worker } from "node:worker_threads";
121
- import { LIMITS as LIMITS2 } from "@rogatio/schema";
122
- import { LIMITS as LIMITS3 } from "@rogatio/schema";
123
- import {
124
- compileUrlRegex as compileUrlRegex22,
125
- normalizeSiteOrigin as normalizeSiteOrigin4
126
- } from "@rogatio/schema";
127
1261
  import {
128
1262
  createPrivateKey,
129
1263
  createSign,
@@ -132,7 +1266,7 @@ import {
132
1266
  } from "node:crypto";
133
1267
  import { readFileSync } from "node:fs";
134
1268
  import { mkdir as mkdir2, readFile as readFile22, rename as rename2, rm, stat as stat2, writeFile as writeFile2 } from "node:fs/promises";
135
- import { basename as basename3, dirname as dirname2, isAbsolute as isAbsolute3, join as join2, relative as relative3 } from "node:path";
1269
+ import { basename as basename3, dirname as dirname3, isAbsolute as isAbsolute3, join as join2, relative as relative3 } from "node:path";
136
1270
  import { generateKeyPairSync as generateKeyPairSync2 } from "node:crypto";
137
1271
  function parseIPv4(value) {
138
1272
  const parts = value.split(".");
@@ -284,7 +1418,7 @@ function normalizeLogicalPath(value) {
284
1418
  }
285
1419
  return parts.join("/");
286
1420
  }
287
- function snapshotOwnData(value, ancestors = /* @__PURE__ */ new WeakSet()) {
1421
+ function snapshotOwnData3(value, ancestors = /* @__PURE__ */ new WeakSet()) {
288
1422
  if (value === null || typeof value !== "object") {
289
1423
  return { valid: true, value };
290
1424
  }
@@ -316,7 +1450,7 @@ function snapshotOwnData(value, ancestors = /* @__PURE__ */ new WeakSet()) {
316
1450
  if (descriptor === void 0 || !("value" in descriptor) || !descriptor.enumerable) {
317
1451
  return { valid: false };
318
1452
  }
319
- const child = snapshotOwnData(descriptor.value, ancestors);
1453
+ const child = snapshotOwnData3(descriptor.value, ancestors);
320
1454
  if (!child.valid) return child;
321
1455
  snapshot2[index] = child.value;
322
1456
  }
@@ -330,7 +1464,7 @@ function snapshotOwnData(value, ancestors = /* @__PURE__ */ new WeakSet()) {
330
1464
  if (descriptor === void 0 || !("value" in descriptor) || !descriptor.enumerable) {
331
1465
  return { valid: false };
332
1466
  }
333
- const child = snapshotOwnData(descriptor.value, ancestors);
1467
+ const child = snapshotOwnData3(descriptor.value, ancestors);
334
1468
  if (!child.valid) return child;
335
1469
  Object.defineProperty(snapshot, key, {
336
1470
  configurable: true,
@@ -381,11 +1515,11 @@ function validHostname(hostname) {
381
1515
  if (unbracketed.includes("%") || unbracketed.endsWith(".")) return false;
382
1516
  if (isIP2(unbracketed) !== 0) return true;
383
1517
  if (unbracketed.length === 0 || unbracketed.length > 253) return false;
384
- return unbracketed.split(".").every((label) => ID_PATTERN.test(label));
1518
+ return unbracketed.split(".").every((label2) => ID_PATTERN.test(label2));
385
1519
  }
386
1520
  function canonicalizeOutboundTarget(value) {
387
1521
  if (typeof value !== "string" || value.length === 0) return null;
388
- if (value.trim() !== value || hasControl2(value)) return null;
1522
+ if (value.trim() !== value || hasControl(value)) return null;
389
1523
  if (value.includes("\\") || value.includes("#")) return null;
390
1524
  if (!hasValidPercentEncoding(value)) return null;
391
1525
  if (/%(?:2f|2F|5c|5C)/.test(value)) return null;
@@ -422,13 +1556,13 @@ function isOriginAllowed(target, origins) {
422
1556
  return origin !== null && origins.includes(origin);
423
1557
  }
424
1558
  function validMethod(value) {
425
- return typeof value === "string" && HTTP_METHODS2.includes(value);
1559
+ return typeof value === "string" && HTTP_METHODS.includes(value);
426
1560
  }
427
1561
  function validId(value) {
428
1562
  return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(value);
429
1563
  }
430
1564
  function exactDescriptor(value) {
431
- const snapshot = snapshotOwnData(value);
1565
+ const snapshot = snapshotOwnData3(value);
432
1566
  if (!snapshot.valid || snapshot.value === null || typeof snapshot.value !== "object" || Array.isArray(snapshot.value))
433
1567
  return null;
434
1568
  const record = snapshot.value;
@@ -755,7 +1889,7 @@ function generatePacScript(origins, endpoint, options) {
755
1889
  }
756
1890
  const valid = [];
757
1891
  for (const origin of origins) {
758
- const normalized = normalizeSiteOrigin2(origin);
1892
+ const normalized = normalizeSiteOrigin(origin);
759
1893
  if (normalized !== null) valid.push(normalized);
760
1894
  }
761
1895
  const unique = Array.from(new Set(valid)).sort();
@@ -927,7 +2061,7 @@ async function readMockFile(root, logicalPath) {
927
2061
  if (normalized === null) return failure("runtime.file-denied");
928
2062
  try {
929
2063
  const canonicalRoot = await realpath2(root);
930
- const candidate = resolve3(canonicalRoot, ...normalized.split("/"));
2064
+ const candidate = resolve4(canonicalRoot, ...normalized.split("/"));
931
2065
  const actualPath = await realpath2(candidate);
932
2066
  if (!withinRoot2(canonicalRoot, actualPath))
933
2067
  return failure("runtime.file-denied");
@@ -1839,14 +2973,14 @@ function validId2(value) {
1839
2973
  return typeof value === "string" && ID_PATTERN2.test(value);
1840
2974
  }
1841
2975
  function validMethod2(value) {
1842
- return typeof value === "string" && HTTP_METHODS22.includes(value);
2976
+ return typeof value === "string" && HTTP_METHODS.includes(value);
1843
2977
  }
1844
2978
  function normalizeMockHeader(value) {
1845
2979
  if (value === null || typeof value !== "object" || Array.isArray(value))
1846
2980
  return null;
1847
2981
  if (!exactKeys(value, ["name", "value"])) return null;
1848
2982
  const record = value;
1849
- if (typeof record.name !== "string" || record.name.length === 0 || record.name.length > LIMITS.maxMockHeaderNameLength || hasControl3(record.name) || record.name.includes(":"))
2983
+ if (typeof record.name !== "string" || record.name.length === 0 || record.name.length > LIMITS.maxMockHeaderNameLength || hasControl(record.name) || record.name.includes(":"))
1850
2984
  return null;
1851
2985
  if (typeof record.value !== "string" || record.value.length > LIMITS.maxMockHeaderValueLength)
1852
2986
  return null;
@@ -1894,7 +3028,7 @@ function normalizeMockConfig(value, matcherById) {
1894
3028
  if (bodySet === fileSet) return null;
1895
3029
  if (bodySet && body.length > LIMITS.maxMockInlineBodyLength) return null;
1896
3030
  if (fileSet) {
1897
- if (file.length === 0 || file.length > LIMITS.maxMockFilePathLength || hasControl3(file))
3031
+ if (file.length === 0 || file.length > LIMITS.maxMockFilePathLength || hasControl(file))
1898
3032
  return null;
1899
3033
  }
1900
3034
  return Object.freeze({
@@ -1907,7 +3041,7 @@ function normalizeMockConfig(value, matcherById) {
1907
3041
  });
1908
3042
  }
1909
3043
  function validResourceType(value) {
1910
- return typeof value === "string" && RESOURCE_TYPES2.includes(value);
3044
+ return typeof value === "string" && RESOURCE_TYPES.includes(value);
1911
3045
  }
1912
3046
  function freezeMatcher(operation) {
1913
3047
  const matcher = Object.freeze({
@@ -1959,14 +3093,14 @@ function normalizeMatcher(value) {
1959
3093
  return null;
1960
3094
  }
1961
3095
  const regex = regexValue;
1962
- if (typeof regex.source !== "string" || regex.source.length > LIMITS.maxUrlRegexLength || regex.flags !== "" || compileUrlRegex2(regex.source) === null) {
3096
+ if (typeof regex.source !== "string" || regex.source.length > LIMITS.maxUrlRegexLength || regex.flags !== "" || compileUrlRegex(regex.source) === null) {
1963
3097
  return null;
1964
3098
  }
1965
3099
  if (!Array.isArray(matcher.origins) || matcher.origins.length === 0 || matcher.origins.length > LIMITS.maxOriginsPerScope)
1966
3100
  return null;
1967
3101
  const origins = [];
1968
3102
  for (const value2 of matcher.origins) {
1969
- const normalized = normalizeSiteOrigin3(value2);
3103
+ const normalized = normalizeSiteOrigin(value2);
1970
3104
  if (normalized === null || origins.includes(normalized)) return null;
1971
3105
  origins.push(normalized);
1972
3106
  }
@@ -1978,7 +3112,7 @@ function normalizeMatcher(value) {
1978
3112
  resourceTypes.push(value2);
1979
3113
  }
1980
3114
  resourceTypes.sort(
1981
- (left, right) => RESOURCE_TYPES2.indexOf(left) - RESOURCE_TYPES2.indexOf(right)
3115
+ (left, right) => RESOURCE_TYPES.indexOf(left) - RESOURCE_TYPES.indexOf(right)
1982
3116
  );
1983
3117
  if (typeof matcher.priority !== "number" || !Number.isSafeInteger(matcher.priority) || matcher.priority < LIMITS.minPriority || matcher.priority > LIMITS.maxPriority)
1984
3118
  return null;
@@ -2052,7 +3186,7 @@ function makeGrant(value, matcherById) {
2052
3186
  });
2053
3187
  }
2054
3188
  function normalizeRuntimePreset(value) {
2055
- const snapshot = snapshotOwnData(value);
3189
+ const snapshot = snapshotOwnData3(value);
2056
3190
  if (!snapshot.valid || snapshot.value === null || typeof snapshot.value !== "object" || Array.isArray(snapshot.value)) {
2057
3191
  return failure("runtime.invalid-preset");
2058
3192
  }
@@ -2540,10 +3674,10 @@ async function rewriteRequestBody(input, action) {
2540
3674
  if (action.pattern.length === 0) {
2541
3675
  return failure("runtime.request-body-regex-missing-pattern");
2542
3676
  }
2543
- if (action.pattern.length > LIMITS2.maxRequestBodyPatternLength) {
3677
+ if (action.pattern.length > LIMITS.maxRequestBodyPatternLength) {
2544
3678
  return failure("runtime.request-body-regex-pattern-too-large");
2545
3679
  }
2546
- if (action.replacement.length > LIMITS2.maxRequestBodyReplacementLength) {
3680
+ if (action.replacement.length > LIMITS.maxRequestBodyReplacementLength) {
2547
3681
  return failure("runtime.request-body-regex-replacement-too-large");
2548
3682
  }
2549
3683
  if (hasLoneSurrogate2(action.replacement)) {
@@ -2588,7 +3722,7 @@ async function rewriteResponseBody(input, replacements) {
2588
3722
  return failure("runtime.size-limit");
2589
3723
  if (input.contentEncoding !== void 0 && input.contentEncoding !== "identity")
2590
3724
  return failure("runtime.size-limit");
2591
- if (input.body.byteLength > RUNTIME_LIMITS.maxResponseBodyBytes || replacements.length === 0 || replacements.length > LIMITS3.maxResponseBodyReplacements)
3725
+ if (input.body.byteLength > RUNTIME_LIMITS.maxResponseBodyBytes || replacements.length === 0 || replacements.length > LIMITS.maxResponseBodyReplacements)
2592
3726
  return failure("runtime.size-limit");
2593
3727
  let text;
2594
3728
  try {
@@ -2598,7 +3732,7 @@ async function rewriteResponseBody(input, replacements) {
2598
3732
  }
2599
3733
  try {
2600
3734
  for (const entry of replacements) {
2601
- if (entry.pattern.length === 0 || entry.pattern.length > LIMITS3.maxResponseBodyPatternLength || entry.replacement.length > LIMITS3.maxResponseBodyReplacementLength)
3735
+ if (entry.pattern.length === 0 || entry.pattern.length > LIMITS.maxResponseBodyPatternLength || entry.replacement.length > LIMITS.maxResponseBodyReplacementLength)
2602
3736
  return failure("runtime.size-limit");
2603
3737
  const regex = new RegExp(entry.pattern, "gu");
2604
3738
  text = text.replace(regex, entry.replacement);
@@ -2643,10 +3777,10 @@ async function fetchAndRewriteAuthorizedResponse(operation, replacements, option
2643
3777
  };
2644
3778
  }
2645
3779
  function originOf(value) {
2646
- const direct = normalizeSiteOrigin4(value);
3780
+ const direct = normalizeSiteOrigin(value);
2647
3781
  if (direct !== null) return direct;
2648
3782
  try {
2649
- return normalizeSiteOrigin4(new URL(value).origin);
3783
+ return normalizeSiteOrigin(new URL(value).origin);
2650
3784
  } catch {
2651
3785
  return null;
2652
3786
  }
@@ -2658,11 +3792,11 @@ function projectHasRule(project, groupId, ruleId) {
2658
3792
  return group.rules.some((rule) => rule.id === ruleId);
2659
3793
  }
2660
3794
  function revalidateAuthority(project, operations, request) {
2661
- const projectSnap = snapshotOwnData(project);
3795
+ const projectSnap = snapshotOwnData3(project);
2662
3796
  if (!projectSnap.valid) return { allowed: false, reason: "project-invalid" };
2663
- const opsSnap = snapshotOwnData(operations);
3797
+ const opsSnap = snapshotOwnData3(operations);
2664
3798
  if (!opsSnap.valid) return { allowed: false, reason: "project-invalid" };
2665
- const reqSnap = snapshotOwnData(request);
3799
+ const reqSnap = snapshotOwnData3(request);
2666
3800
  if (!reqSnap.valid) return { allowed: false, reason: "project-invalid" };
2667
3801
  const operation = operations.find(
2668
3802
  (candidate) => candidate.groupId === request.groupId && candidate.ruleId === request.ruleId && "matcher" in candidate
@@ -2678,7 +3812,7 @@ function revalidateAuthority(project, operations, request) {
2678
3812
  return { allowed: false, reason: "project-inconsistent" };
2679
3813
  }
2680
3814
  const matcher = operation.matcher;
2681
- const regex = compileUrlRegex22(matcher.urlRegex.source);
3815
+ const regex = compileUrlRegex(matcher.urlRegex.source);
2682
3816
  if (regex === null || !regex.test(request.url)) {
2683
3817
  return { allowed: false, reason: "url-mismatch" };
2684
3818
  }
@@ -2858,7 +3992,7 @@ function isWellFormedManifest(value) {
2858
3992
  return typeof m.name === "string" && typeof m.path === "string" && m.type === "stdio" && Array.isArray(m.allowed_origins) && m.allowed_origins.every((o) => typeof o === "string");
2859
3993
  }
2860
3994
  async function writeFileAtomic(path, data) {
2861
- const dir = dirname2(path);
3995
+ const dir = dirname3(path);
2862
3996
  await mkdir2(dir, { recursive: true });
2863
3997
  const tmp = join2(dir, `.${basename3(path)}.${process.pid}.tmp`);
2864
3998
  await writeFile2(tmp, data, "utf8");
@@ -3025,9 +4159,19 @@ function createRequestBodyTrustController(options = {}) {
3025
4159
  return { install, uninstall, trust, untrust, status };
3026
4160
  }
3027
4161
  var MAX_ARRAY_LENGTH, MAX_OBJECT_PROPERTIES, ID_PATTERN, RUNTIME_LIMITS, RUNTIME_PROTOCOL, PROTOCOL, ENVELOPE_MAX_BYTES, MAX_PAC_ORIGINS, MAX_CONCURRENT_TRANSFORMS, REVALIDATION_INTERVAL_MS, FORBIDDEN_BODY_KEYS, MOCK_BODY_KEY, MOCK_BODY_ALLOWED_TYPES, ENVELOPE_MESSAGE_TYPES, EnvelopeError, TOKEN_BYTES, TOKEN_LENGTH, registeredProvider, currentSession, NATIVE_FRAME_MAX_BYTES, NATIVE_POLICY_MAX_BYTES, NATIVE_POLICY_MAX_FRAMES, NATIVE_POLICY_STAGE_TIMEOUT_MS, NativeFrameType, defaultResolver, defaultTransport, ID_PATTERN2, PRIVATE_RANGES, SUPPORTED_MIME_TYPES, SUPPORTED_MIME_PREFIXES, FORBIDDEN_HEADERS, FORBIDDEN_CONTENT_ENCODINGS, RESERVED_MARKER_PREFIX, MARKER_SEPARATOR, pendingAuths, cachedContext, TRUST_LIMITS, TrustError, ORIGIN_RE, DEFAULT_CAPABILITIES;
3028
- var init_node = __esm({
4162
+ var init_node2 = __esm({
3029
4163
  "packages/runtime/dist/node/index.js"() {
3030
4164
  "use strict";
4165
+ init_node();
4166
+ init_node();
4167
+ init_node();
4168
+ init_node();
4169
+ init_node();
4170
+ init_node();
4171
+ init_node();
4172
+ init_node();
4173
+ init_node();
4174
+ init_node();
3031
4175
  MAX_ARRAY_LENGTH = 4096;
3032
4176
  MAX_OBJECT_PROPERTIES = 256;
3033
4177
  ID_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
@@ -3227,12 +4371,11 @@ var init_node = __esm({
3227
4371
 
3228
4372
  // packages/cli/src/index.ts
3229
4373
  import { realpathSync } from "node:fs";
3230
- import { basename as basename4, dirname as dirname4, resolve as resolve7 } from "node:path";
4374
+ import { basename as basename4, dirname as dirname5, resolve as resolve8 } from "node:path";
3231
4375
  import { fileURLToPath as fileURLToPath2 } from "node:url";
3232
4376
 
3233
4377
  // packages/cli/src/commands/edit.ts
3234
- import { resolve as resolve2 } from "node:path";
3235
- import { fileURLToPath } from "node:url";
4378
+ import { resolve as resolve3 } from "node:path";
3236
4379
 
3237
4380
  // packages/cli/src/server/http.ts
3238
4381
  import { randomInt } from "node:crypto";
@@ -3253,11 +4396,11 @@ function createServer(handler, options = {}) {
3253
4396
  let port = null;
3254
4397
  let started = false;
3255
4398
  async function listenOn(candidatePort) {
3256
- await new Promise((resolve8, reject) => {
4399
+ await new Promise((resolve9, reject) => {
3257
4400
  server.once("error", reject);
3258
4401
  server.listen(candidatePort, "127.0.0.1", () => {
3259
4402
  server.off("error", reject);
3260
- resolve8();
4403
+ resolve9();
3261
4404
  });
3262
4405
  });
3263
4406
  }
@@ -3312,8 +4455,8 @@ function createServer(handler, options = {}) {
3312
4455
  },
3313
4456
  async stop() {
3314
4457
  if (!started) return;
3315
- await new Promise((resolve8) => {
3316
- server.close(() => resolve8());
4458
+ await new Promise((resolve9) => {
4459
+ server.close(() => resolve9());
3317
4460
  });
3318
4461
  started = false;
3319
4462
  }
@@ -3324,10 +4467,360 @@ function createServer(handler, options = {}) {
3324
4467
  import { randomBytes } from "node:crypto";
3325
4468
  import { readFile } from "node:fs/promises";
3326
4469
  import { resolve } from "node:path";
3327
- import { compileProject } from "@rogatio/compiler";
4470
+
4471
+ // packages/compiler/dist/node/index.js
4472
+ init_node();
4473
+ init_node();
4474
+ var ISSUE_CODES = {
4475
+ required: "schema.required",
4476
+ additionalProperties: "schema.unknown-property",
4477
+ type: "schema.invalid-type",
4478
+ format: "schema.invalid-format",
4479
+ const: "schema.invalid-value",
4480
+ enum: "schema.invalid-value",
4481
+ pattern: "schema.invalid-value",
4482
+ minLength: "schema.out-of-range",
4483
+ maxLength: "schema.out-of-range",
4484
+ minItems: "schema.out-of-range",
4485
+ maxItems: "schema.out-of-range",
4486
+ minimum: "schema.out-of-range",
4487
+ maximum: "schema.out-of-range",
4488
+ uniqueItems: "schema.out-of-range",
4489
+ ownProperties: "schema.invalid-structure",
4490
+ uniqueId: "schema.duplicate-id",
4491
+ effectiveOrigin: "schema.no-effective-origin",
4492
+ maxRulesPerProject: "schema.rule-limit"
4493
+ };
4494
+ var SAFE_PARAM_KEYS = /* @__PURE__ */ new Set([
4495
+ "additionalProperty",
4496
+ "actual",
4497
+ "allowedValue",
4498
+ "allowedValues",
4499
+ "format",
4500
+ "i",
4501
+ "j",
4502
+ "limit",
4503
+ "missingProperty",
4504
+ "previousPath",
4505
+ "type",
4506
+ "headerName",
4507
+ "headerOperation",
4508
+ "headerDirection"
4509
+ ]);
4510
+ var MESSAGES = {
4511
+ "schema.required": "Required project data is missing.",
4512
+ "schema.unknown-property": "The project contains an unknown property.",
4513
+ "schema.invalid-type": "The project contains a value with an invalid type.",
4514
+ "schema.invalid-format": "The project contains a value with an invalid format.",
4515
+ "schema.invalid-value": "The project contains an invalid value.",
4516
+ "schema.out-of-range": "The project contains a value outside its allowed bounds.",
4517
+ "schema.invalid-structure": "The project contains invalid structure.",
4518
+ "schema.duplicate-id": "Project and rule IDs must be unique.",
4519
+ "schema.no-effective-origin": "Each rule must have at least one effective origin.",
4520
+ "schema.rule-limit": "The project contains too many rules.",
4521
+ "compiler.invariant": "The compiler could not normalize validated project data.",
4522
+ "compiler.forbidden-header": "The header name is forbidden for this direction.",
4523
+ "compiler.header-value-required": "Header value is required for set and append operations.",
4524
+ "compiler.header-value-unexpected": "Header value must not be provided for remove operation.",
4525
+ "compiler.invalid-header-direction": "Invalid header direction.",
4526
+ "compiler.invalid-header-operation": "Invalid header operation."
4527
+ };
4528
+ function copySafeParams(params) {
4529
+ const safe = {};
4530
+ for (const key of Object.keys(params)) {
4531
+ if (!SAFE_PARAM_KEYS.has(key)) continue;
4532
+ const value = params[key];
4533
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null) {
4534
+ safe[key] = value;
4535
+ continue;
4536
+ }
4537
+ if (Array.isArray(value)) {
4538
+ const values = [];
4539
+ for (let index = 0; index < value.length; index += 1) {
4540
+ const item = value[index];
4541
+ if (typeof item === "string" || typeof item === "number" || typeof item === "boolean" || item === null) {
4542
+ values.push(item);
4543
+ }
4544
+ }
4545
+ safe[key] = values;
4546
+ }
4547
+ }
4548
+ return safe;
4549
+ }
4550
+ function compareCodeUnits(left, right) {
4551
+ if (left < right) return -1;
4552
+ if (left > right) return 1;
4553
+ return 0;
4554
+ }
4555
+ function compareDiagnostics(left, right) {
4556
+ const leftParams = stableParams(left.params);
4557
+ const rightParams = stableParams(right.params);
4558
+ return compareCodeUnits(left.path, right.path) || compareCodeUnits(left.code, right.code) || compareCodeUnits(left.message, right.message) || compareCodeUnits(leftParams, rightParams);
4559
+ }
4560
+ function stableParams(params) {
4561
+ const keys = Object.keys(params).sort(compareCodeUnits);
4562
+ return keys.map((key) => `${JSON.stringify(key)}:${JSON.stringify(params[key])}`).join(",");
4563
+ }
4564
+ function mapValidationIssues(issues) {
4565
+ return issues.map((issue) => {
4566
+ const code = Object.hasOwn(ISSUE_CODES, issue.keyword) ? ISSUE_CODES[issue.keyword] : "schema.invalid-value";
4567
+ return {
4568
+ code,
4569
+ severity: "error",
4570
+ path: issue.instancePath,
4571
+ message: MESSAGES[code],
4572
+ params: copySafeParams(issue.params)
4573
+ };
4574
+ }).sort(compareDiagnostics);
4575
+ }
4576
+ function invariantDiagnostic(path = "") {
4577
+ return {
4578
+ code: "compiler.invariant",
4579
+ severity: "error",
4580
+ path,
4581
+ message: MESSAGES["compiler.invariant"],
4582
+ params: {}
4583
+ };
4584
+ }
4585
+ function compareCodeUnits2(left, right) {
4586
+ if (left < right) return -1;
4587
+ if (left > right) return 1;
4588
+ return 0;
4589
+ }
4590
+ function snapshotOwnData2(value, ancestors = /* @__PURE__ */ new WeakSet()) {
4591
+ if (value === null || typeof value !== "object") {
4592
+ return { valid: true, value };
4593
+ }
4594
+ if (ancestors.has(value)) return { valid: false };
4595
+ ancestors.add(value);
4596
+ try {
4597
+ if (Object.getOwnPropertySymbols(value).length > 0) {
4598
+ return { valid: false };
4599
+ }
4600
+ if (Array.isArray(value)) {
4601
+ const lengthDescriptor = Object.getOwnPropertyDescriptor(value, "length");
4602
+ if (lengthDescriptor === void 0 || !("value" in lengthDescriptor) || !Number.isSafeInteger(lengthDescriptor.value) || lengthDescriptor.value < 0 || lengthDescriptor.value > LIMITS.maxRulesPerProject) {
4603
+ return { valid: false };
4604
+ }
4605
+ const length = lengthDescriptor.value;
4606
+ for (const propertyName of Object.getOwnPropertyNames(value)) {
4607
+ if (propertyName === "length") continue;
4608
+ const index = Number(propertyName);
4609
+ if (!Number.isInteger(index) || index < 0 || index >= length || String(index) !== propertyName) {
4610
+ return { valid: false };
4611
+ }
4612
+ }
4613
+ const snapshot2 = new Array(length);
4614
+ for (let index = 0; index < length; index += 1) {
4615
+ const descriptor = Object.getOwnPropertyDescriptor(
4616
+ value,
4617
+ String(index)
4618
+ );
4619
+ if (descriptor === void 0 || !("value" in descriptor) || !descriptor.enumerable) {
4620
+ return { valid: false };
4621
+ }
4622
+ const child = snapshotOwnData2(descriptor.value, ancestors);
4623
+ if (!child.valid) return child;
4624
+ snapshot2[index] = child.value;
4625
+ }
4626
+ return { valid: true, value: snapshot2 };
4627
+ }
4628
+ const snapshot = /* @__PURE__ */ Object.create(null);
4629
+ for (const key of Object.getOwnPropertyNames(value)) {
4630
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
4631
+ if (descriptor === void 0 || !("value" in descriptor) || !descriptor.enumerable) {
4632
+ return { valid: false };
4633
+ }
4634
+ const child = snapshotOwnData2(descriptor.value, ancestors);
4635
+ if (!child.valid) return child;
4636
+ Object.defineProperty(snapshot, key, {
4637
+ configurable: true,
4638
+ enumerable: true,
4639
+ value: child.value,
4640
+ writable: true
4641
+ });
4642
+ }
4643
+ return { valid: true, value: snapshot };
4644
+ } catch {
4645
+ return { valid: false };
4646
+ } finally {
4647
+ ancestors.delete(value);
4648
+ }
4649
+ }
4650
+ var CompilerInvariantError = class extends Error {
4651
+ constructor(path) {
4652
+ super("invalid normalized origin");
4653
+ this.path = path;
4654
+ this.name = "CompilerInvariantError";
4655
+ }
4656
+ path;
4657
+ };
4658
+ function normalizeOrigins(group, rule, groupIndex, ruleIndex) {
4659
+ const origins = /* @__PURE__ */ new Set();
4660
+ const sourceArrays = [group.origins, rule.origins];
4661
+ for (let sourceIndex = 0; sourceIndex < sourceArrays.length; sourceIndex += 1) {
4662
+ const source = sourceArrays[sourceIndex];
4663
+ for (let originIndex = 0; originIndex < source.length; originIndex += 1) {
4664
+ const normalized = normalizeSiteOrigin(source[originIndex]);
4665
+ if (normalized === null) {
4666
+ const path = sourceIndex === 0 ? `/groups/${groupIndex}/origins/${originIndex}` : `/groups/${groupIndex}/rules/${ruleIndex}/origins/${originIndex}`;
4667
+ throw new CompilerInvariantError(path);
4668
+ }
4669
+ origins.add(normalized);
4670
+ }
4671
+ }
4672
+ const normalizedOrigins = [];
4673
+ for (const origin of origins) normalizedOrigins.push(origin);
4674
+ normalizedOrigins.sort(compareCodeUnits2);
4675
+ return normalizedOrigins;
4676
+ }
4677
+ function canonicalResourceTypes(resourceTypes) {
4678
+ const ordered = [];
4679
+ for (let canonicalIndex = 0; canonicalIndex < RESOURCE_TYPES.length; canonicalIndex += 1) {
4680
+ const canonical = RESOURCE_TYPES[canonicalIndex];
4681
+ for (let sourceIndex = 0; sourceIndex < resourceTypes.length; sourceIndex += 1) {
4682
+ if (resourceTypes[sourceIndex] === canonical) ordered.push(canonical);
4683
+ }
4684
+ }
4685
+ return ordered;
4686
+ }
4687
+ function compileMatcher(group, rule, groupIndex, ruleIndex) {
4688
+ const matcher = {
4689
+ urlRegex: { source: rule.urlRegex, flags: "" },
4690
+ origins: normalizeOrigins(group, rule, groupIndex, ruleIndex),
4691
+ resourceTypes: canonicalResourceTypes(rule.resourceTypes),
4692
+ priority: rule.priority
4693
+ };
4694
+ if (rule.method !== void 0) matcher.method = rule.method;
4695
+ return matcher;
4696
+ }
4697
+ function compileOperations(project) {
4698
+ const operations = [];
4699
+ for (let groupIndex = 0; groupIndex < project.groups.length; groupIndex += 1) {
4700
+ const group = project.groups[groupIndex];
4701
+ for (let ruleIndex = 0; ruleIndex < group.rules.length; ruleIndex += 1) {
4702
+ const rule = group.rules[ruleIndex];
4703
+ const matcher = compileMatcher(group, rule, groupIndex, ruleIndex);
4704
+ if (rule.type === "redirect") {
4705
+ const operation = {
4706
+ kind: "redirect",
4707
+ groupId: group.id,
4708
+ ruleId: rule.id,
4709
+ matcher,
4710
+ redirect: { destination: rule.redirect?.destination ?? "" }
4711
+ };
4712
+ operations.push(operation);
4713
+ } else if (rule.type === "query" && rule.action && "type" in rule.action && rule.action.type === "query") {
4714
+ const action = rule.action;
4715
+ const operation = {
4716
+ kind: "query",
4717
+ groupId: group.id,
4718
+ ruleId: rule.id,
4719
+ matcher,
4720
+ action
4721
+ };
4722
+ operations.push(operation);
4723
+ } else if (rule.type === "header") {
4724
+ const operation = {
4725
+ kind: "header",
4726
+ groupId: group.id,
4727
+ ruleId: rule.id,
4728
+ matcher,
4729
+ header: {
4730
+ direction: rule.headerDirection ?? "request",
4731
+ operation: rule.headerOperation ?? "set",
4732
+ name: rule.headerName ?? "",
4733
+ ...rule.headerValue !== void 0 ? { value: rule.headerValue } : {}
4734
+ }
4735
+ };
4736
+ operations.push(operation);
4737
+ } else if (rule.type === "mock") {
4738
+ const operation = {
4739
+ kind: "mock",
4740
+ groupId: group.id,
4741
+ ruleId: rule.id,
4742
+ matcher,
4743
+ mock: rule.mock ?? { status: 200, body: "" }
4744
+ };
4745
+ operations.push(operation);
4746
+ } else if (rule.type === "response-body") {
4747
+ const operation = {
4748
+ kind: "response-body",
4749
+ groupId: group.id,
4750
+ ruleId: rule.id,
4751
+ matcher,
4752
+ responseBody: rule.responseBody ?? { replacements: [] }
4753
+ };
4754
+ operations.push(operation);
4755
+ } else if (rule.type === "request-body") {
4756
+ const operation = {
4757
+ kind: "request-body",
4758
+ groupId: group.id,
4759
+ ruleId: rule.id,
4760
+ matcher,
4761
+ requestBody: rule.requestBody ?? { mode: "replace", body: "" }
4762
+ };
4763
+ operations.push(operation);
4764
+ } else {
4765
+ const operation = {
4766
+ kind: "matcher",
4767
+ groupId: group.id,
4768
+ ruleId: rule.id,
4769
+ matcher
4770
+ };
4771
+ operations.push(operation);
4772
+ }
4773
+ }
4774
+ }
4775
+ return operations;
4776
+ }
4777
+ function compileProject(value) {
4778
+ const snapshot = snapshotOwnData2(value);
4779
+ if (!snapshot.valid) {
4780
+ return {
4781
+ ok: false,
4782
+ operations: [],
4783
+ diagnostics: mapValidationIssues([
4784
+ {
4785
+ instancePath: "",
4786
+ keyword: "ownProperties",
4787
+ message: "must contain only own data properties",
4788
+ params: {}
4789
+ }
4790
+ ])
4791
+ };
4792
+ }
4793
+ let validation;
4794
+ try {
4795
+ validation = validateProjectDetailed(snapshot.value);
4796
+ } catch {
4797
+ return { ok: false, operations: [], diagnostics: [invariantDiagnostic()] };
4798
+ }
4799
+ if (!validation.valid) {
4800
+ return {
4801
+ ok: false,
4802
+ operations: [],
4803
+ diagnostics: mapValidationIssues(validation.errors)
4804
+ };
4805
+ }
4806
+ try {
4807
+ return {
4808
+ ok: true,
4809
+ operations: compileOperations(validation.data),
4810
+ diagnostics: []
4811
+ };
4812
+ } catch (error) {
4813
+ const path = error instanceof CompilerInvariantError ? error.path : "";
4814
+ return {
4815
+ ok: false,
4816
+ operations: [],
4817
+ diagnostics: [invariantDiagnostic(path)]
4818
+ };
4819
+ }
4820
+ }
3328
4821
 
3329
4822
  // packages/dry-run/dist/node/index.js
3330
- import { compileUrlRegex, HTTP_METHODS, RESOURCE_TYPES } from "@rogatio/schema";
4823
+ init_node();
3331
4824
  function parseTestUrl(input) {
3332
4825
  if (typeof input !== "string" || input.length === 0) {
3333
4826
  return { ok: false };
@@ -3633,7 +5126,7 @@ function dryRunProject(operations, cases, options) {
3633
5126
  }
3634
5127
 
3635
5128
  // packages/cli/src/server/routes.ts
3636
- import { validateProjectDetailed } from "@rogatio/schema";
5129
+ init_node();
3637
5130
 
3638
5131
  // packages/cli/src/utils/mock-preview.ts
3639
5132
  import { basename } from "node:path";
@@ -3678,7 +5171,7 @@ var RequestBodyError = class extends Error {
3678
5171
  code = "request-body-too-large";
3679
5172
  };
3680
5173
  function getRequestBody(req) {
3681
- return new Promise((resolve8, reject) => {
5174
+ return new Promise((resolve9, reject) => {
3682
5175
  let body = "";
3683
5176
  let bytes = 0;
3684
5177
  let settled = false;
@@ -3708,7 +5201,7 @@ function getRequestBody(req) {
3708
5201
  req.on("end", () => {
3709
5202
  if (!settled) {
3710
5203
  settled = true;
3711
- resolve8(body);
5204
+ resolve9(body);
3712
5205
  }
3713
5206
  });
3714
5207
  req.on("error", (error) => {
@@ -4052,6 +5545,21 @@ function createRoutes(context) {
4052
5545
  };
4053
5546
  }
4054
5547
 
5548
+ // packages/cli/src/utils/asset-paths.ts
5549
+ import { dirname, resolve as resolve2 } from "node:path";
5550
+ import { fileURLToPath } from "node:url";
5551
+ function isDistBuild(here = dirname(fileURLToPath(import.meta.url))) {
5552
+ return here.includes("/dist/") || here.includes("\\dist\\");
5553
+ }
5554
+ function editorAssetPaths(here = dirname(fileURLToPath(import.meta.url))) {
5555
+ const editorRoot = isDistBuild(here) ? resolve2(here, "..", "editor") : resolve2(here, "..", "..", "..", "editor", "dist", "browser");
5556
+ return {
5557
+ bundle: resolve2(editorRoot, "index.js"),
5558
+ css: resolve2(editorRoot, "index.css"),
5559
+ fonts: resolve2(editorRoot, "fonts")
5560
+ };
5561
+ }
5562
+
4055
5563
  // packages/cli/src/utils/browser.ts
4056
5564
  import { spawn } from "node:child_process";
4057
5565
  var BrowserLaunchError = class extends Error {
@@ -4088,7 +5596,7 @@ async function launchBrowser(url) {
4088
5596
  `Unsupported platform: ${platform}`
4089
5597
  );
4090
5598
  }
4091
- return new Promise((resolve8) => {
5599
+ return new Promise((resolve9) => {
4092
5600
  const child = spawn(command, args, {
4093
5601
  detached: true,
4094
5602
  stdio: "ignore"
@@ -4096,13 +5604,13 @@ async function launchBrowser(url) {
4096
5604
  child.unref();
4097
5605
  child.on("error", (err) => {
4098
5606
  if (err.code === "ENOENT") {
4099
- resolve8(false);
5607
+ resolve9(false);
4100
5608
  } else {
4101
- resolve8(false);
5609
+ resolve9(false);
4102
5610
  }
4103
5611
  });
4104
5612
  child.on("close", (code) => {
4105
- resolve8(code === 0);
5613
+ resolve9(code === 0);
4106
5614
  });
4107
5615
  });
4108
5616
  }
@@ -4110,7 +5618,7 @@ async function launchBrowser(url) {
4110
5618
  // packages/cli/src/utils/file.ts
4111
5619
  import { randomBytes as randomBytes2 } from "node:crypto";
4112
5620
  import { mkdir, readFile as readFile2, rename, writeFile } from "node:fs/promises";
4113
- import { basename as basename2, dirname, join } from "node:path";
5621
+ import { basename as basename2, dirname as dirname2, join } from "node:path";
4114
5622
  var ProjectFileError = class extends Error {
4115
5623
  code;
4116
5624
  path;
@@ -4160,10 +5668,10 @@ async function readProject(path) {
4160
5668
  }
4161
5669
  }
4162
5670
  async function writeProject(path, data) {
4163
- const tempName = `.${basename2(dirname(path))}.${randomBytes2(8).toString("hex")}.tmp`;
4164
- const tempPath = join(dirname(path), tempName);
5671
+ const tempName = `.${basename2(dirname2(path))}.${randomBytes2(8).toString("hex")}.tmp`;
5672
+ const tempPath = join(dirname2(path), tempName);
4165
5673
  try {
4166
- await mkdir(dirname(path), { recursive: true });
5674
+ await mkdir(dirname2(path), { recursive: true });
4167
5675
  await writeFile(tempPath, JSON.stringify(data, null, 2), "utf-8");
4168
5676
  await rename(tempPath, path);
4169
5677
  } catch (e) {
@@ -4224,9 +5732,9 @@ Options:
4224
5732
  }
4225
5733
  let filePath;
4226
5734
  if (positionalArgs[0]) {
4227
- filePath = resolve2(positionalArgs[0]);
5735
+ filePath = resolve3(positionalArgs[0]);
4228
5736
  } else {
4229
- filePath = resolve2(process.cwd(), ".rogatio.json");
5737
+ filePath = resolve3(process.cwd(), ".rogatio.json");
4230
5738
  }
4231
5739
  try {
4232
5740
  const stat3 = await import("node:fs/promises").then(
@@ -4295,17 +5803,11 @@ Options:
4295
5803
  }
4296
5804
  const serverUrl = `http://127.0.0.1:${server.port}`;
4297
5805
  const editorUrl = `${serverUrl}/editor.html`;
4298
- let editorBundlePath;
4299
- try {
4300
- editorBundlePath = fileURLToPath(import.meta.resolve("@rogatio/editor"));
4301
- } catch (e) {
4302
- console.error(`Error: cannot resolve @rogatio/editor bundle: ${e}`);
4303
- await server.stop();
4304
- return { exitCode: Promise.resolve(2), shutdown: () => {
4305
- } };
4306
- }
4307
- const editorCssPath = editorBundlePath.replace(/index\.js$/u, "index.css");
4308
- const editorFontsPath = resolve2(editorBundlePath, "..", "fonts");
5806
+ const {
5807
+ bundle: editorBundlePath,
5808
+ css: editorCssPath,
5809
+ fonts: editorFontsPath
5810
+ } = editorAssetPaths();
4309
5811
  context.editorHtml = generateEditorHtml(serverUrl, csrfToken, filePath);
4310
5812
  context.editorBundlePath = editorBundlePath;
4311
5813
  context.editorCssPath = editorCssPath;
@@ -4322,11 +5824,11 @@ Options:
4322
5824
  console.log(`Editor available at: ${editorUrl}`);
4323
5825
  console.log("Open this URL in your browser to edit the project.");
4324
5826
  }
4325
- const exitCodePromise = new Promise((resolve8) => {
5827
+ const exitCodePromise = new Promise((resolve9) => {
4326
5828
  const checkShutdown = setInterval(() => {
4327
5829
  if (shutdownCalled) {
4328
5830
  clearInterval(checkShutdown);
4329
- resolve8(0);
5831
+ resolve9(0);
4330
5832
  }
4331
5833
  }, 100);
4332
5834
  const handleSignal = () => {
@@ -4334,8 +5836,8 @@ Options:
4334
5836
  };
4335
5837
  process.on("SIGINT", handleSignal);
4336
5838
  process.on("SIGTERM", handleSignal);
4337
- const originalResolve = resolve8;
4338
- resolve8 = (code) => {
5839
+ const originalResolve = resolve9;
5840
+ resolve9 = (code) => {
4339
5841
  clearInterval(checkShutdown);
4340
5842
  process.off("SIGINT", handleSignal);
4341
5843
  process.off("SIGTERM", handleSignal);
@@ -4460,10 +5962,9 @@ function generateEditorHtml(apiBase, csrfToken, filePath) {
4460
5962
  }
4461
5963
 
4462
5964
  // packages/cli/src/commands/runtime.ts
5965
+ import { dirname as dirname4, isAbsolute as isAbsolute4, join as join3, relative as relative4, resolve as resolve5, sep as sep2 } from "node:path";
5966
+ init_node2();
4463
5967
  init_node();
4464
- import { dirname as dirname3, isAbsolute as isAbsolute4, join as join3, relative as relative4, resolve as resolve4, sep as sep2 } from "node:path";
4465
- import { compileProject as compileProject2 } from "@rogatio/compiler";
4466
- import { validateProjectDetailed as validateProjectDetailed2 } from "@rogatio/schema";
4467
5968
  function showRuntimeHelp() {
4468
5969
  console.log(`Usage: rogatio runtime <command> [options]
4469
5970
 
@@ -4506,7 +6007,7 @@ function toMatcherOperations2(operations) {
4506
6007
  }
4507
6008
  function resolveMockFile(root, filePath) {
4508
6009
  if (filePath.includes("\0")) return null;
4509
- const absolute = isAbsolute4(filePath) ? filePath : resolve4(root, filePath);
6010
+ const absolute = isAbsolute4(filePath) ? filePath : resolve5(root, filePath);
4510
6011
  const rel = relative4(root, absolute);
4511
6012
  if (rel.startsWith("..") || isAbsolute4(rel)) return null;
4512
6013
  const logical = rel.split(sep2).join("/");
@@ -4663,7 +6164,7 @@ async function runtimeStatusCommand(_args) {
4663
6164
  return 0;
4664
6165
  }
4665
6166
  async function loadControlPreset() {
4666
- const { normalizeRuntimePreset: normalizeRuntimePreset2 } = await Promise.resolve().then(() => (init_node(), node_exports));
6167
+ const { normalizeRuntimePreset: normalizeRuntimePreset2 } = await Promise.resolve().then(() => (init_node2(), node_exports));
4667
6168
  const result = normalizeRuntimePreset2({
4668
6169
  version: 1,
4669
6170
  limits: RUNTIME_LIMITS,
@@ -4681,7 +6182,7 @@ async function runtimeHostCommand(args) {
4681
6182
  for (let index = 0; index < args.length; index += 1) {
4682
6183
  const arg = args[index];
4683
6184
  if (arg === "--root" && index + 1 < args.length) {
4684
- root = resolve4(args[++index]);
6185
+ root = resolve5(args[++index]);
4685
6186
  } else if (arg === "--root") {
4686
6187
  argumentError = "--root requires a value";
4687
6188
  } else if (arg === "--mock-port" && index + 1 < args.length) {
@@ -4715,7 +6216,7 @@ async function runtimeHostCommand(args) {
4715
6216
  filePath = "<stdin>";
4716
6217
  projectData = JSON.parse(chunks.join(""));
4717
6218
  } else {
4718
- filePath = inputPath ? resolve4(inputPath) : resolve4(process.cwd(), ".rogatio.json");
6219
+ filePath = inputPath ? resolve5(inputPath) : resolve5(process.cwd(), ".rogatio.json");
4719
6220
  projectData = await readProject(filePath);
4720
6221
  }
4721
6222
  } catch (error) {
@@ -4723,7 +6224,7 @@ async function runtimeHostCommand(args) {
4723
6224
  console.error(`Error: ${message}`);
4724
6225
  return 2;
4725
6226
  }
4726
- const schemaResult = validateProjectDetailed2(projectData);
6227
+ const schemaResult = validateProjectDetailed(projectData);
4727
6228
  if (!schemaResult.valid) {
4728
6229
  for (const issue of schemaResult.errors) {
4729
6230
  console.error(
@@ -4732,7 +6233,7 @@ async function runtimeHostCommand(args) {
4732
6233
  }
4733
6234
  return 1;
4734
6235
  }
4735
- const compileResult = compileProject2(schemaResult.data);
6236
+ const compileResult = compileProject(schemaResult.data);
4736
6237
  if (!compileResult.ok) {
4737
6238
  for (const diagnostic of compileResult.diagnostics) {
4738
6239
  console.error(
@@ -4741,7 +6242,7 @@ async function runtimeHostCommand(args) {
4741
6242
  }
4742
6243
  return 1;
4743
6244
  }
4744
- const rootDir = root ?? (inputPath === "-" ? process.cwd() : dirname3(filePath));
6245
+ const rootDir = root ?? (inputPath === "-" ? process.cwd() : dirname4(filePath));
4745
6246
  const mocksResult = buildMockConfigs(compileResult.operations, rootDir);
4746
6247
  if (!mocksResult.ok) {
4747
6248
  console.error(`Error: ${mocksResult.message}`);
@@ -4790,9 +6291,8 @@ async function runRuntimeHostEntry() {
4790
6291
 
4791
6292
  // packages/cli/src/commands/test.ts
4792
6293
  import { readFile as readFile4 } from "node:fs/promises";
4793
- import { resolve as resolve5 } from "node:path";
4794
- import { compileProject as compileProject3 } from "@rogatio/compiler";
4795
- import { validateProjectDetailed as validateProjectDetailed3 } from "@rogatio/schema";
6294
+ import { resolve as resolve6 } from "node:path";
6295
+ init_node();
4796
6296
  function usageError(message) {
4797
6297
  return `Error: ${message}
4798
6298
  `;
@@ -4865,7 +6365,7 @@ function resultOptions(maxCases, operations) {
4865
6365
  return options;
4866
6366
  }
4867
6367
  function diagnosticsFromSchema(projectData) {
4868
- const result = validateProjectDetailed3(projectData);
6368
+ const result = validateProjectDetailed(projectData);
4869
6369
  if (result.valid) return [];
4870
6370
  return result.errors.map((error) => ({
4871
6371
  code: `schema.${error.keyword}`,
@@ -4914,7 +6414,7 @@ function testCommandNeedsStdin(args) {
4914
6414
  return !hasUrlSource && positionalUrls.length === 0;
4915
6415
  }
4916
6416
  async function testCommandImpl(args, stdinInput, captureOutput) {
4917
- let filePath = resolve5(process.cwd(), ".rogatio.json");
6417
+ let filePath = resolve6(process.cwd(), ".rogatio.json");
4918
6418
  let jsonMode = false;
4919
6419
  let maxCases;
4920
6420
  const urlCases = [];
@@ -4973,7 +6473,7 @@ async function testCommandImpl(args, stdinInput, captureOutput) {
4973
6473
  }
4974
6474
  filePath = "<stdin>";
4975
6475
  } else if (inputPath) {
4976
- filePath = resolve5(inputPath);
6476
+ filePath = resolve6(inputPath);
4977
6477
  }
4978
6478
  for (const url of positionalUrls) urlCases.push({ url });
4979
6479
  if (urlsFile) {
@@ -5025,7 +6525,7 @@ async function testCommandImpl(args, stdinInput, captureOutput) {
5025
6525
  console.error(output.trim());
5026
6526
  return 2;
5027
6527
  }
5028
- const schemaResult = validateProjectDetailed3(projectData);
6528
+ const schemaResult = validateProjectDetailed(projectData);
5029
6529
  let diagnostics = diagnosticsFromSchema(projectData);
5030
6530
  if (!schemaResult.valid) {
5031
6531
  const output = jsonMode ? jsonOutput({ diagnostics }) : diagnostics.map(
@@ -5037,7 +6537,7 @@ async function testCommandImpl(args, stdinInput, captureOutput) {
5037
6537
  else console.error(output.trim());
5038
6538
  return 1;
5039
6539
  }
5040
- const compileResult = compileProject3(schemaResult.data);
6540
+ const compileResult = compileProject(schemaResult.data);
5041
6541
  diagnostics = diagnosticsFromCompiler(compileResult);
5042
6542
  if (!compileResult.ok) {
5043
6543
  const output = jsonMode ? jsonOutput({ diagnostics }) : diagnostics.map(
@@ -5115,9 +6615,8 @@ async function testCommand(args, stdinInput, captureOutput = false) {
5115
6615
  }
5116
6616
 
5117
6617
  // packages/cli/src/commands/verify.ts
5118
- import { resolve as resolve6 } from "node:path";
5119
- import { compileProject as compileProject4 } from "@rogatio/compiler";
5120
- import { validateProjectDetailed as validateProjectDetailed4 } from "@rogatio/schema";
6618
+ import { resolve as resolve7 } from "node:path";
6619
+ init_node();
5121
6620
  async function verifyCommandImpl(args, stdinInput, captureOutput) {
5122
6621
  let filePath;
5123
6622
  let jsonOutput2 = false;
@@ -5143,9 +6642,9 @@ async function verifyCommandImpl(args, stdinInput, captureOutput) {
5143
6642
  }
5144
6643
  filePath = "<stdin>";
5145
6644
  } else if (inputPath) {
5146
- filePath = resolve6(inputPath);
6645
+ filePath = resolve7(inputPath);
5147
6646
  } else {
5148
- filePath = resolve6(process.cwd(), ".rogatio.json");
6647
+ filePath = resolve7(process.cwd(), ".rogatio.json");
5149
6648
  }
5150
6649
  let projectData;
5151
6650
  try {
@@ -5163,7 +6662,7 @@ async function verifyCommandImpl(args, stdinInput, captureOutput) {
5163
6662
  console.error(output2.trim());
5164
6663
  return 2;
5165
6664
  }
5166
- const schemaResult = validateProjectDetailed4(projectData);
6665
+ const schemaResult = validateProjectDetailed(projectData);
5167
6666
  const diagnostics = [];
5168
6667
  if (!schemaResult.valid) {
5169
6668
  for (const error of schemaResult.errors) {
@@ -5176,7 +6675,7 @@ async function verifyCommandImpl(args, stdinInput, captureOutput) {
5176
6675
  });
5177
6676
  }
5178
6677
  } else {
5179
- const compileResult = compileProject4(schemaResult.data);
6678
+ const compileResult = compileProject(schemaResult.data);
5180
6679
  if (!compileResult.ok) {
5181
6680
  for (const diag of compileResult.diagnostics) {
5182
6681
  diagnostics.push({
@@ -5213,11 +6712,10 @@ async function verifyCommand(args, stdinInput, captureOutput = false) {
5213
6712
  }
5214
6713
 
5215
6714
  // packages/cli/src/index.ts
5216
- var __dirname = dirname4(fileURLToPath2(import.meta.url));
5217
- var isDist = __dirname.includes("/dist/") || __dirname.includes("\\dist\\");
5218
- var packageJsonPath = resolve7(
6715
+ var __dirname = dirname5(fileURLToPath2(import.meta.url));
6716
+ var packageJsonPath = resolve8(
5219
6717
  __dirname,
5220
- isDist ? "../../package.json" : "../package.json"
6718
+ isDistBuild(__dirname) ? "../../package.json" : "../package.json"
5221
6719
  );
5222
6720
  var packageJson = JSON.parse(
5223
6721
  await import("node:fs/promises").then(
@@ -5423,7 +6921,7 @@ Exit codes:
5423
6921
  1 Validation/compile/test errors
5424
6922
  2 Usage error (invalid arguments, missing input)`);
5425
6923
  }
5426
- if (process.argv[1] !== void 0 && realpathSync.native(fileURLToPath2(import.meta.url)) === realpathSync.native(resolve7(process.argv[1]))) {
6924
+ if (process.argv[1] !== void 0 && realpathSync.native(fileURLToPath2(import.meta.url)) === realpathSync.native(resolve8(process.argv[1]))) {
5427
6925
  if (basename4(process.argv[1]) === "runtime-host") {
5428
6926
  runRuntimeHostEntry().catch((err) => {
5429
6927
  console.error(err);