wiki-viewer 2.7.4 → 2.7.6
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +3 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/internal/span/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/pdf/save/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/[token]/asset/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/[token]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/set-root/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/branch/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/refresh/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/backlinks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/file/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-branches/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-checkout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-diff/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-file-info/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-history/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-pull/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/outlinks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0v4uz-4._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/middleware-manifest.json +5 -5
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/{0p1blx45umac6.js → 0hwf-t3aoviy_.js} +2 -2
- package/.next/standalone/next.config.ts +5 -0
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/server.js +1 -1
- package/bin/wiki-viewer.js +121 -22
- package/package.json +1 -1
- /package/.next/standalone/.next/static/{FGEHouLkusE6SPcSxOC3u → GrvEfHFNbgW5qJUpfaeje}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{FGEHouLkusE6SPcSxOC3u → GrvEfHFNbgW5qJUpfaeje}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{FGEHouLkusE6SPcSxOC3u → GrvEfHFNbgW5qJUpfaeje}/_ssgManifest.js +0 -0
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { NextConfig } from "next";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
|
+
import pkg from "./package.json" with { type: "json" };
|
|
5
|
+
|
|
4
6
|
const nextConfig: NextConfig = {
|
|
5
7
|
output: "standalone",
|
|
8
|
+
env: {
|
|
9
|
+
NEXT_PUBLIC_APP_VERSION: pkg.version,
|
|
10
|
+
},
|
|
6
11
|
// Pin tracing root to this repo so a stray lockfile in a parent dir (e.g.
|
|
7
12
|
// ~/package-lock.json) can't make Next nest the standalone output under a
|
|
8
13
|
// subdir and break the `server.js` location the publish prepack checks.
|
|
@@ -15,7 +15,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
|
|
|
15
15
|
const hostname = process.env.HOSTNAME || '0.0.0.0'
|
|
16
16
|
|
|
17
17
|
let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
|
|
18
|
-
const nextConfig = {"env":{},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":false,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/wiki-viewer/wiki-viewer","allowedDevOrigins":["devvm"],"cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/wiki-viewer/wiki-viewer"},"distDirRoot":".next"}
|
|
18
|
+
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"2.7.6"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":false,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/wiki-viewer/wiki-viewer","allowedDevOrigins":["devvm"],"cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/wiki-viewer/wiki-viewer"},"distDirRoot":".next"}
|
|
19
19
|
|
|
20
20
|
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
|
|
21
21
|
|
package/bin/wiki-viewer.js
CHANGED
|
@@ -76,6 +76,7 @@ function parseServeArgs(args) {
|
|
|
76
76
|
let host = process.env.HOSTNAME;
|
|
77
77
|
let useHttps;
|
|
78
78
|
let userSpecifiedPort = false;
|
|
79
|
+
let userSpecifiedHost = false;
|
|
79
80
|
let rootDir;
|
|
80
81
|
let noAuth;
|
|
81
82
|
let sshKey;
|
|
@@ -86,7 +87,7 @@ function parseServeArgs(args) {
|
|
|
86
87
|
for (let i = 0; i < args.length; i++) {
|
|
87
88
|
const a = args[i];
|
|
88
89
|
if (a === "-p" || a === "--port") { port = args[++i] ?? port; userSpecifiedPort = true; }
|
|
89
|
-
else if (a === "-H" || a === "--host") host = args[++i] ?? host;
|
|
90
|
+
else if (a === "-H" || a === "--host") { host = args[++i] ?? host; userSpecifiedHost = true; }
|
|
90
91
|
else if (a === "-e" || a === "--env") { i++; } // consumed by parseEnvFlags
|
|
91
92
|
else if (a === "--https") useHttps = true;
|
|
92
93
|
else if (a === "--no-auth") noAuth = true;
|
|
@@ -97,7 +98,7 @@ function parseServeArgs(args) {
|
|
|
97
98
|
else if (!a.startsWith("-") && rootDir === undefined) rootDir = a;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
return { rootDir, port, host, useHttps, userSpecifiedPort, noAuth: Boolean(noAuth), sshKey, sshPort, sshPassword: Boolean(sshPassword), sshReadOnly: Boolean(sshReadOnly) };
|
|
101
|
+
return { rootDir, port, host, useHttps, userSpecifiedPort, userSpecifiedHost, noAuth: Boolean(noAuth), sshKey, sshPort, sshPassword: Boolean(sshPassword), sshReadOnly: Boolean(sshReadOnly) };
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
// ── ssh (sshfs) targets ──────────────────────────────────────────────────────
|
|
@@ -587,6 +588,85 @@ function runQuiet(cmd, args) {
|
|
|
587
588
|
|
|
588
589
|
// ── service: install ──────────────────────────────────────────────────────────
|
|
589
590
|
|
|
591
|
+
// A persistent service bakes an absolute path to this script into the unit /
|
|
592
|
+
// plist (ExecStart). If we're running from a package-manager scratch cache
|
|
593
|
+
// (`npx wiki-viewer …`, `pnpm dlx …`, or an OS temp dir), that path is deleted
|
|
594
|
+
// the moment the cache is pruned, leaving a service that silently fails on the
|
|
595
|
+
// next reboot. Detect it and refuse, pointing the user at a global install.
|
|
596
|
+
function ephemeralInstallReason() {
|
|
597
|
+
const p = selfScript;
|
|
598
|
+
const sep = path.sep;
|
|
599
|
+
if (p.includes(`${sep}_npx${sep}`)) return "an npx cache";
|
|
600
|
+
if (p.includes(`${sep}dlx-`)) return "a pnpm/yarn dlx cache";
|
|
601
|
+
const tmp = os.tmpdir();
|
|
602
|
+
if (p === tmp || p.startsWith(tmp + sep)) return "a temporary directory";
|
|
603
|
+
return null;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
function requirePersistentInstall() {
|
|
607
|
+
const reason = ephemeralInstallReason();
|
|
608
|
+
if (!reason) return;
|
|
609
|
+
console.error(`Error: cannot install a service from ${reason}.`);
|
|
610
|
+
console.error(` wiki-viewer is running from ${selfScript},`);
|
|
611
|
+
console.error(` which your package manager will delete. A service pointed there would`);
|
|
612
|
+
console.error(` break after the next cache cleanup or reboot.`);
|
|
613
|
+
console.error(``);
|
|
614
|
+
console.error(` Install it globally first, then install the service:`);
|
|
615
|
+
console.error(` npm install -g ${SERVICE_NAME}`);
|
|
616
|
+
console.error(` ${SERVICE_NAME} service install ...`);
|
|
617
|
+
process.exit(1);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// The unit/plist runs node by absolute path. process.execPath is often a
|
|
621
|
+
// version-manager runtime pinned to one Node version (fnm/nvm) — a version bump
|
|
622
|
+
// deletes that path and silently breaks the service. fnm keeps a stable
|
|
623
|
+
// `aliases/default/bin/node` symlink that follows the user's default across
|
|
624
|
+
// upgrades; prefer it. Never use `which node`: under fnm that's an ephemeral
|
|
625
|
+
// per-shell path in /run that vanishes on reboot.
|
|
626
|
+
function fnmRoot() {
|
|
627
|
+
return process.env.FNM_DIR || path.join(os.homedir(), ".local", "share", "fnm");
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
function resolveServiceNode() {
|
|
631
|
+
const exec = process.execPath;
|
|
632
|
+
const looksFnm = exec.includes("/fnm/") || exec.includes("/.fnm/") || exec.includes("fnm_multishells") || exec.includes("/fnm/node-versions/") || exec.includes("/.local/share/fnm/");
|
|
633
|
+
if (looksFnm) {
|
|
634
|
+
const fnmDefault = path.join(fnmRoot(), "aliases", "default", "bin", "node");
|
|
635
|
+
if (existsSync(fnmDefault)) return fnmDefault;
|
|
636
|
+
}
|
|
637
|
+
return exec;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// Symmetric to resolveServiceNode: when this script lives inside an fnm
|
|
641
|
+
// version-pinned global tree (`.../node-versions/<ver>/installation/...`, where
|
|
642
|
+
// `npm install -g` lands under fnm), a Node upgrade or prune deletes that whole
|
|
643
|
+
// tree — including this file. Redirect ExecStart through the stable
|
|
644
|
+
// `aliases/default` symlink, which follows the user's default version.
|
|
645
|
+
function resolveServiceScript() {
|
|
646
|
+
const script = selfScript;
|
|
647
|
+
const pinned = path.join(fnmRoot(), "node-versions") + path.sep;
|
|
648
|
+
if (!script.startsWith(pinned)) return script; // dev checkout / system install: already stable
|
|
649
|
+
const parts = path.relative(path.join(fnmRoot(), "node-versions"), script).split(path.sep);
|
|
650
|
+
// parts = [<ver>, "installation", ...rest]; aliases/default -> the installation dir.
|
|
651
|
+
if (parts[1] !== "installation") return script;
|
|
652
|
+
const durable = path.join(fnmRoot(), "aliases", "default", ...parts.slice(2));
|
|
653
|
+
return existsSync(durable) ? durable : script;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// After resolving the most durable node we can, warn if it's *still* pinned to a
|
|
657
|
+
// version-manager runtime version we couldn't redirect to a stable alias.
|
|
658
|
+
function versionManagedNodeWarning(nodePath) {
|
|
659
|
+
const markers = ["/.nvm/", "/.asdf/", "/.volta/", "/n/versions/", "/fnm_multishells/", "/node-versions/"];
|
|
660
|
+
if (!markers.some((m) => nodePath.includes(m))) return null;
|
|
661
|
+
return (
|
|
662
|
+
`The service will run Node from a version-manager path:\n` +
|
|
663
|
+
` ${nodePath}\n` +
|
|
664
|
+
` If you upgrade or remove that Node version, the service will stop working.\n` +
|
|
665
|
+
` Set a stable default (e.g. \`fnm default <version>\`) or install wiki-viewer\n` +
|
|
666
|
+
` under a system Node, then re-run the install.`
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
|
|
590
670
|
// Pull repeatable `--env KEY=VALUE` (or `-e KEY=VALUE`) pairs out of an argv
|
|
591
671
|
// list. Returns the collected map; the caller has already parsed the rest.
|
|
592
672
|
function parseEnvFlags(args) {
|
|
@@ -607,6 +687,8 @@ function parseEnvFlags(args) {
|
|
|
607
687
|
|
|
608
688
|
function serviceInstall(args) {
|
|
609
689
|
const p = requireSupportedPlatform();
|
|
690
|
+
// Refuse before writing anything if we can't produce a durable ExecStart path.
|
|
691
|
+
requirePersistentInstall();
|
|
610
692
|
|
|
611
693
|
// Capture the run config from flags (falling back to existing config), persist it.
|
|
612
694
|
const cli = parseServeArgs(args);
|
|
@@ -614,21 +696,31 @@ function serviceInstall(args) {
|
|
|
614
696
|
const existing = loadConfig();
|
|
615
697
|
const mergedEnv = { ...(existing.env ?? {}), ...envFlags };
|
|
616
698
|
const cliIsSsh = cli.rootDir != null && looksLikeSshTarget(cli.rootDir);
|
|
699
|
+
// Spread the existing config first so keys we don't manage here (and
|
|
700
|
+
// existing.ssh when this run isn't an SSH target) survive instead of being
|
|
701
|
+
// clobbered back to defaults.
|
|
617
702
|
const cfg = {
|
|
703
|
+
...existing,
|
|
618
704
|
rootDir: cli.rootDir != null
|
|
619
705
|
? (cliIsSsh ? cli.rootDir : path.resolve(cli.rootDir))
|
|
620
706
|
: existing.rootDir ?? null,
|
|
621
|
-
|
|
622
|
-
|
|
707
|
+
// Only let the CLI override the persisted host/port when the flag was
|
|
708
|
+
// explicitly passed. cli.host/cli.port are seeded from HOSTNAME/PORT env, so
|
|
709
|
+
// gating on `??` would let ambient env silently clobber the saved config on
|
|
710
|
+
// every reinstall.
|
|
711
|
+
host: cli.userSpecifiedHost ? cli.host : existing.host ?? "localhost",
|
|
712
|
+
port: cli.userSpecifiedPort ? cli.port : existing.port ?? "3000",
|
|
623
713
|
https: cli.useHttps ?? existing.https ?? false,
|
|
624
|
-
// Persist ssh options so `service run` can remount on boot. Password auth is
|
|
625
|
-
// intentionally NOT persisted — services run non-interactively, so use
|
|
626
|
-
// ssh-agent or --ssh-key for a reboot-persistent SSH workspace.
|
|
627
|
-
...(cliIsSsh
|
|
628
|
-
? { ssh: { ...(cli.sshKey ? { key: cli.sshKey } : {}), ...(cli.sshPort ? { port: cli.sshPort } : {}), ...(cli.sshReadOnly ? { readOnly: true } : {}) } }
|
|
629
|
-
: existing.ssh ? { ssh: existing.ssh } : {}),
|
|
630
|
-
...(Object.keys(mergedEnv).length ? { env: mergedEnv } : {}),
|
|
631
714
|
};
|
|
715
|
+
// Persist ssh options so `service run` can remount on boot. Password auth is
|
|
716
|
+
// intentionally NOT persisted — services run non-interactively, so use
|
|
717
|
+
// ssh-agent or --ssh-key for a reboot-persistent SSH workspace. Only overwrite
|
|
718
|
+
// ssh when this run explicitly targets one; otherwise existing.ssh is kept.
|
|
719
|
+
if (cliIsSsh) {
|
|
720
|
+
cfg.ssh = { ...(cli.sshKey ? { key: cli.sshKey } : {}), ...(cli.sshPort ? { port: cli.sshPort } : {}), ...(cli.sshReadOnly ? { readOnly: true } : {}) };
|
|
721
|
+
}
|
|
722
|
+
if (Object.keys(mergedEnv).length) cfg.env = mergedEnv;
|
|
723
|
+
else delete cfg.env;
|
|
632
724
|
if (cliIsSsh && cli.sshPassword) {
|
|
633
725
|
console.log("⚠️ --ssh-password is ignored for services (non-interactive). Use ssh-agent or --ssh-key.\n");
|
|
634
726
|
}
|
|
@@ -649,6 +741,9 @@ function serviceInstall(args) {
|
|
|
649
741
|
});
|
|
650
742
|
for (const w of warnings) console.log(`⚠️ ${w}\n`);
|
|
651
743
|
|
|
744
|
+
const nodeWarning = versionManagedNodeWarning(resolveServiceNode());
|
|
745
|
+
if (nodeWarning) console.log(`⚠️ ${nodeWarning}\n`);
|
|
746
|
+
|
|
652
747
|
if (p === "linux") installSystemd();
|
|
653
748
|
else installLaunchd();
|
|
654
749
|
}
|
|
@@ -709,13 +804,15 @@ function installSystemd() {
|
|
|
709
804
|
mkdirSync(unitDir, { recursive: true });
|
|
710
805
|
const unitPath = path.join(unitDir, `${SERVICE_NAME}.service`);
|
|
711
806
|
|
|
807
|
+
const nodeBin = resolveServiceNode();
|
|
808
|
+
const scriptPath = resolveServiceScript();
|
|
712
809
|
const unit = `[Unit]
|
|
713
810
|
Description=wiki-viewer local file viewer
|
|
714
811
|
After=network.target
|
|
715
812
|
|
|
716
813
|
[Service]
|
|
717
814
|
Type=simple
|
|
718
|
-
ExecStart=${
|
|
815
|
+
ExecStart=${nodeBin} ${scriptPath} service run
|
|
719
816
|
Restart=on-failure
|
|
720
817
|
RestartSec=3
|
|
721
818
|
Environment=NODE_ENV=production
|
|
@@ -751,6 +848,8 @@ function installLaunchd() {
|
|
|
751
848
|
const outLog = path.join(logDir, "out.log");
|
|
752
849
|
const errLog = path.join(logDir, "err.log");
|
|
753
850
|
|
|
851
|
+
const nodeBin = resolveServiceNode();
|
|
852
|
+
const scriptPath = resolveServiceScript();
|
|
754
853
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
755
854
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
756
855
|
<plist version="1.0">
|
|
@@ -759,8 +858,8 @@ function installLaunchd() {
|
|
|
759
858
|
<string>${LAUNCHD_LABEL}</string>
|
|
760
859
|
<key>ProgramArguments</key>
|
|
761
860
|
<array>
|
|
762
|
-
<string>${
|
|
763
|
-
<string>${
|
|
861
|
+
<string>${nodeBin}</string>
|
|
862
|
+
<string>${scriptPath}</string>
|
|
764
863
|
<string>service</string>
|
|
765
864
|
<string>run</string>
|
|
766
865
|
</array>
|
|
@@ -1013,14 +1112,11 @@ async function runWizard() {
|
|
|
1013
1112
|
}
|
|
1014
1113
|
}
|
|
1015
1114
|
|
|
1016
|
-
// Build and preview the config.
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
https: useHttps,
|
|
1022
|
-
...(Object.keys(env).length ? { env } : {}),
|
|
1023
|
-
};
|
|
1115
|
+
// Build and preview the config. Spread the existing config first so keys the
|
|
1116
|
+
// wizard doesn't touch (e.g. ssh) survive; then explicitly set/clear env.
|
|
1117
|
+
const cfg = { ...existing, rootDir, host, port, https: useHttps };
|
|
1118
|
+
if (Object.keys(env).length) cfg.env = env;
|
|
1119
|
+
else delete cfg.env;
|
|
1024
1120
|
|
|
1025
1121
|
console.log("\nConfiguration:");
|
|
1026
1122
|
console.log(` directory : ${rootDir ?? "(choose in browser)"}`);
|
|
@@ -1053,6 +1149,9 @@ async function runWizard() {
|
|
|
1053
1149
|
console.log("Run it yourself with: wiki-viewer service run");
|
|
1054
1150
|
return;
|
|
1055
1151
|
}
|
|
1152
|
+
requirePersistentInstall();
|
|
1153
|
+
const nodeWarning = versionManagedNodeWarning(resolveServiceNode());
|
|
1154
|
+
if (nodeWarning) console.log(`\n⚠️ ${nodeWarning}\n`);
|
|
1056
1155
|
if (p === "linux") installSystemd();
|
|
1057
1156
|
else installLaunchd();
|
|
1058
1157
|
} else if (choice === "2") {
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|