@rogatio/cli 1.2.0 → 1.3.0

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.
Files changed (2) hide show
  1. package/dist/node/index.js +87 -35
  2. package/package.json +1 -1
@@ -2,11 +2,11 @@
2
2
 
3
3
  // packages/cli/src/index.ts
4
4
  import { realpathSync } from "node:fs";
5
- import { dirname as dirname4, resolve as resolve6 } from "node:path";
5
+ import { dirname as dirname4, resolve as resolve7 } from "node:path";
6
6
  import { fileURLToPath as fileURLToPath2 } from "node:url";
7
7
 
8
8
  // packages/cli/src/commands/edit.ts
9
- import { resolve } from "node:path";
9
+ import { resolve as resolve2 } from "node:path";
10
10
  import { fileURLToPath } from "node:url";
11
11
 
12
12
  // packages/cli/src/server/http.ts
@@ -28,11 +28,11 @@ function createServer(handler, options = {}) {
28
28
  let port = null;
29
29
  let started = false;
30
30
  async function listenOn(candidatePort) {
31
- await new Promise((resolve7, reject) => {
31
+ await new Promise((resolve8, reject) => {
32
32
  server.once("error", reject);
33
33
  server.listen(candidatePort, "127.0.0.1", () => {
34
34
  server.off("error", reject);
35
- resolve7();
35
+ resolve8();
36
36
  });
37
37
  });
38
38
  }
@@ -86,8 +86,8 @@ function createServer(handler, options = {}) {
86
86
  },
87
87
  async stop() {
88
88
  if (!started) return;
89
- await new Promise((resolve7) => {
90
- server.close(() => resolve7());
89
+ await new Promise((resolve8) => {
90
+ server.close(() => resolve8());
91
91
  });
92
92
  started = false;
93
93
  }
@@ -97,6 +97,7 @@ function createServer(handler, options = {}) {
97
97
  // packages/cli/src/server/routes.ts
98
98
  import { randomBytes } from "node:crypto";
99
99
  import { readFile } from "node:fs/promises";
100
+ import { resolve } from "node:path";
100
101
  import { compileProject } from "@rogatio/compiler";
101
102
 
102
103
  // packages/dry-run/dist/node/index.js
@@ -451,7 +452,7 @@ var RequestBodyError = class extends Error {
451
452
  code = "request-body-too-large";
452
453
  };
453
454
  function getRequestBody(req) {
454
- return new Promise((resolve7, reject) => {
455
+ return new Promise((resolve8, reject) => {
455
456
  let body = "";
456
457
  let bytes = 0;
457
458
  let settled = false;
@@ -481,7 +482,7 @@ function getRequestBody(req) {
481
482
  req.on("end", () => {
482
483
  if (!settled) {
483
484
  settled = true;
484
- resolve7(body);
485
+ resolve8(body);
485
486
  }
486
487
  });
487
488
  req.on("error", (error) => {
@@ -590,6 +591,45 @@ function createRoutes(context) {
590
591
  }
591
592
  return;
592
593
  }
594
+ if (pathname === "/vendor/editor.css" && method === "GET") {
595
+ try {
596
+ const css = await readFile(context.editorCssPath, "utf-8");
597
+ res.writeHead(200, {
598
+ "Content-Type": "text/css; charset=utf-8",
599
+ ...corsHeaders
600
+ });
601
+ res.end(css);
602
+ } catch (e) {
603
+ res.writeHead(500, { "Content-Type": "application/json" });
604
+ res.end(
605
+ JSON.stringify({
606
+ code: "css-load-failed",
607
+ message: e instanceof Error ? e.message : "Failed to load editor stylesheet"
608
+ })
609
+ );
610
+ }
611
+ return;
612
+ }
613
+ if (pathname.startsWith("/vendor/fonts/") && method === "GET") {
614
+ const fileName = pathname.slice("/vendor/fonts/".length);
615
+ if (!fileName || fileName.includes("..") || fileName.includes("/") || fileName.includes("\\")) {
616
+ res.writeHead(404, { "Content-Type": "application/json" });
617
+ res.end(JSON.stringify({ code: "not-found", message: "Not found" }));
618
+ return;
619
+ }
620
+ try {
621
+ const font = await readFile(resolve(context.editorFontsPath, fileName));
622
+ res.writeHead(200, {
623
+ "Content-Type": "font/woff2",
624
+ ...corsHeaders
625
+ });
626
+ res.end(font);
627
+ } catch {
628
+ res.writeHead(404, { "Content-Type": "application/json" });
629
+ res.end(JSON.stringify({ code: "not-found", message: "Not found" }));
630
+ }
631
+ return;
632
+ }
593
633
  if (pathname === "/api/project" && method === "GET") {
594
634
  res.writeHead(200, { "Content-Type": "application/json" });
595
635
  res.end(JSON.stringify(context.project));
@@ -822,7 +862,7 @@ async function launchBrowser(url) {
822
862
  `Unsupported platform: ${platform}`
823
863
  );
824
864
  }
825
- return new Promise((resolve7) => {
865
+ return new Promise((resolve8) => {
826
866
  const child = spawn(command, args, {
827
867
  detached: true,
828
868
  stdio: "ignore"
@@ -830,13 +870,13 @@ async function launchBrowser(url) {
830
870
  child.unref();
831
871
  child.on("error", (err) => {
832
872
  if (err.code === "ENOENT") {
833
- resolve7(false);
873
+ resolve8(false);
834
874
  } else {
835
- resolve7(false);
875
+ resolve8(false);
836
876
  }
837
877
  });
838
878
  child.on("close", (code) => {
839
- resolve7(code === 0);
879
+ resolve8(code === 0);
840
880
  });
841
881
  });
842
882
  }
@@ -958,9 +998,9 @@ Options:
958
998
  }
959
999
  let filePath;
960
1000
  if (positionalArgs[0]) {
961
- filePath = resolve(positionalArgs[0]);
1001
+ filePath = resolve2(positionalArgs[0]);
962
1002
  } else {
963
- filePath = resolve(process.cwd(), ".rogatio.json");
1003
+ filePath = resolve2(process.cwd(), ".rogatio.json");
964
1004
  }
965
1005
  try {
966
1006
  const stat3 = await import("node:fs/promises").then(
@@ -1011,7 +1051,9 @@ Options:
1011
1051
  shutdown();
1012
1052
  },
1013
1053
  editorHtml: "",
1014
- editorBundlePath: ""
1054
+ editorBundlePath: "",
1055
+ editorCssPath: "",
1056
+ editorFontsPath: ""
1015
1057
  };
1016
1058
  let server;
1017
1059
  try {
@@ -1036,8 +1078,12 @@ Options:
1036
1078
  return { exitCode: Promise.resolve(2), shutdown: () => {
1037
1079
  } };
1038
1080
  }
1081
+ const editorCssPath = editorBundlePath.replace(/index\.js$/u, "index.css");
1082
+ const editorFontsPath = resolve2(editorBundlePath, "..", "fonts");
1039
1083
  context.editorHtml = generateEditorHtml(serverUrl, csrfToken, filePath);
1040
1084
  context.editorBundlePath = editorBundlePath;
1085
+ context.editorCssPath = editorCssPath;
1086
+ context.editorFontsPath = editorFontsPath;
1041
1087
  let shutdownCalled = false;
1042
1088
  function shutdown() {
1043
1089
  shutdownCalled = true;
@@ -1050,11 +1096,11 @@ Options:
1050
1096
  console.log(`Editor available at: ${editorUrl}`);
1051
1097
  console.log("Open this URL in your browser to edit the project.");
1052
1098
  }
1053
- const exitCodePromise = new Promise((resolve7) => {
1099
+ const exitCodePromise = new Promise((resolve8) => {
1054
1100
  const checkShutdown = setInterval(() => {
1055
1101
  if (shutdownCalled) {
1056
1102
  clearInterval(checkShutdown);
1057
- resolve7(0);
1103
+ resolve8(0);
1058
1104
  }
1059
1105
  }, 100);
1060
1106
  const handleSignal = () => {
@@ -1062,8 +1108,8 @@ Options:
1062
1108
  };
1063
1109
  process.on("SIGINT", handleSignal);
1064
1110
  process.on("SIGTERM", handleSignal);
1065
- const originalResolve = resolve7;
1066
- resolve7 = (code) => {
1111
+ const originalResolve = resolve8;
1112
+ resolve8 = (code) => {
1067
1113
  clearInterval(checkShutdown);
1068
1114
  process.off("SIGINT", handleSignal);
1069
1115
  process.off("SIGTERM", handleSignal);
@@ -1082,9 +1128,15 @@ function generateEditorHtml(apiBase, csrfToken, filePath) {
1082
1128
  <meta charset="UTF-8">
1083
1129
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
1084
1130
  <title>Rogatio Editor</title>
1131
+ <link rel="stylesheet" href="/vendor/editor.css" />
1085
1132
  <style>
1086
- body { margin: 0; font-family: system-ui, sans-serif; }
1087
- #editor-root { width: 100vw; height: 100vh; }
1133
+ html, body { margin: 0; min-height: 100%; }
1134
+ body {
1135
+ background-color: #121417;
1136
+ background-image: radial-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px);
1137
+ background-size: 24px 24px;
1138
+ }
1139
+ #editor-root { min-height: 100vh; }
1088
1140
  </style>
1089
1141
  </head>
1090
1142
  <body>
@@ -1182,7 +1234,7 @@ function generateEditorHtml(apiBase, csrfToken, filePath) {
1182
1234
  }
1183
1235
 
1184
1236
  // packages/cli/src/commands/runtime.ts
1185
- import { dirname as dirname3, isAbsolute, join as join3, relative, resolve as resolve3, sep as sep2 } from "node:path";
1237
+ import { dirname as dirname3, isAbsolute, join as join3, relative, resolve as resolve4, sep as sep2 } from "node:path";
1186
1238
  import { compileProject as compileProject2 } from "@rogatio/compiler";
1187
1239
 
1188
1240
  // packages/runtime/dist/node/index.js
@@ -1213,7 +1265,7 @@ import { createHash as createHash3, randomBytes as randomBytes3, timingSafeEqual
1213
1265
  import { isSha256Digest } from "@rogatio/schema";
1214
1266
  import { randomBytes as randomBytes22 } from "node:crypto";
1215
1267
  import { readFile as readFile3, realpath as realpath2, stat } from "node:fs/promises";
1216
- import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2, sep } from "node:path";
1268
+ import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve3, sep } from "node:path";
1217
1269
  import { mkdir as mkdir2, readFile as readFile22, rename as rename2, rm, stat as stat2, writeFile as writeFile2 } from "node:fs/promises";
1218
1270
  import { basename as basename3, dirname as dirname2, isAbsolute as isAbsolute4, join as join2, relative as relative3 } from "node:path";
1219
1271
  import { generateKeyPairSync as generateKeyPairSync2 } from "node:crypto";
@@ -2093,7 +2145,7 @@ async function readMockFile(root, logicalPath) {
2093
2145
  if (normalized === null) return failure("runtime.file-denied");
2094
2146
  try {
2095
2147
  const canonicalRoot = await realpath2(root);
2096
- const candidate = resolve2(canonicalRoot, ...normalized.split("/"));
2148
+ const candidate = resolve3(canonicalRoot, ...normalized.split("/"));
2097
2149
  const actualPath = await realpath2(candidate);
2098
2150
  if (!withinRoot2(canonicalRoot, actualPath))
2099
2151
  return failure("runtime.file-denied");
@@ -2957,7 +3009,7 @@ function toMatcherOperations2(operations) {
2957
3009
  }
2958
3010
  function resolveMockFile(root, filePath) {
2959
3011
  if (filePath.includes("\0")) return null;
2960
- const absolute = isAbsolute(filePath) ? filePath : resolve3(root, filePath);
3012
+ const absolute = isAbsolute(filePath) ? filePath : resolve4(root, filePath);
2961
3013
  const rel = relative(root, absolute);
2962
3014
  if (rel.startsWith("..") || isAbsolute(rel)) return null;
2963
3015
  const logical = rel.split(sep2).join("/");
@@ -3142,7 +3194,7 @@ async function runtimeCommand(args, options = {}) {
3142
3194
  argumentError = "--port must be an integer between 0 and 65535";
3143
3195
  }
3144
3196
  } else if (arg === "--root" && index + 1 < args.length) {
3145
- root = resolve3(args[++index]);
3197
+ root = resolve4(args[++index]);
3146
3198
  } else if (arg === "--port" || arg === "--root") {
3147
3199
  argumentError = `${arg} requires a value`;
3148
3200
  } else if (arg === "-" || !arg.startsWith("-")) {
@@ -3168,7 +3220,7 @@ async function runtimeCommand(args, options = {}) {
3168
3220
  filePath = "<stdin>";
3169
3221
  projectData = JSON.parse(options.stdinInput);
3170
3222
  } else {
3171
- filePath = inputPath ? resolve3(inputPath) : resolve3(process.cwd(), ".rogatio.json");
3223
+ filePath = inputPath ? resolve4(inputPath) : resolve4(process.cwd(), ".rogatio.json");
3172
3224
  projectData = await readProject(filePath);
3173
3225
  }
3174
3226
  } catch (error) {
@@ -3259,7 +3311,7 @@ async function runtimeCommand(args, options = {}) {
3259
3311
 
3260
3312
  // packages/cli/src/commands/test.ts
3261
3313
  import { readFile as readFile4 } from "node:fs/promises";
3262
- import { resolve as resolve4 } from "node:path";
3314
+ import { resolve as resolve5 } from "node:path";
3263
3315
  import { compileProject as compileProject3 } from "@rogatio/compiler";
3264
3316
  import { validateProjectDetailed as validateProjectDetailed3 } from "@rogatio/schema";
3265
3317
  function usageError(message) {
@@ -3383,7 +3435,7 @@ function testCommandNeedsStdin(args) {
3383
3435
  return !hasUrlSource && positionalUrls.length === 0;
3384
3436
  }
3385
3437
  async function testCommandImpl(args, stdinInput, captureOutput) {
3386
- let filePath = resolve4(process.cwd(), ".rogatio.json");
3438
+ let filePath = resolve5(process.cwd(), ".rogatio.json");
3387
3439
  let jsonMode = false;
3388
3440
  let maxCases;
3389
3441
  const urlCases = [];
@@ -3442,7 +3494,7 @@ async function testCommandImpl(args, stdinInput, captureOutput) {
3442
3494
  }
3443
3495
  filePath = "<stdin>";
3444
3496
  } else if (inputPath) {
3445
- filePath = resolve4(inputPath);
3497
+ filePath = resolve5(inputPath);
3446
3498
  }
3447
3499
  for (const url of positionalUrls) urlCases.push({ url });
3448
3500
  if (urlsFile) {
@@ -3584,7 +3636,7 @@ async function testCommand(args, stdinInput, captureOutput = false) {
3584
3636
  }
3585
3637
 
3586
3638
  // packages/cli/src/commands/verify.ts
3587
- import { resolve as resolve5 } from "node:path";
3639
+ import { resolve as resolve6 } from "node:path";
3588
3640
  import { compileProject as compileProject4 } from "@rogatio/compiler";
3589
3641
  import { validateProjectDetailed as validateProjectDetailed4 } from "@rogatio/schema";
3590
3642
  async function verifyCommandImpl(args, stdinInput, captureOutput) {
@@ -3612,9 +3664,9 @@ async function verifyCommandImpl(args, stdinInput, captureOutput) {
3612
3664
  }
3613
3665
  filePath = "<stdin>";
3614
3666
  } else if (inputPath) {
3615
- filePath = resolve5(inputPath);
3667
+ filePath = resolve6(inputPath);
3616
3668
  } else {
3617
- filePath = resolve5(process.cwd(), ".rogatio.json");
3669
+ filePath = resolve6(process.cwd(), ".rogatio.json");
3618
3670
  }
3619
3671
  let projectData;
3620
3672
  try {
@@ -3684,7 +3736,7 @@ async function verifyCommand(args, stdinInput, captureOutput = false) {
3684
3736
  // packages/cli/src/index.ts
3685
3737
  var __dirname = dirname4(fileURLToPath2(import.meta.url));
3686
3738
  var isDist = __dirname.includes("/dist/") || __dirname.includes("\\dist\\");
3687
- var packageJsonPath = resolve6(
3739
+ var packageJsonPath = resolve7(
3688
3740
  __dirname,
3689
3741
  isDist ? "../../package.json" : "../package.json"
3690
3742
  );
@@ -3885,7 +3937,7 @@ Exit codes:
3885
3937
  1 Validation/compile/test errors
3886
3938
  2 Usage error (invalid arguments, missing input)`);
3887
3939
  }
3888
- if (process.argv[1] !== void 0 && realpathSync.native(fileURLToPath2(import.meta.url)) === realpathSync.native(resolve6(process.argv[1]))) {
3940
+ if (process.argv[1] !== void 0 && realpathSync.native(fileURLToPath2(import.meta.url)) === realpathSync.native(resolve7(process.argv[1]))) {
3889
3941
  cli().catch((err) => {
3890
3942
  console.error(err);
3891
3943
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogatio/cli",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Local-first browser request and response rules — editor host, file verification, test runner, and runtime dispatch.",