@xbghc/warden 0.11.1 → 0.13.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.
- package/README.md +29 -9
- package/dist/cli.js +168 -91
- package/dist/web/assets/index-BsNHVg_q.css +1 -0
- package/dist/web/assets/index-DxvNLKja.js +198 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-BDGIw0fQ.js +0 -198
- package/dist/web/assets/index-CPEr86QO.css +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// bin/cli.ts
|
|
4
|
-
import
|
|
4
|
+
import path10 from "path";
|
|
5
5
|
import { spawn } from "child_process";
|
|
6
6
|
import { existsSync as existsSync2 } from "fs";
|
|
7
7
|
import { fileURLToPath } from "url";
|
|
@@ -812,26 +812,26 @@ var throwNestingLimitExceeded = () => {
|
|
|
812
812
|
};
|
|
813
813
|
|
|
814
814
|
// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/utils/url.js
|
|
815
|
-
var splitPath = (
|
|
816
|
-
const paths =
|
|
815
|
+
var splitPath = (path11) => {
|
|
816
|
+
const paths = path11.split("/");
|
|
817
817
|
if (paths[0] === "") {
|
|
818
818
|
paths.shift();
|
|
819
819
|
}
|
|
820
820
|
return paths;
|
|
821
821
|
};
|
|
822
822
|
var splitRoutingPath = (routePath) => {
|
|
823
|
-
const { groups, path:
|
|
824
|
-
const paths = splitPath(
|
|
823
|
+
const { groups, path: path11 } = extractGroupsFromPath(routePath);
|
|
824
|
+
const paths = splitPath(path11);
|
|
825
825
|
return replaceGroupMarks(paths, groups);
|
|
826
826
|
};
|
|
827
|
-
var extractGroupsFromPath = (
|
|
827
|
+
var extractGroupsFromPath = (path11) => {
|
|
828
828
|
const groups = [];
|
|
829
|
-
|
|
829
|
+
path11 = path11.replace(/\{[^}]+\}/g, (match2, index) => {
|
|
830
830
|
const mark = `@${index}`;
|
|
831
831
|
groups.push([mark, match2]);
|
|
832
832
|
return mark;
|
|
833
833
|
});
|
|
834
|
-
return { groups, path:
|
|
834
|
+
return { groups, path: path11 };
|
|
835
835
|
};
|
|
836
836
|
var replaceGroupMarks = (paths, groups) => {
|
|
837
837
|
for (let i = groups.length - 1; i >= 0; i--) {
|
|
@@ -888,8 +888,8 @@ var getPath = (request) => {
|
|
|
888
888
|
const queryIndex = url.indexOf("?", i);
|
|
889
889
|
const hashIndex = url.indexOf("#", i);
|
|
890
890
|
const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
|
|
891
|
-
const
|
|
892
|
-
return tryDecodeURI(
|
|
891
|
+
const path11 = url.slice(start, end);
|
|
892
|
+
return tryDecodeURI(path11.includes("%25") ? path11.replace(/%25/g, "%2525") : path11);
|
|
893
893
|
} else if (charCode === 63 || charCode === 35) {
|
|
894
894
|
break;
|
|
895
895
|
}
|
|
@@ -906,11 +906,11 @@ var mergePath = (base, sub, ...rest) => {
|
|
|
906
906
|
}
|
|
907
907
|
return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
|
|
908
908
|
};
|
|
909
|
-
var checkOptionalParameter = (
|
|
910
|
-
if (
|
|
909
|
+
var checkOptionalParameter = (path11) => {
|
|
910
|
+
if (path11.charCodeAt(path11.length - 1) !== 63 || !path11.includes(":")) {
|
|
911
911
|
return null;
|
|
912
912
|
}
|
|
913
|
-
const segments =
|
|
913
|
+
const segments = path11.split("/");
|
|
914
914
|
const results = [];
|
|
915
915
|
let basePath = "";
|
|
916
916
|
segments.forEach((segment) => {
|
|
@@ -1052,9 +1052,9 @@ var HonoRequest = class {
|
|
|
1052
1052
|
*/
|
|
1053
1053
|
path;
|
|
1054
1054
|
bodyCache = {};
|
|
1055
|
-
constructor(request,
|
|
1055
|
+
constructor(request, path11 = "/", matchResult = [[]]) {
|
|
1056
1056
|
this.raw = request;
|
|
1057
|
-
this.path =
|
|
1057
|
+
this.path = path11;
|
|
1058
1058
|
this.#matchResult = matchResult;
|
|
1059
1059
|
}
|
|
1060
1060
|
param(key) {
|
|
@@ -1826,8 +1826,8 @@ var Hono = class _Hono {
|
|
|
1826
1826
|
return this;
|
|
1827
1827
|
};
|
|
1828
1828
|
});
|
|
1829
|
-
this.on = (method,
|
|
1830
|
-
for (const p of [
|
|
1829
|
+
this.on = (method, path11, ...handlers) => {
|
|
1830
|
+
for (const p of [path11].flat()) {
|
|
1831
1831
|
this.#path = p;
|
|
1832
1832
|
for (const m of [method].flat()) {
|
|
1833
1833
|
const methodName = m.toUpperCase();
|
|
@@ -1885,8 +1885,8 @@ var Hono = class _Hono {
|
|
|
1885
1885
|
* app.route("/api", app2) // GET /api/user
|
|
1886
1886
|
* ```
|
|
1887
1887
|
*/
|
|
1888
|
-
route(
|
|
1889
|
-
const subApp = this.basePath(
|
|
1888
|
+
route(path11, app) {
|
|
1889
|
+
const subApp = this.basePath(path11);
|
|
1890
1890
|
app.routes.map((r) => {
|
|
1891
1891
|
let handler;
|
|
1892
1892
|
if (app.errorHandler === errorHandler) {
|
|
@@ -1912,9 +1912,9 @@ var Hono = class _Hono {
|
|
|
1912
1912
|
* const api = new Hono().basePath('/api')
|
|
1913
1913
|
* ```
|
|
1914
1914
|
*/
|
|
1915
|
-
basePath(
|
|
1915
|
+
basePath(path11) {
|
|
1916
1916
|
const subApp = this.#clone();
|
|
1917
|
-
subApp._basePath = mergePath(this._basePath,
|
|
1917
|
+
subApp._basePath = mergePath(this._basePath, path11);
|
|
1918
1918
|
return subApp;
|
|
1919
1919
|
}
|
|
1920
1920
|
/**
|
|
@@ -1988,7 +1988,7 @@ var Hono = class _Hono {
|
|
|
1988
1988
|
* })
|
|
1989
1989
|
* ```
|
|
1990
1990
|
*/
|
|
1991
|
-
mount(
|
|
1991
|
+
mount(path11, applicationHandler, options) {
|
|
1992
1992
|
let replaceRequest;
|
|
1993
1993
|
let optionHandler;
|
|
1994
1994
|
if (options) {
|
|
@@ -2015,7 +2015,7 @@ var Hono = class _Hono {
|
|
|
2015
2015
|
return [c.env, executionContext];
|
|
2016
2016
|
};
|
|
2017
2017
|
replaceRequest ||= (() => {
|
|
2018
|
-
const mergedPath = mergePath(this._basePath,
|
|
2018
|
+
const mergedPath = mergePath(this._basePath, path11);
|
|
2019
2019
|
const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
|
|
2020
2020
|
return (request) => {
|
|
2021
2021
|
const url = new URL(request.url);
|
|
@@ -2030,18 +2030,18 @@ var Hono = class _Hono {
|
|
|
2030
2030
|
}
|
|
2031
2031
|
await next();
|
|
2032
2032
|
};
|
|
2033
|
-
this.#addRoute(METHOD_NAME_ALL, mergePath(
|
|
2033
|
+
this.#addRoute(METHOD_NAME_ALL, mergePath(path11, "*"), handler);
|
|
2034
2034
|
return this;
|
|
2035
2035
|
}
|
|
2036
|
-
#addRoute(method,
|
|
2037
|
-
|
|
2036
|
+
#addRoute(method, path11, handler, baseRoutePath) {
|
|
2037
|
+
path11 = mergePath(this._basePath, path11);
|
|
2038
2038
|
const r = {
|
|
2039
2039
|
basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,
|
|
2040
|
-
path:
|
|
2040
|
+
path: path11,
|
|
2041
2041
|
method,
|
|
2042
2042
|
handler
|
|
2043
2043
|
};
|
|
2044
|
-
this.router.add(method,
|
|
2044
|
+
this.router.add(method, path11, [handler, r]);
|
|
2045
2045
|
this.routes.push(r);
|
|
2046
2046
|
}
|
|
2047
2047
|
#handleError(err, c) {
|
|
@@ -2054,10 +2054,10 @@ var Hono = class _Hono {
|
|
|
2054
2054
|
if (method === "HEAD") {
|
|
2055
2055
|
return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
|
|
2056
2056
|
}
|
|
2057
|
-
const
|
|
2058
|
-
const matchResult = this.router.match(method,
|
|
2057
|
+
const path11 = this.getPath(request, { env });
|
|
2058
|
+
const matchResult = this.router.match(method, path11);
|
|
2059
2059
|
const c = new Context(request, {
|
|
2060
|
-
path:
|
|
2060
|
+
path: path11,
|
|
2061
2061
|
matchResult,
|
|
2062
2062
|
env,
|
|
2063
2063
|
executionCtx,
|
|
@@ -2160,7 +2160,7 @@ var createNullObject = () => /* @__PURE__ */ Object.create(null);
|
|
|
2160
2160
|
|
|
2161
2161
|
// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/router/reg-exp-router/matcher.js
|
|
2162
2162
|
var emptyParam = [];
|
|
2163
|
-
function match(method,
|
|
2163
|
+
function match(method, path11) {
|
|
2164
2164
|
const matchers = this.buildAllMatchers();
|
|
2165
2165
|
const match2 = ((method2, path22) => {
|
|
2166
2166
|
const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
|
|
@@ -2176,7 +2176,7 @@ function match(method, path10) {
|
|
|
2176
2176
|
return [matcher[1][index], match3];
|
|
2177
2177
|
});
|
|
2178
2178
|
this.match = match2;
|
|
2179
|
-
return match2(method,
|
|
2179
|
+
return match2(method, path11);
|
|
2180
2180
|
}
|
|
2181
2181
|
|
|
2182
2182
|
// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/router/reg-exp-router/node.js
|
|
@@ -2293,14 +2293,14 @@ var Trie = class {
|
|
|
2293
2293
|
#index = 0;
|
|
2294
2294
|
// dynamic path -> [handler index, param assoc]; static paths are not registered
|
|
2295
2295
|
paths = createNullObject();
|
|
2296
|
-
insert(
|
|
2296
|
+
insert(path11, isStatic) {
|
|
2297
2297
|
if (isStatic) {
|
|
2298
|
-
this.#root.insert(
|
|
2298
|
+
this.#root.insert(path11.split(""), 0, [], this.#context, true);
|
|
2299
2299
|
return;
|
|
2300
2300
|
}
|
|
2301
2301
|
const paramAssoc = [];
|
|
2302
2302
|
const groups = [];
|
|
2303
|
-
let markedPath =
|
|
2303
|
+
let markedPath = path11;
|
|
2304
2304
|
for (let i = 0; ; ) {
|
|
2305
2305
|
let replaced = false;
|
|
2306
2306
|
markedPath = markedPath.replace(/\{[^}]+\}/g, (m) => {
|
|
@@ -2325,7 +2325,7 @@ var Trie = class {
|
|
|
2325
2325
|
}
|
|
2326
2326
|
}
|
|
2327
2327
|
this.#root.insert(tokens, this.#index, paramAssoc, this.#context, false);
|
|
2328
|
-
this.paths[
|
|
2328
|
+
this.paths[path11] = [this.#index++, paramAssoc];
|
|
2329
2329
|
}
|
|
2330
2330
|
buildRegExp() {
|
|
2331
2331
|
let regexp = this.#root.buildRegExpStr();
|
|
@@ -2352,17 +2352,17 @@ var Trie = class {
|
|
|
2352
2352
|
|
|
2353
2353
|
// node_modules/.pnpm/hono@4.13.7/node_modules/hono/dist/router/reg-exp-router/router.js
|
|
2354
2354
|
var wildcardRegExpCache = createNullObject();
|
|
2355
|
-
function buildWildcardRegExp(
|
|
2356
|
-
return wildcardRegExpCache[
|
|
2357
|
-
`^${
|
|
2355
|
+
function buildWildcardRegExp(path11) {
|
|
2356
|
+
return wildcardRegExpCache[path11] ??= new RegExp(
|
|
2357
|
+
`^${path11.replace(
|
|
2358
2358
|
/\/:[^/{}]+(?:\{\[\^\/]\+})?(?=[/{]|$)|\/?\*$|([.\\+*[^\]$()?{}|])/g,
|
|
2359
2359
|
(match2, metaChar) => metaChar ? `\\${metaChar}` : match2 === "/*" ? TAIL_WILDCARD_REG_EXP_STR : match2 === "*" ? ONLY_WILDCARD_REG_EXP_STR : `/:${LABEL_REG_EXP_STR}`
|
|
2360
2360
|
)}$`
|
|
2361
2361
|
);
|
|
2362
2362
|
}
|
|
2363
|
-
function findMiddleware(middleware,
|
|
2363
|
+
function findMiddleware(middleware, path11) {
|
|
2364
2364
|
for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
|
|
2365
|
-
if (buildWildcardRegExp(k).test(
|
|
2365
|
+
if (buildWildcardRegExp(k).test(path11)) {
|
|
2366
2366
|
return [...middleware[k]];
|
|
2367
2367
|
}
|
|
2368
2368
|
}
|
|
@@ -2378,14 +2378,14 @@ var RegExpRouter = class {
|
|
|
2378
2378
|
this.#routes = { [METHOD_NAME_ALL]: createNullObject() };
|
|
2379
2379
|
this.#tries = { [METHOD_NAME_ALL]: new Trie() };
|
|
2380
2380
|
}
|
|
2381
|
-
#insertPath(method,
|
|
2381
|
+
#insertPath(method, path11) {
|
|
2382
2382
|
try {
|
|
2383
|
-
this.#tries[method].insert(
|
|
2383
|
+
this.#tries[method].insert(path11, !/\*|\/:/.test(path11));
|
|
2384
2384
|
} catch (e) {
|
|
2385
|
-
throw e === PATH_ERROR ? new UnsupportedPathError(
|
|
2385
|
+
throw e === PATH_ERROR ? new UnsupportedPathError(path11) : e;
|
|
2386
2386
|
}
|
|
2387
2387
|
}
|
|
2388
|
-
add(method,
|
|
2388
|
+
add(method, path11, handler) {
|
|
2389
2389
|
const middleware = this.#middleware;
|
|
2390
2390
|
const routes = this.#routes;
|
|
2391
2391
|
if (!middleware) {
|
|
@@ -2401,28 +2401,28 @@ var RegExpRouter = class {
|
|
|
2401
2401
|
}
|
|
2402
2402
|
}
|
|
2403
2403
|
}
|
|
2404
|
-
if (
|
|
2405
|
-
|
|
2404
|
+
if (path11 === "/*") {
|
|
2405
|
+
path11 = "*";
|
|
2406
2406
|
}
|
|
2407
2407
|
const methods = method === METHOD_NAME_ALL ? Object.keys(middleware) : [method];
|
|
2408
|
-
if (/\*$/.test(
|
|
2409
|
-
const re = buildWildcardRegExp(
|
|
2408
|
+
if (/\*$/.test(path11)) {
|
|
2409
|
+
const re = buildWildcardRegExp(path11);
|
|
2410
2410
|
for (const m of methods) {
|
|
2411
|
-
if (!middleware[m][
|
|
2412
|
-
this.#insertPath(m,
|
|
2413
|
-
middleware[m][
|
|
2411
|
+
if (!middleware[m][path11]) {
|
|
2412
|
+
this.#insertPath(m, path11);
|
|
2413
|
+
middleware[m][path11] = findMiddleware(middleware[m], path11) || findMiddleware(middleware[METHOD_NAME_ALL], path11) || [];
|
|
2414
2414
|
}
|
|
2415
2415
|
}
|
|
2416
2416
|
for (const handlerMap of [middleware, routes]) {
|
|
2417
2417
|
for (const m of methods) {
|
|
2418
2418
|
for (const p in handlerMap[m]) {
|
|
2419
|
-
re.test(p) && handlerMap[m][p].push([handler,
|
|
2419
|
+
re.test(p) && handlerMap[m][p].push([handler, path11]);
|
|
2420
2420
|
}
|
|
2421
2421
|
}
|
|
2422
2422
|
}
|
|
2423
2423
|
return;
|
|
2424
2424
|
}
|
|
2425
|
-
const paths = checkOptionalParameter(
|
|
2425
|
+
const paths = checkOptionalParameter(path11) || [path11];
|
|
2426
2426
|
for (const path22 of paths) {
|
|
2427
2427
|
for (const m of methods) {
|
|
2428
2428
|
if (!routes[m][path22]) {
|
|
@@ -2451,11 +2451,11 @@ var RegExpRouter = class {
|
|
|
2451
2451
|
const handlerData = [];
|
|
2452
2452
|
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
2453
2453
|
for (const r of [middleware, routes]) {
|
|
2454
|
-
for (const
|
|
2455
|
-
const handlers = r[
|
|
2456
|
-
const pathData = trie.paths[
|
|
2454
|
+
for (const path11 in r) {
|
|
2455
|
+
const handlers = r[path11];
|
|
2456
|
+
const pathData = trie.paths[path11];
|
|
2457
2457
|
if (!pathData) {
|
|
2458
|
-
staticMap[
|
|
2458
|
+
staticMap[path11] = [handlers.map(([h]) => [h, createNullObject()]), emptyParam];
|
|
2459
2459
|
continue;
|
|
2460
2460
|
}
|
|
2461
2461
|
handlerData[pathData[0]] = handlers.map(([h, handlerPath]) => [
|
|
@@ -2479,13 +2479,13 @@ var SmartRouter = class {
|
|
|
2479
2479
|
constructor(init) {
|
|
2480
2480
|
this.#routers = init.routers;
|
|
2481
2481
|
}
|
|
2482
|
-
add(method,
|
|
2482
|
+
add(method, path11, handler) {
|
|
2483
2483
|
if (!this.#routes) {
|
|
2484
2484
|
throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
|
|
2485
2485
|
}
|
|
2486
|
-
this.#routes.push([method,
|
|
2486
|
+
this.#routes.push([method, path11, handler]);
|
|
2487
2487
|
}
|
|
2488
|
-
match(method,
|
|
2488
|
+
match(method, path11) {
|
|
2489
2489
|
if (!this.#routes) {
|
|
2490
2490
|
throw new Error("Fatal error");
|
|
2491
2491
|
}
|
|
@@ -2500,7 +2500,7 @@ var SmartRouter = class {
|
|
|
2500
2500
|
for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {
|
|
2501
2501
|
router.add(...routes[i2]);
|
|
2502
2502
|
}
|
|
2503
|
-
res = router.match(method,
|
|
2503
|
+
res = router.match(method, path11);
|
|
2504
2504
|
} catch (e) {
|
|
2505
2505
|
if (e instanceof UnsupportedPathError) {
|
|
2506
2506
|
continue;
|
|
@@ -2535,9 +2535,9 @@ var Node2 = class _Node2 {
|
|
|
2535
2535
|
#patterns = [];
|
|
2536
2536
|
#pattern;
|
|
2537
2537
|
#params = emptyParams;
|
|
2538
|
-
insert(method,
|
|
2538
|
+
insert(method, path11, handler) {
|
|
2539
2539
|
let curNode = this;
|
|
2540
|
-
const parts = splitRoutingPath(
|
|
2540
|
+
const parts = splitRoutingPath(path11);
|
|
2541
2541
|
const possibleKeys = /* @__PURE__ */ new Set();
|
|
2542
2542
|
let i = 0;
|
|
2543
2543
|
for (const p of parts) {
|
|
@@ -2577,12 +2577,12 @@ var Node2 = class _Node2 {
|
|
|
2577
2577
|
}
|
|
2578
2578
|
}
|
|
2579
2579
|
}
|
|
2580
|
-
search(method,
|
|
2580
|
+
search(method, path11) {
|
|
2581
2581
|
const handlerSets = [];
|
|
2582
2582
|
this.#params = emptyParams;
|
|
2583
2583
|
const curNode = this;
|
|
2584
2584
|
let curNodes = [curNode];
|
|
2585
|
-
const parts = splitPath(
|
|
2585
|
+
const parts = splitPath(path11);
|
|
2586
2586
|
const curNodesQueue = [];
|
|
2587
2587
|
const len = parts.length;
|
|
2588
2588
|
let partOffsets = null;
|
|
@@ -2624,13 +2624,13 @@ var Node2 = class _Node2 {
|
|
|
2624
2624
|
if (matcher !== true) {
|
|
2625
2625
|
if (!partOffsets) {
|
|
2626
2626
|
partOffsets = [];
|
|
2627
|
-
let offset =
|
|
2627
|
+
let offset = path11[0] === "/" ? 1 : 0;
|
|
2628
2628
|
for (let p = 0; p < len; p++) {
|
|
2629
2629
|
partOffsets[p] = offset;
|
|
2630
2630
|
offset += parts[p].length + 1;
|
|
2631
2631
|
}
|
|
2632
2632
|
}
|
|
2633
|
-
const restPathString =
|
|
2633
|
+
const restPathString = path11.slice(partOffsets[i]);
|
|
2634
2634
|
const m = matcher.exec(restPathString);
|
|
2635
2635
|
if (m) {
|
|
2636
2636
|
params[name] = m[0];
|
|
@@ -2690,13 +2690,13 @@ var Node2 = class _Node2 {
|
|
|
2690
2690
|
var TrieRouter = class {
|
|
2691
2691
|
name = "TrieRouter";
|
|
2692
2692
|
#node = new Node2();
|
|
2693
|
-
add(method,
|
|
2694
|
-
for (const result of checkOptionalParameter(
|
|
2693
|
+
add(method, path11, handler) {
|
|
2694
|
+
for (const result of checkOptionalParameter(path11) || [path11]) {
|
|
2695
2695
|
this.#node.insert(method, result, handler);
|
|
2696
2696
|
}
|
|
2697
2697
|
}
|
|
2698
|
-
match(method,
|
|
2699
|
-
return this.#node.search(method,
|
|
2698
|
+
match(method, path11) {
|
|
2699
|
+
return this.#node.search(method, path11);
|
|
2700
2700
|
}
|
|
2701
2701
|
};
|
|
2702
2702
|
|
|
@@ -2965,6 +2965,9 @@ function stageModeFor(t) {
|
|
|
2965
2965
|
if (t.kind === "staged") return "unstage";
|
|
2966
2966
|
return void 0;
|
|
2967
2967
|
}
|
|
2968
|
+
function tracksViewed(t) {
|
|
2969
|
+
return !isLocalTarget(t);
|
|
2970
|
+
}
|
|
2968
2971
|
function localViewKeys(key) {
|
|
2969
2972
|
const t = tryParseTargetKey(key);
|
|
2970
2973
|
const wt = t?.worktree ? { worktree: t.worktree } : {};
|
|
@@ -4251,7 +4254,7 @@ function normalise(raw2, repoRoot) {
|
|
|
4251
4254
|
...typeof v.head === "string" ? { head: v.head } : {}
|
|
4252
4255
|
};
|
|
4253
4256
|
}
|
|
4254
|
-
|
|
4257
|
+
migrateLocalViews(targets);
|
|
4255
4258
|
return {
|
|
4256
4259
|
schemaVersion: 1,
|
|
4257
4260
|
repoRoot: r.repoRoot ?? repoRoot,
|
|
@@ -4267,11 +4270,12 @@ function normalise(raw2, repoRoot) {
|
|
|
4267
4270
|
}
|
|
4268
4271
|
};
|
|
4269
4272
|
}
|
|
4270
|
-
function
|
|
4273
|
+
function migrateLocalViews(targets) {
|
|
4271
4274
|
for (const key of Object.keys(targets).sort()) {
|
|
4272
4275
|
const scope = commentScopeKey(key);
|
|
4273
4276
|
if (scope === key) continue;
|
|
4274
4277
|
const src = targets[key];
|
|
4278
|
+
delete targets[key];
|
|
4275
4279
|
if (src.comments.length === 0) continue;
|
|
4276
4280
|
let dst = targets[scope];
|
|
4277
4281
|
if (!dst) {
|
|
@@ -4279,7 +4283,6 @@ function migrateLocalComments(targets) {
|
|
|
4279
4283
|
targets[scope] = dst;
|
|
4280
4284
|
}
|
|
4281
4285
|
dst.comments.push(...src.comments);
|
|
4282
|
-
src.comments = [];
|
|
4283
4286
|
}
|
|
4284
4287
|
}
|
|
4285
4288
|
var LOCK_STALE_MS = 5e3;
|
|
@@ -4594,9 +4597,9 @@ var TmuxService = class {
|
|
|
4594
4597
|
const sessions = [];
|
|
4595
4598
|
for (const line of output.trimEnd().split("\n")) {
|
|
4596
4599
|
const [id, name, ...parts] = line.split(" ");
|
|
4597
|
-
const
|
|
4598
|
-
if (!id || !/^\$\d+$/.test(id) || !name || !
|
|
4599
|
-
if (await realpath3(
|
|
4600
|
+
const path11 = parts.join(" ");
|
|
4601
|
+
if (!id || !/^\$\d+$/.test(id) || !name || !path11) continue;
|
|
4602
|
+
if (await realpath3(path11).catch(() => null) === root) sessions.push({ id, name, path: path11 });
|
|
4600
4603
|
}
|
|
4601
4604
|
return sessions;
|
|
4602
4605
|
}
|
|
@@ -4852,6 +4855,7 @@ function createApp(opts) {
|
|
|
4852
4855
|
return c.json(info);
|
|
4853
4856
|
});
|
|
4854
4857
|
api.get("/state", async (c) => c.json(await store.load()));
|
|
4858
|
+
api.get("/update", async (c) => c.json(await opts.update ?? null));
|
|
4855
4859
|
api.patch("/prefs", async (c) => {
|
|
4856
4860
|
const body = await c.req.json();
|
|
4857
4861
|
const prefs = await store.update((s) => {
|
|
@@ -4875,8 +4879,7 @@ function createApp(opts) {
|
|
|
4875
4879
|
changedNotices.set(key, notices);
|
|
4876
4880
|
const stale = [];
|
|
4877
4881
|
const state = await store.load();
|
|
4878
|
-
const
|
|
4879
|
-
const viewed = t?.viewed ?? {};
|
|
4882
|
+
const viewed = tracksViewed(ctx.target) ? state.targets[key]?.viewed ?? {} : {};
|
|
4880
4883
|
for (const [p, h] of Object.entries(viewed)) {
|
|
4881
4884
|
const f = diffs.find((d) => d.path === p);
|
|
4882
4885
|
if (!f || f.contentHash !== h) stale.push(p);
|
|
@@ -4925,7 +4928,8 @@ function createApp(opts) {
|
|
|
4925
4928
|
});
|
|
4926
4929
|
api.put("/targets/:key/viewed", async (c) => {
|
|
4927
4930
|
const key = c.req.param("key");
|
|
4928
|
-
await targetCtx(key);
|
|
4931
|
+
const ctx = await targetCtx(key);
|
|
4932
|
+
if (!tracksViewed(ctx.target)) throw badRequest(`${key} keeps no viewed mark: a file there is reviewed once it is staged`, "viewed_not_tracked");
|
|
4929
4933
|
const body = await c.req.json();
|
|
4930
4934
|
if (!body.path) throw badRequest("missing path");
|
|
4931
4935
|
const viewed = await store.update((s) => {
|
|
@@ -5530,6 +5534,70 @@ function reachableFromWindows(port, token, timeoutMs = PROBE_TIMEOUT_MS) {
|
|
|
5530
5534
|
});
|
|
5531
5535
|
}
|
|
5532
5536
|
|
|
5537
|
+
// packages/server/src/update.ts
|
|
5538
|
+
import path9 from "path";
|
|
5539
|
+
import { mkdir as mkdir2, readFile as readFile5, writeFile as writeFile2 } from "fs/promises";
|
|
5540
|
+
var PACKAGE = "@xbghc/warden";
|
|
5541
|
+
var LATEST_URL = "https://registry.npmjs.org/@xbghc%2fwarden/latest";
|
|
5542
|
+
var FETCH_TIMEOUT_MS = 3e3;
|
|
5543
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
5544
|
+
function updateCacheFile(baseDir = dataDir()) {
|
|
5545
|
+
return path9.join(baseDir, "update-check.json");
|
|
5546
|
+
}
|
|
5547
|
+
function updateCheckEnabled(env = process.env) {
|
|
5548
|
+
return !env.WARDEN_NO_UPDATE_CHECK && !env.NO_UPDATE_NOTIFIER && !env.CI;
|
|
5549
|
+
}
|
|
5550
|
+
function isNewer(latest, current) {
|
|
5551
|
+
const parse = (v) => /^(\d+)\.(\d+)\.(\d+)$/.exec(v)?.slice(1).map(Number);
|
|
5552
|
+
const a = parse(latest);
|
|
5553
|
+
const b = parse(current);
|
|
5554
|
+
if (!a || !b) return false;
|
|
5555
|
+
for (let i = 0; i < 3; i++) {
|
|
5556
|
+
if (a[i] !== b[i]) return a[i] > b[i];
|
|
5557
|
+
}
|
|
5558
|
+
return false;
|
|
5559
|
+
}
|
|
5560
|
+
async function fetchLatestFromRegistry() {
|
|
5561
|
+
const res = await fetch(LATEST_URL, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), headers: { accept: "application/json" } });
|
|
5562
|
+
if (!res.ok) throw new Error(`registry answered ${res.status}`);
|
|
5563
|
+
const body = await res.json();
|
|
5564
|
+
if (typeof body.version !== "string") throw new Error("registry answer carries no version");
|
|
5565
|
+
return body.version;
|
|
5566
|
+
}
|
|
5567
|
+
async function readCache(file, now) {
|
|
5568
|
+
try {
|
|
5569
|
+
const cache = JSON.parse(await readFile5(file, "utf8"));
|
|
5570
|
+
if (typeof cache.latest !== "string" || typeof cache.checkedAt !== "number") return void 0;
|
|
5571
|
+
const age = now - cache.checkedAt;
|
|
5572
|
+
return age >= 0 && age < CHECK_INTERVAL_MS ? cache.latest : void 0;
|
|
5573
|
+
} catch {
|
|
5574
|
+
return void 0;
|
|
5575
|
+
}
|
|
5576
|
+
}
|
|
5577
|
+
async function writeCache(file, cache) {
|
|
5578
|
+
try {
|
|
5579
|
+
await mkdir2(path9.dirname(file), { recursive: true });
|
|
5580
|
+
await writeFile2(file, JSON.stringify(cache));
|
|
5581
|
+
} catch {
|
|
5582
|
+
}
|
|
5583
|
+
}
|
|
5584
|
+
async function checkForUpdate(opts) {
|
|
5585
|
+
try {
|
|
5586
|
+
const cacheFile = opts.cacheFile ?? updateCacheFile();
|
|
5587
|
+
const now = (opts.now ?? Date.now)();
|
|
5588
|
+
let latest = await readCache(cacheFile, now);
|
|
5589
|
+
if (latest === void 0) {
|
|
5590
|
+
latest = await (opts.fetchLatest ?? fetchLatestFromRegistry)();
|
|
5591
|
+
await writeCache(cacheFile, { checkedAt: now, latest });
|
|
5592
|
+
}
|
|
5593
|
+
if (!isNewer(latest, opts.current)) return null;
|
|
5594
|
+
const command = opts.npx ? `npx ${PACKAGE}@latest` : `npm i -g ${PACKAGE}@latest`;
|
|
5595
|
+
return { current: opts.current, latest, command };
|
|
5596
|
+
} catch {
|
|
5597
|
+
return null;
|
|
5598
|
+
}
|
|
5599
|
+
}
|
|
5600
|
+
|
|
5533
5601
|
// packages/server/src/index.ts
|
|
5534
5602
|
var HOST = "127.0.0.1";
|
|
5535
5603
|
var DEFAULT_PORT_START = 4100;
|
|
@@ -5554,7 +5622,7 @@ async function startServer(opts) {
|
|
|
5554
5622
|
const stateFile = opts.stateFile ?? stateFilePath(repo.commonRoot);
|
|
5555
5623
|
const store = new StateStore(stateFile, repo.commonRoot);
|
|
5556
5624
|
const instanceToken = randomUUID2();
|
|
5557
|
-
const app = createApp({ repo, store, nvim: new NvimService(), webDir: opts.webDir, instanceToken });
|
|
5625
|
+
const app = createApp({ repo, store, nvim: new NvimService(), webDir: opts.webDir, instanceToken, update: opts.update });
|
|
5558
5626
|
const listen = (p) => new Promise((resolve, reject) => {
|
|
5559
5627
|
const s = serve({ fetch: app.fetch, hostname: HOST, port: p }, () => resolve(s));
|
|
5560
5628
|
s.once("error", reject);
|
|
@@ -5597,13 +5665,14 @@ async function startServer(opts) {
|
|
|
5597
5665
|
}
|
|
5598
5666
|
|
|
5599
5667
|
// bin/cli.ts
|
|
5600
|
-
var VERSION = true ? "0.
|
|
5668
|
+
var VERSION = true ? "0.13.0" : "dev";
|
|
5601
5669
|
function parseArgs(argv) {
|
|
5602
|
-
const args = { repoPath: process.cwd(), open: true, help: false, version: false };
|
|
5670
|
+
const args = { repoPath: process.cwd(), open: true, updateCheck: true, help: false, version: false };
|
|
5603
5671
|
for (let i = 0; i < argv.length; i++) {
|
|
5604
5672
|
const a = argv[i];
|
|
5605
5673
|
if (a === "--no-open") args.open = false;
|
|
5606
5674
|
else if (a === "--open") args.open = true;
|
|
5675
|
+
else if (a === "--no-update-check") args.updateCheck = false;
|
|
5607
5676
|
else if (a === "--port" || a === "-p") {
|
|
5608
5677
|
const v = argv[++i];
|
|
5609
5678
|
if (!v || !/^\d+$/.test(v)) throw new Error("--port requires a number");
|
|
@@ -5615,7 +5684,7 @@ function parseArgs(argv) {
|
|
|
5615
5684
|
} else if (a === "--help" || a === "-h") args.help = true;
|
|
5616
5685
|
else if (a === "--version" || a === "-v") args.version = true;
|
|
5617
5686
|
else if (a.startsWith("-")) throw new Error(`unknown option: ${a}`);
|
|
5618
|
-
else args.repoPath =
|
|
5687
|
+
else args.repoPath = path10.resolve(a);
|
|
5619
5688
|
}
|
|
5620
5689
|
return args;
|
|
5621
5690
|
}
|
|
@@ -5628,6 +5697,8 @@ Options:
|
|
|
5628
5697
|
--port <n>, -p <n> Listen on a fixed port (default: first free port from 4100, and under WSL
|
|
5629
5698
|
the first one the Windows side can reach)
|
|
5630
5699
|
--no-open Do not try to open the browser
|
|
5700
|
+
--no-update-check Do not ask the npm registry whether a newer warden exists
|
|
5701
|
+
(also: WARDEN_NO_UPDATE_CHECK=1, NO_UPDATE_NOTIFIER=1, CI)
|
|
5631
5702
|
-h, --help Show this help
|
|
5632
5703
|
-v, --version Print version
|
|
5633
5704
|
`;
|
|
@@ -5658,16 +5729,16 @@ async function openBrowser(url) {
|
|
|
5658
5729
|
return false;
|
|
5659
5730
|
}
|
|
5660
5731
|
function resolveWebDir() {
|
|
5661
|
-
const here =
|
|
5732
|
+
const here = path10.dirname(fileURLToPath(import.meta.url));
|
|
5662
5733
|
const candidates = [
|
|
5663
5734
|
process.env.WARDEN_WEB_DIR,
|
|
5664
|
-
|
|
5735
|
+
path10.join(here, "web"),
|
|
5665
5736
|
// dist/cli.js -> dist/web
|
|
5666
|
-
|
|
5737
|
+
path10.join(here, "..", "dist", "web")
|
|
5667
5738
|
// bin/cli.ts (tsx dev) -> dist/web
|
|
5668
5739
|
].filter((p) => !!p);
|
|
5669
5740
|
for (const dir of candidates) {
|
|
5670
|
-
if (existsSync2(
|
|
5741
|
+
if (existsSync2(path10.join(dir, "index.html"))) return dir;
|
|
5671
5742
|
}
|
|
5672
5743
|
return void 0;
|
|
5673
5744
|
}
|
|
@@ -5692,9 +5763,12 @@ async function main() {
|
|
|
5692
5763
|
if (!webDir) {
|
|
5693
5764
|
console.error("warning: built web assets not found (dist/web). Only the /api endpoints will be served.");
|
|
5694
5765
|
}
|
|
5766
|
+
const viaNpx = fileURLToPath(import.meta.url).includes(`${path10.sep}_npx${path10.sep}`);
|
|
5767
|
+
const checking = args.updateCheck && VERSION !== "dev" && updateCheckEnabled();
|
|
5768
|
+
const update = checking ? checkForUpdate({ current: VERSION, npx: viaNpx }) : Promise.resolve(null);
|
|
5695
5769
|
let server;
|
|
5696
5770
|
try {
|
|
5697
|
-
server = await startServer({ repoPath: args.repoPath, port: args.port, webDir });
|
|
5771
|
+
server = await startServer({ repoPath: args.repoPath, port: args.port, webDir, update });
|
|
5698
5772
|
} catch (e) {
|
|
5699
5773
|
console.error(`warden: ${e.message}`);
|
|
5700
5774
|
process.exit(1);
|
|
@@ -5715,6 +5789,9 @@ async function main() {
|
|
|
5715
5789
|
const opened = await openBrowser(server.url);
|
|
5716
5790
|
if (!opened) console.log(" (could not open a browser automatically; open the URL manually)");
|
|
5717
5791
|
}
|
|
5792
|
+
void update.then((u) => {
|
|
5793
|
+
if (u) console.log(` update: ${u.latest} is available (running ${u.current}) \u2014 ${u.command}`);
|
|
5794
|
+
});
|
|
5718
5795
|
const shutdown = () => {
|
|
5719
5796
|
server.close().finally(() => process.exit(0));
|
|
5720
5797
|
};
|