@rogatio/cli 6.20.0 → 6.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/node/index.js +104 -151
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ rogatio <command> [options]
|
|
|
45
45
|
| `rogatio runtime <install\|uninstall\|verify>` | Register the native-messaging host with `install` and trust the device-local CA in one **transactional** call; it needs elevated privileges (Linux `sudo`, macOS keychain authorization, Windows Administrator) and rolls back with exit `1` and `trust unsupported: <reasons>` when a capability or elevation is missing. Release users never pass `--extension-id`. That flag is only for development (a local unpacked build without the release key) and for forks. `uninstall` removes the host manifest, the device-local CA files, and the CA trust installation (idempotent). `verify` reports whether manifest, `runtime-host` wrapper, allowed origins, and CA trust are all valid, and fails when `allowed_origins` omits the release ID. Release users never pass `--extension-id` on verify either. |
|
|
46
46
|
| `rogatio runtime host [path]` | Run the consolidated native-messaging host for the project (pair/authorize/body transforms and mock responses over stdio). Normally launched by the browser; run manually only for debugging. `--root <dir>` overrides the confined mock file root. When omitted, a saved device-local root for that project file is used, otherwise the project directory. A stdin project that contains a file mock requires `--root`. |
|
|
47
47
|
|
|
48
|
-
`rogatio edit` includes **Run checks**. It calls `POST /api/doctor` (CSRF-
|
|
48
|
+
`rogatio edit` includes **Run checks**. It calls `POST /e/<session>/api/doctor` (session path, loopback Origin, and `X-CSRF-Token`) and shows editor checks plus the same report as `rogatio doctor` for the open file. A provider configured after the page opened is picked up on the next `rogatio edit`.
|
|
49
49
|
|
|
50
50
|
Global options: `--help, -h` and `--version, -v`. Run `rogatio <command> --help`
|
|
51
51
|
for command-specific usage.
|
package/dist/node/index.js
CHANGED
|
@@ -7,8 +7,6 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
|
7
7
|
|
|
8
8
|
// packages/runtime/dist/node/index.js
|
|
9
9
|
import { isIP } from "node:net";
|
|
10
|
-
import * as fs from "node:fs/promises";
|
|
11
|
-
import * as path from "node:path";
|
|
12
10
|
|
|
13
11
|
// packages/schema/dist/node/index.js
|
|
14
12
|
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
@@ -2260,6 +2258,8 @@ function sameOrigin(a, b) {
|
|
|
2260
2258
|
}
|
|
2261
2259
|
|
|
2262
2260
|
// packages/runtime/dist/node/index.js
|
|
2261
|
+
import * as fs from "node:fs/promises";
|
|
2262
|
+
import * as path from "node:path";
|
|
2263
2263
|
import { isIP as isIP2 } from "node:net";
|
|
2264
2264
|
import { constants, existsSync } from "node:fs";
|
|
2265
2265
|
import { open, readlink, realpath } from "node:fs/promises";
|
|
@@ -21133,79 +21133,51 @@ function sleep(ms) {
|
|
|
21133
21133
|
function calculateRetryDelay(attempt) {
|
|
21134
21134
|
return RETRY_DELAY_BASE * 2 ** attempt + Math.random() * 100;
|
|
21135
21135
|
}
|
|
21136
|
-
|
|
21137
|
-
|
|
21138
|
-
|
|
21139
|
-
|
|
21140
|
-
|
|
21141
|
-
}
|
|
21142
|
-
try {
|
|
21143
|
-
const controller = new AbortController();
|
|
21144
|
-
const timeoutId = setTimeout(() => controller.abort(), COMPLETE_TIMEOUT);
|
|
21145
|
-
if (signal) {
|
|
21146
|
-
signal.addEventListener("abort", () => controller.abort());
|
|
21147
|
-
}
|
|
21148
|
-
const response = await fetch(url, {
|
|
21149
|
-
...init,
|
|
21150
|
-
signal: controller.signal
|
|
21151
|
-
});
|
|
21152
|
-
clearTimeout(timeoutId);
|
|
21153
|
-
if (response.ok) {
|
|
21154
|
-
return response;
|
|
21155
|
-
}
|
|
21156
|
-
const shouldRetry = response.status === 429 || response.status >= 500;
|
|
21157
|
-
if (shouldRetry && attempt < MAX_RETRIES) {
|
|
21158
|
-
const retryAfter = response.headers.get("Retry-After");
|
|
21159
|
-
const delay = retryAfter ? parseInt(retryAfter, 10) * 1e3 : calculateRetryDelay(attempt);
|
|
21160
|
-
await sleep(Math.min(delay, 1e4));
|
|
21161
|
-
continue;
|
|
21162
|
-
}
|
|
21163
|
-
const errorText = await response.text().catch(() => "");
|
|
21164
|
-
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
21165
|
-
} catch (e) {
|
|
21166
|
-
lastError = e;
|
|
21167
|
-
if (e instanceof DOMException && e.name === "AbortError") {
|
|
21168
|
-
throw e;
|
|
21169
|
-
}
|
|
21170
|
-
if (attempt < MAX_RETRIES && e.name !== "AbortError") {
|
|
21171
|
-
await sleep(calculateRetryDelay(attempt));
|
|
21172
|
-
continue;
|
|
21173
|
-
}
|
|
21174
|
-
throw e;
|
|
21175
|
-
}
|
|
21176
|
-
}
|
|
21177
|
-
throw lastError;
|
|
21136
|
+
function providerStatusError(status) {
|
|
21137
|
+
return new Error(`HTTP ${status}`);
|
|
21138
|
+
}
|
|
21139
|
+
async function releaseResponse(response) {
|
|
21140
|
+
await response.body?.cancel().catch(() => void 0);
|
|
21178
21141
|
}
|
|
21179
|
-
async function
|
|
21142
|
+
async function fetchProvider(url, init, timeoutMs, signal) {
|
|
21180
21143
|
let lastError;
|
|
21181
21144
|
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
21182
21145
|
if (signal?.aborted) {
|
|
21183
21146
|
throw new DOMException("Aborted", "AbortError");
|
|
21184
21147
|
}
|
|
21148
|
+
const controller = new AbortController();
|
|
21149
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
21150
|
+
if (signal) {
|
|
21151
|
+
signal.addEventListener("abort", () => controller.abort());
|
|
21152
|
+
}
|
|
21153
|
+
let terminalStatus;
|
|
21185
21154
|
try {
|
|
21186
|
-
const controller = new AbortController();
|
|
21187
|
-
const timeoutId = setTimeout(() => controller.abort(), STREAM_TIMEOUT);
|
|
21188
|
-
if (signal) {
|
|
21189
|
-
signal.addEventListener("abort", () => controller.abort());
|
|
21190
|
-
}
|
|
21191
21155
|
const response = await fetch(url, {
|
|
21192
21156
|
...init,
|
|
21157
|
+
// Stay on the configured URL. A 3xx response is not followed.
|
|
21158
|
+
redirect: "manual",
|
|
21193
21159
|
signal: controller.signal
|
|
21194
21160
|
});
|
|
21195
21161
|
clearTimeout(timeoutId);
|
|
21196
|
-
if (response.
|
|
21162
|
+
if (response.status >= 300 && response.status <= 399) {
|
|
21163
|
+
await releaseResponse(response);
|
|
21164
|
+
terminalStatus = response.status;
|
|
21165
|
+
} else if (response.ok) {
|
|
21197
21166
|
return response;
|
|
21167
|
+
} else {
|
|
21168
|
+
const shouldRetry = response.status === 429 || response.status >= 500;
|
|
21169
|
+
if (shouldRetry && attempt < MAX_RETRIES) {
|
|
21170
|
+
await releaseResponse(response);
|
|
21171
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
21172
|
+
const delay = retryAfter ? parseInt(retryAfter, 10) * 1e3 : calculateRetryDelay(attempt);
|
|
21173
|
+
await sleep(Math.min(delay, 1e4));
|
|
21174
|
+
continue;
|
|
21175
|
+
}
|
|
21176
|
+
await releaseResponse(response);
|
|
21177
|
+
terminalStatus = response.status;
|
|
21198
21178
|
}
|
|
21199
|
-
const shouldRetry = response.status === 429 || response.status >= 500;
|
|
21200
|
-
if (shouldRetry && attempt < MAX_RETRIES) {
|
|
21201
|
-
const retryAfter = response.headers.get("Retry-After");
|
|
21202
|
-
const delay = retryAfter ? parseInt(retryAfter, 10) * 1e3 : calculateRetryDelay(attempt);
|
|
21203
|
-
await sleep(Math.min(delay, 1e4));
|
|
21204
|
-
continue;
|
|
21205
|
-
}
|
|
21206
|
-
const errorText = await response.text().catch(() => "");
|
|
21207
|
-
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
21208
21179
|
} catch (e) {
|
|
21180
|
+
clearTimeout(timeoutId);
|
|
21209
21181
|
lastError = e;
|
|
21210
21182
|
if (e instanceof DOMException && e.name === "AbortError") {
|
|
21211
21183
|
throw e;
|
|
@@ -21216,9 +21188,18 @@ async function fetchStreamWithRetry(url, init, signal) {
|
|
|
21216
21188
|
}
|
|
21217
21189
|
throw e;
|
|
21218
21190
|
}
|
|
21191
|
+
if (terminalStatus !== void 0) {
|
|
21192
|
+
throw providerStatusError(terminalStatus);
|
|
21193
|
+
}
|
|
21219
21194
|
}
|
|
21220
21195
|
throw lastError;
|
|
21221
21196
|
}
|
|
21197
|
+
function fetchWithRetry(url, init, signal) {
|
|
21198
|
+
return fetchProvider(url, init, COMPLETE_TIMEOUT, signal);
|
|
21199
|
+
}
|
|
21200
|
+
function fetchStreamWithRetry(url, init, signal) {
|
|
21201
|
+
return fetchProvider(url, init, STREAM_TIMEOUT, signal);
|
|
21202
|
+
}
|
|
21222
21203
|
function sanitizeResponse(text) {
|
|
21223
21204
|
return text;
|
|
21224
21205
|
}
|
|
@@ -21318,67 +21299,23 @@ function createAIClient(config) {
|
|
|
21318
21299
|
}
|
|
21319
21300
|
};
|
|
21320
21301
|
}
|
|
21321
|
-
var
|
|
21322
|
-
"main_frame",
|
|
21323
|
-
"sub_frame",
|
|
21324
|
-
"stylesheet",
|
|
21325
|
-
"script",
|
|
21326
|
-
"image",
|
|
21327
|
-
"font",
|
|
21328
|
-
"object",
|
|
21329
|
-
"xmlhttprequest",
|
|
21330
|
-
"fetch",
|
|
21331
|
-
"media",
|
|
21332
|
-
"websocket",
|
|
21333
|
-
"manifest",
|
|
21334
|
-
"other"
|
|
21335
|
-
];
|
|
21336
|
-
var HTTP_METHODS2 = [
|
|
21337
|
-
"GET",
|
|
21338
|
-
"POST",
|
|
21339
|
-
"PUT",
|
|
21340
|
-
"PATCH",
|
|
21341
|
-
"DELETE",
|
|
21342
|
-
"HEAD",
|
|
21343
|
-
"OPTIONS",
|
|
21344
|
-
"CONNECT",
|
|
21345
|
-
"TRACE"
|
|
21346
|
-
];
|
|
21347
|
-
var FORBIDDEN_REQUEST_HEADERS2 = [
|
|
21348
|
-
"accept-charset",
|
|
21349
|
-
"accept-encoding",
|
|
21350
|
-
"access-control-request-headers",
|
|
21351
|
-
"access-control-request-method",
|
|
21352
|
-
"connection",
|
|
21353
|
-
"content-length",
|
|
21354
|
-
"cookie",
|
|
21355
|
-
"cookie2",
|
|
21356
|
-
"date",
|
|
21357
|
-
"dnt",
|
|
21358
|
-
"expect",
|
|
21359
|
-
"host",
|
|
21360
|
-
"keep-alive",
|
|
21361
|
-
"origin",
|
|
21362
|
-
"referer",
|
|
21363
|
-
"te",
|
|
21364
|
-
"trailer",
|
|
21365
|
-
"transfer-encoding",
|
|
21366
|
-
"upgrade",
|
|
21367
|
-
"via"
|
|
21368
|
-
];
|
|
21369
|
-
var FORBIDDEN_RESPONSE_HEADERS2 = ["set-cookie", "set-cookie2"];
|
|
21302
|
+
var MAX_PROJECTS_PER_PROFILE = 64;
|
|
21370
21303
|
function formatResourceTypes() {
|
|
21371
|
-
return
|
|
21304
|
+
return [...RESOURCE_TYPES].join(", ");
|
|
21372
21305
|
}
|
|
21373
21306
|
function formatHttpMethods() {
|
|
21374
|
-
return
|
|
21307
|
+
return [...HTTP_METHODS].join(", ");
|
|
21375
21308
|
}
|
|
21376
21309
|
function formatForbiddenHeaders() {
|
|
21377
21310
|
return [
|
|
21378
|
-
...
|
|
21379
|
-
...
|
|
21311
|
+
...FORBIDDEN_REQUEST_HEADERS.map((header) => `request: ${header}`),
|
|
21312
|
+
...FORBIDDEN_REQUEST_PREFIXES.map((prefix) => `request prefix: ${prefix}`),
|
|
21313
|
+
...FORBIDDEN_RESPONSE_HEADERS.map((header) => `response: ${header}`)
|
|
21380
21314
|
].join(", ");
|
|
21381
21315
|
}
|
|
21316
|
+
function formatDiagnostics() {
|
|
21317
|
+
return Object.entries(MESSAGES).map(([code, message]) => `- ${code} - ${message}`).join("\n");
|
|
21318
|
+
}
|
|
21382
21319
|
function formatProjectContext(project) {
|
|
21383
21320
|
try {
|
|
21384
21321
|
return JSON.stringify(project, null, 2);
|
|
@@ -21411,9 +21348,10 @@ ${formatResourceTypes()}
|
|
|
21411
21348
|
${formatHttpMethods()}
|
|
21412
21349
|
|
|
21413
21350
|
### Bounds
|
|
21414
|
-
- Max
|
|
21415
|
-
- Max
|
|
21416
|
-
- Max
|
|
21351
|
+
- Max ${MAX_PROJECTS_PER_PROFILE} projects per profile
|
|
21352
|
+
- Max ${LIMITS.maxGroups} groups per project
|
|
21353
|
+
- Max ${LIMITS.maxRulesPerGroup} rules per group
|
|
21354
|
+
- Max ${LIMITS.maxRulesPerProject} rules per project
|
|
21417
21355
|
|
|
21418
21356
|
## Rule Types
|
|
21419
21357
|
|
|
@@ -21435,22 +21373,7 @@ Replace-mode body may use URL captures. Regex-mode replacement strings use captu
|
|
|
21435
21373
|
Replace-mode body may use URL captures. Regex-mode replacement strings use captures from the body pattern, not the source pattern.
|
|
21436
21374
|
|
|
21437
21375
|
## Compiler Diagnostic Codes (stable)
|
|
21438
|
-
|
|
21439
|
-
- schema.unknown-property - The project contains an unknown property
|
|
21440
|
-
- schema.invalid-type - A value has an invalid type
|
|
21441
|
-
- schema.invalid-format - A value has an invalid format
|
|
21442
|
-
- schema.invalid-value - A value is invalid
|
|
21443
|
-
- schema.out-of-range - A value is outside its allowed bounds
|
|
21444
|
-
- schema.invalid-structure - A value has invalid structure
|
|
21445
|
-
- schema.duplicate-id - Duplicate group or rule ID
|
|
21446
|
-
- schema.duplicate-name - Duplicate group or rule name; every group and rule name must be unique in the project
|
|
21447
|
-
- schema.rule-limit - The project contains too many rules
|
|
21448
|
-
- compiler.invariant - The compiler could not normalize the project
|
|
21449
|
-
- compiler.forbidden-header - The header is forbidden for this direction
|
|
21450
|
-
- compiler.header-value-required - A header value is required for set and append
|
|
21451
|
-
- compiler.header-value-unexpected - A header value is not allowed for remove
|
|
21452
|
-
- compiler.invalid-header-direction - Invalid header direction
|
|
21453
|
-
- compiler.invalid-header-operation - Invalid header operation
|
|
21376
|
+
${formatDiagnostics()}
|
|
21454
21377
|
|
|
21455
21378
|
## Current Project
|
|
21456
21379
|
${projectJson}
|
|
@@ -29697,7 +29620,7 @@ function createServer3(handler, options = {}) {
|
|
|
29697
29620
|
}
|
|
29698
29621
|
|
|
29699
29622
|
// packages/cli/src/server/routes.ts
|
|
29700
|
-
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
29623
|
+
import { randomBytes as randomBytes4, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
29701
29624
|
import { readFile as readFile5 } from "node:fs/promises";
|
|
29702
29625
|
import { dirname as dirname9, isAbsolute as isAbsolute5, resolve as resolve5 } from "node:path";
|
|
29703
29626
|
|
|
@@ -30153,17 +30076,44 @@ function isAllowedEditorHost(host, boundPort) {
|
|
|
30153
30076
|
return host === `127.0.0.1:${expected}` || host === `localhost:${expected}`;
|
|
30154
30077
|
}
|
|
30155
30078
|
function isAllowedEditorOrigin(origin, boundPort) {
|
|
30156
|
-
if (origin === void 0)
|
|
30157
|
-
|
|
30079
|
+
if (origin === void 0 || !Number.isInteger(boundPort) || boundPort <= 0) {
|
|
30080
|
+
return false;
|
|
30081
|
+
}
|
|
30158
30082
|
const expected = String(boundPort);
|
|
30159
30083
|
return origin === `http://127.0.0.1:${expected}` || origin === `http://localhost:${expected}`;
|
|
30160
30084
|
}
|
|
30161
30085
|
function generateCsrfToken() {
|
|
30162
30086
|
return randomBytes4(16).toString("hex");
|
|
30163
30087
|
}
|
|
30088
|
+
function tokensEqual(provided, expected) {
|
|
30089
|
+
const providedBytes = Buffer.from(provided);
|
|
30090
|
+
const expectedBytes = Buffer.from(expected);
|
|
30091
|
+
if (providedBytes.length !== expectedBytes.length) return false;
|
|
30092
|
+
return timingSafeEqual2(providedBytes, expectedBytes);
|
|
30093
|
+
}
|
|
30094
|
+
function scopedPathname(pathname, sessionToken) {
|
|
30095
|
+
const marker = "/e/";
|
|
30096
|
+
if (!pathname.startsWith(marker)) return void 0;
|
|
30097
|
+
const after = pathname.slice(marker.length);
|
|
30098
|
+
const slash = after.indexOf("/");
|
|
30099
|
+
const candidate = slash === -1 ? after : after.slice(0, slash);
|
|
30100
|
+
if (candidate.length === 0 || !tokensEqual(candidate, sessionToken)) {
|
|
30101
|
+
return void 0;
|
|
30102
|
+
}
|
|
30103
|
+
return slash === -1 ? "/" : after.slice(slash);
|
|
30104
|
+
}
|
|
30105
|
+
function editorSessionPath(token, suffix) {
|
|
30106
|
+
const path2 = suffix.startsWith("/") ? suffix : `/${suffix}`;
|
|
30107
|
+
return `/e/${token}${path2}`;
|
|
30108
|
+
}
|
|
30164
30109
|
function validateCsrf(req, expectedToken) {
|
|
30165
|
-
const token = req.headers["x-csrf-token"];
|
|
30166
|
-
|
|
30110
|
+
const token = headerValue3(req.headers["x-csrf-token"]);
|
|
30111
|
+
if (token === void 0) return false;
|
|
30112
|
+
return tokensEqual(token, expectedToken);
|
|
30113
|
+
}
|
|
30114
|
+
function emptyNotFound(res) {
|
|
30115
|
+
res.writeHead(404);
|
|
30116
|
+
res.end();
|
|
30167
30117
|
}
|
|
30168
30118
|
var MAX_REQUEST_BODY_BYTES = 8 * 1024 * 1024;
|
|
30169
30119
|
var RequestBodyError = class extends Error {
|
|
@@ -30268,8 +30218,13 @@ function createRoutes(context) {
|
|
|
30268
30218
|
);
|
|
30269
30219
|
return;
|
|
30270
30220
|
}
|
|
30271
|
-
const { pathname } = parseUrl(req);
|
|
30221
|
+
const { pathname: requestPath } = parseUrl(req);
|
|
30272
30222
|
const method = req.method || "GET";
|
|
30223
|
+
const pathname = scopedPathname(requestPath, context.csrfToken);
|
|
30224
|
+
if (pathname === void 0) {
|
|
30225
|
+
emptyNotFound(res);
|
|
30226
|
+
return;
|
|
30227
|
+
}
|
|
30273
30228
|
if (method === "POST") {
|
|
30274
30229
|
const origin = headerValue3(req.headers.origin);
|
|
30275
30230
|
if (!isAllowedEditorOrigin(origin, context.boundPort)) {
|
|
@@ -30290,7 +30245,8 @@ function createRoutes(context) {
|
|
|
30290
30245
|
}
|
|
30291
30246
|
if (pathname === "/editor.html" && method === "GET") {
|
|
30292
30247
|
res.writeHead(200, {
|
|
30293
|
-
"Content-Type": "text/html; charset=utf-8"
|
|
30248
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
30249
|
+
"Referrer-Policy": "no-referrer"
|
|
30294
30250
|
});
|
|
30295
30251
|
res.end(context.editorHtml);
|
|
30296
30252
|
return;
|
|
@@ -31035,18 +30991,13 @@ async function editCommand(args, options = {}) {
|
|
|
31035
30991
|
}
|
|
31036
30992
|
context.boundPort = server.port;
|
|
31037
30993
|
const serverUrl = `http://127.0.0.1:${server.port}`;
|
|
31038
|
-
const editorUrl = `${serverUrl}/editor.html`;
|
|
30994
|
+
const editorUrl = `${serverUrl}${editorSessionPath(csrfToken, "/editor.html")}`;
|
|
31039
30995
|
const {
|
|
31040
30996
|
bundle: editorBundlePath,
|
|
31041
30997
|
css: editorCssPath,
|
|
31042
30998
|
fonts: editorFontsPath
|
|
31043
30999
|
} = editorAssetPaths();
|
|
31044
|
-
context.editorHtml = generateEditorHtml(
|
|
31045
|
-
serverUrl,
|
|
31046
|
-
csrfToken,
|
|
31047
|
-
filePath,
|
|
31048
|
-
!!aiClient
|
|
31049
|
-
);
|
|
31000
|
+
context.editorHtml = generateEditorHtml(filePath, !!aiClient);
|
|
31050
31001
|
context.editorBundlePath = editorBundlePath;
|
|
31051
31002
|
context.editorCssPath = editorCssPath;
|
|
31052
31003
|
context.editorFontsPath = editorFontsPath;
|
|
@@ -31111,7 +31062,7 @@ async function ensureCivilizationProjectName(storage, filePath, data) {
|
|
|
31111
31062
|
await storage.update(filePath, named);
|
|
31112
31063
|
return named;
|
|
31113
31064
|
}
|
|
31114
|
-
function generateEditorHtml(
|
|
31065
|
+
function generateEditorHtml(filePath, aiConfigured) {
|
|
31115
31066
|
const aiAssistHandler = aiConfigured ? `
|
|
31116
31067
|
aiAssist: async function(request) {
|
|
31117
31068
|
const res = await fetch(apiBase + '/api/ai/assist', {
|
|
@@ -31140,7 +31091,7 @@ function generateEditorHtml(apiBase, csrfToken, filePath, aiConfigured) {
|
|
|
31140
31091
|
<meta charset="UTF-8">
|
|
31141
31092
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
31142
31093
|
<title>Rogatio Editor</title>
|
|
31143
|
-
<link rel="stylesheet" href="
|
|
31094
|
+
<link rel="stylesheet" href="vendor/editor.css" />
|
|
31144
31095
|
<style>
|
|
31145
31096
|
html, body { margin: 0; min-height: 100%; }
|
|
31146
31097
|
body {
|
|
@@ -31168,14 +31119,16 @@ function generateEditorHtml(apiBase, csrfToken, filePath, aiConfigured) {
|
|
|
31168
31119
|
<div id="editor-doctor" hidden></div>
|
|
31169
31120
|
<div id="editor-root"></div>
|
|
31170
31121
|
<script type="importmap">
|
|
31171
|
-
{ "imports": { "@rogatio/editor": "
|
|
31122
|
+
{ "imports": { "@rogatio/editor": "./vendor/editor.js" } }
|
|
31172
31123
|
</script>
|
|
31173
31124
|
<script type="module">
|
|
31174
31125
|
import { createEditor } from '@rogatio/editor';
|
|
31175
31126
|
|
|
31176
31127
|
const root = document.getElementById('editor-root');
|
|
31177
|
-
const apiBase =
|
|
31178
|
-
|
|
31128
|
+
const apiBase = location.pathname.endsWith('/editor.html')
|
|
31129
|
+
? location.pathname.slice(0, -'/editor.html'.length)
|
|
31130
|
+
: location.pathname;
|
|
31131
|
+
const csrfToken = apiBase.slice(apiBase.lastIndexOf('/') + 1);
|
|
31179
31132
|
const filePath = ${embedJson(filePath)};
|
|
31180
31133
|
const doctorTitles = ${embedJson(editorPageTitles())};
|
|
31181
31134
|
const serverStoppedJson = ${embedJson(serializeEditorDiagnostics(editorServerStoppedReport(filePath)))};
|
package/package.json
CHANGED