wiki-viewer 2.9.1 → 2.9.3
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/app-path-routes-manifest.json +0 -4
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +4 -4
- package/.next/standalone/.next/routes-manifest.json +0 -24
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
- 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/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent/activity/route.js +7 -7
- package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/admin/agents/[agentId]/revoke/route.js +5 -5
- package/.next/standalone/.next/server/app/api/agent/admin/agents/[agentId]/revoke/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/admin/agents/route.js +5 -5
- package/.next/standalone/.next/server/app/api/agent/admin/agents/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/approve/route.js +5 -5
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/approve/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/deny/route.js +5 -5
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/deny/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/route.js +5 -5
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js +7 -7
- 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 +9 -9
- 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 +7 -7
- 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 +8 -8
- 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 +8 -8
- 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 +8 -8
- 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 +8 -8
- 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 +8 -8
- 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 +8 -8
- package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js +10 -2
- package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/assets/[...path]/route.js +5 -5
- package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/[...all]/route.js +2 -2
- package/.next/standalone/.next/server/app/api/pdf/save/route.js +8 -8
- 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 +3 -2
- 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 +8 -7
- 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 +8 -8
- package/.next/standalone/.next/server/app/api/share/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/admins/route.js +5 -5
- package/.next/standalone/.next/server/app/api/system/admins/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/api-key/route.js +2 -2
- package/.next/standalone/.next/server/app/api/system/api-key/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/auth-config/route.js +3 -3
- package/.next/standalone/.next/server/app/api/system/auth-config/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/auth-settings/route.js +5 -5
- package/.next/standalone/.next/server/app/api/system/auth-settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/browse/route.js +4 -4
- package/.next/standalone/.next/server/app/api/system/browse/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/config/route.js +3 -3
- package/.next/standalone/.next/server/app/api/system/config/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/pins/route.js +5 -5
- package/.next/standalone/.next/server/app/api/system/pins/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/reveal/route.js +4 -4
- package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/users/route.js +4 -4
- package/.next/standalone/.next/server/app/api/system/users/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/branch/route.js +5 -5
- 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 +5 -5
- 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 +5 -5
- 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 +5 -5
- 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 +4 -4
- 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 +7 -7
- 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 +9 -9
- 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 +7 -7
- 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 +10 -10
- 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 +9 -9
- package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/folder/route.js +7 -7
- 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 +7 -7
- 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 +6 -6
- 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 +7 -7
- 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 +7 -7
- 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 +7 -7
- 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 +8 -8
- 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 +8 -8
- 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 +8 -8
- 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 +7 -7
- 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 +8 -8
- 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 +7 -7
- 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 +8 -8
- 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 +8 -8
- 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 +8 -8
- 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 +8 -8
- 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 +4 -4
- package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/s/[token]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/s/[token]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/s/[token]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/signin/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/signin/page.js +4 -4
- package/.next/standalone/.next/server/app/signin/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/signin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +0 -4
- package/.next/standalone/.next/server/chunks/0p91_next_dist_esm_build_templates_app-route_0ytral2.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.xk8gi._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__00awqt2._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__00sn-o5._.js +16 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0mw1brk._.js → [root-of-the-server]__01y-312._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__12jdw86._.js → [root-of-the-server]__02373p-._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__03_q-~2._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__03c09g7._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__03prziv._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__04vo55d._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__04~wbjj._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__05tbv~.._.js +16 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__068r9h7._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06jm~o8._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07ox9i8._.js +12 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__088zh92._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_5~w8k._.js +20 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_g-.kr._.js +20 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0bdxjy5._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__10c4_fo._.js → [root-of-the-server]__0e1kbl7._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__12v.eva._.js → [root-of-the-server]__0er9oof._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e~2gkf._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0f2frhc._.js +4 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0hgccef._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0egcl8n._.js → [root-of-the-server]__0j40f60._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__04mie79._.js → [root-of-the-server]__0k0t_.e._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0k46u9j._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kau~ca._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kuwuwk._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kvxxt~._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l5io1-._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0md2vr3._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0muj-bp._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0nnxcs7._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0omny3u._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ou7hai._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0r--676._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0r55bc0._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rdt~cr._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0tizmgc._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vr.qhy._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0915i_~._.js → [root-of-the-server]__0x.030x._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__11mhei8._.js → [root-of-the-server]__0xlo2r_._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0yfb5md._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0a7c~hj._.js → [root-of-the-server]__0z5xk6f._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0~gd460._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0~i3blt._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__10p-nga._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__10zrueo._.js +12 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__11ltgmp._.js +20 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__11zy4x1._.js +6 -6
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__12bl1v6._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__12g8s_j._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__13h_w~h._.js +4 -0
- package/.next/standalone/.next/server/chunks/_079xuln._.js +1 -1
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_open_route_actions_1087xu7.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules__pnpm_0aj5g-w._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_0ks~u~e._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_lib_fs_mounts_ts_0ksy80l._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_lib_workspaces_ts_0qon40u._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0bt7d39._.js → 0e.4_sonner_dist_index_mjs_0u2em8w._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{0~w0_katex_dist_katex_mjs_0p7ph25._.js → 0~w0_katex_dist_katex_mjs_018q_uc._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_chunk-5ZQYHXKU_mjs_0z1.978._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_chunk-KSCS5N6A_mjs_0v4oeem._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ybtj28._.js → [root-of-the-server]__02ov~kn._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__13k6~ax._.js → [root-of-the-server]__0n5kphk._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0vglc36._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_00pku9f._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0_.s7b8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0oq8kwv._.js +174 -0
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_04qqrjr._.js → node_modules__pnpm_0.wgpvp._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_09k0q18._.js → node_modules__pnpm_02j0p3a._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0wg48.8._.js → node_modules__pnpm_02yqus6._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_11g2aee._.js → node_modules__pnpm_07bf4mp._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0a4su30._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0a-f4gi._.js → node_modules__pnpm_0a~3f2a._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0819uyi._.js → node_modules__pnpm_0bnc0lk._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0b3l3b4._.js → node_modules__pnpm_0dm.meu._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0rc4s48._.js → node_modules__pnpm_0ebvpwi._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0jp7ggg._.js → node_modules__pnpm_0f.5boy._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ha2xsd._.js → node_modules__pnpm_0f9vj0~._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ypcps.._.js → node_modules__pnpm_0f9vuiw._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_06usij4._.js → node_modules__pnpm_0fa23-q._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0cuckmp._.js → node_modules__pnpm_0g21lw4._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_09ybwhl._.js → node_modules__pnpm_0kdk2ot._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0wjizot._.js → node_modules__pnpm_0kkbph0._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0xp3s_y._.js → node_modules__pnpm_0mv0.4i._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0z~bh__._.js → node_modules__pnpm_0nt22aq._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0o~d81.._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0m2hb6k._.js → node_modules__pnpm_0p4w0~q._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_03ciu.l._.js → node_modules__pnpm_0pv3k.9._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_09c3lg3._.js → node_modules__pnpm_0qmqt0m._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0iuzd3o._.js → node_modules__pnpm_0q~maar._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ldft78._.js → node_modules__pnpm_0s1th-1._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0qhs4r2._.js → node_modules__pnpm_0tdnho_._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0dsnv76._.js → node_modules__pnpm_0w6oo9l._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0eiz-8_._.js → node_modules__pnpm_0x9-_1d._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0gnc95r._.js → node_modules__pnpm_0xq~zku._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0~88b7s._.js → node_modules__pnpm_12nfd13._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_app_s_[token]_page_tsx_0_fzrmd._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
- 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/00_12ekhbvhhp.js +1 -0
- package/.next/standalone/.next/static/chunks/01u~45r8icusu.js +1 -0
- package/.next/standalone/.next/static/chunks/0aeii_m.9~9_t.js +1 -0
- package/.next/standalone/.next/static/chunks/0fm2eul-wqh2f.js +1 -0
- package/.next/standalone/.next/static/chunks/{08usk_~k6d0yf.js → 0k31ncl7m_j9q.js} +2 -2
- package/.next/standalone/.next/static/chunks/0n7px0u5.eizf.css +9 -0
- package/.next/standalone/.next/static/chunks/0qs6cl.~q-0tv.js +1 -0
- package/.next/standalone/.next/static/chunks/0wu_n6m9jg8rn.js +1 -0
- package/.next/standalone/.next/static/chunks/0yixq3fhhpk~9.js +172 -0
- package/.next/standalone/.next/static/chunks/{turbopack-0~8fsjmdvb_1i.js → turbopack-1105gjd__15ti.js} +1 -1
- package/.next/standalone/.test-floor +1 -1
- package/.next/standalone/biome.json +70 -0
- package/.next/standalone/package.json +128 -129
- package/.next/standalone/scripts/format-check.mjs +25 -0
- package/.next/standalone/scripts/test-floor.mjs +86 -37
- package/.next/standalone/server.js +1 -1
- package/README.md +12 -5
- package/bin/cli/config.js +105 -0
- package/bin/cli/prompt.js +36 -0
- package/bin/cli/serve.js +413 -0
- package/bin/cli/service.js +304 -0
- package/bin/cli/update.js +58 -0
- package/bin/cli/wizard.js +134 -0
- package/bin/shared/ssh-target.js +154 -0
- package/bin/wiki-viewer.js +118 -1224
- package/package.json +128 -129
- package/.next/standalone/.next/server/app/api/system/clear-root/route/app-paths-manifest.json +0 -3
- package/.next/standalone/.next/server/app/api/system/clear-root/route/build-manifest.json +0 -9
- package/.next/standalone/.next/server/app/api/system/clear-root/route/server-reference-manifest.json +0 -4
- package/.next/standalone/.next/server/app/api/system/clear-root/route.js +0 -14
- package/.next/standalone/.next/server/app/api/system/clear-root/route.js.map +0 -5
- package/.next/standalone/.next/server/app/api/system/clear-root/route.js.nft.json +0 -1
- package/.next/standalone/.next/server/app/api/system/clear-root/route_client-reference-manifest.js +0 -3
- package/.next/standalone/.next/server/app/api/system/root-status/route/app-paths-manifest.json +0 -3
- package/.next/standalone/.next/server/app/api/system/root-status/route/build-manifest.json +0 -9
- package/.next/standalone/.next/server/app/api/system/root-status/route/server-reference-manifest.json +0 -4
- package/.next/standalone/.next/server/app/api/system/root-status/route.js +0 -14
- package/.next/standalone/.next/server/app/api/system/root-status/route.js.map +0 -5
- package/.next/standalone/.next/server/app/api/system/root-status/route.js.nft.json +0 -1
- package/.next/standalone/.next/server/app/api/system/root-status/route_client-reference-manifest.js +0 -3
- package/.next/standalone/.next/server/app/api/system/set-root/route/app-paths-manifest.json +0 -3
- package/.next/standalone/.next/server/app/api/system/set-root/route/build-manifest.json +0 -9
- package/.next/standalone/.next/server/app/api/system/set-root/route/server-reference-manifest.json +0 -4
- package/.next/standalone/.next/server/app/api/system/set-root/route.js +0 -15
- package/.next/standalone/.next/server/app/api/system/set-root/route.js.map +0 -5
- package/.next/standalone/.next/server/app/api/system/set-root/route.js.nft.json +0 -1
- package/.next/standalone/.next/server/app/api/system/set-root/route_client-reference-manifest.js +0 -3
- package/.next/standalone/.next/server/app/api/wiki/file/route/app-paths-manifest.json +0 -3
- package/.next/standalone/.next/server/app/api/wiki/file/route/build-manifest.json +0 -9
- package/.next/standalone/.next/server/app/api/wiki/file/route/server-reference-manifest.json +0 -4
- package/.next/standalone/.next/server/app/api/wiki/file/route.js +0 -16
- package/.next/standalone/.next/server/app/api/wiki/file/route.js.map +0 -5
- package/.next/standalone/.next/server/app/api/wiki/file/route.js.nft.json +0 -1
- package/.next/standalone/.next/server/app/api/wiki/file/route_client-reference-manifest.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-3eby~._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-bd36s._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0._o62m._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.f~mr1._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.xsx4e._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__01w5s-4._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__02hiw0n._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__037g~yp._.js +0 -20
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__04yzrn9._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__05dk_5q._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__05nk8xg._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__05wicn_._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07i72.r._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__086~~78._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__08h0txl._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__09ezcba._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0au~ncj._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0c-49tx._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0di13ue._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0dkxp4y._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jhwupj._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ker6~l._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0mkrdf0._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0nzjsw9._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o0lsmx._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0omc1-s._.js +0 -20
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0os3ej1._.js +0 -16
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0px8._m._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qe7kxb._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qe8lje._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qox302._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s5ns33._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s6kt0y._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t_s2dg._.js +0 -20
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0tchvup._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0tw6h_5._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wmp13_._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0z8qb~s._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zy2f8y._.js +0 -12
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0~s~szv._.js +0 -16
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1024gkd._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__12abg.4._.js +0 -3
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_clear-root_route_actions_065znew.js +0 -3
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_root-status_route_actions_0stp57y.js +0 -3
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_set-root_route_actions_0vxn8ey.js +0 -3
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_wiki_file_route_actions_0ytnc0i.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/0~w0_katex_dist_katex_mjs_12lt4cp._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0a3bjyp._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_03xt0rl._.js +0 -158
- package/.next/standalone/.next/server/chunks/ssr/_06rf50_._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0i3r51-._.js +0 -158
- package/.next/standalone/.next/server/chunks/ssr/_0jdop6l._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0v4uz-4._.js +0 -19
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0.6uh54._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_00o9din._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_02jnz2o._.js +0 -17
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_03jchtd._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_04xh4re._.js +0 -26
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_07p8tmd._.js +0 -17
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_08jqh.4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0_up15t._.js +0 -17
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0c.b4rt._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0dr38_k._.js +0 -31
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0e-nvo5._.js +0 -45
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0e9l2~p._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0k_8g5d._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0kli5~f._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0n-ec__._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0odzirk._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0ov9ih8._.js +0 -17
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0qb~hug._.js +0 -17
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0t24-57._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0umkew~._.js +0 -17
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0w_fkrb._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0yfe2s1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0~ovwm1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_10-i1v8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_12dmj0l._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_133w.gx._.js +0 -11
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_13y5ncy._.js +0 -3
- package/.next/standalone/.next/static/chunks/0-lsw0io13aha.js +0 -1
- package/.next/standalone/.next/static/chunks/01-v2wyaj~5gn.js +0 -1
- package/.next/standalone/.next/static/chunks/04_l8s7dy454_.js +0 -1
- package/.next/standalone/.next/static/chunks/08yt220_vis~5.js +0 -17
- package/.next/standalone/.next/static/chunks/0a~z4.g.dtxjm.js +0 -156
- package/.next/standalone/.next/static/chunks/0ky8fha87kp0_.js +0 -1
- package/.next/standalone/.next/static/chunks/0nzvnpn.j1~sx.js +0 -1
- package/.next/standalone/.next/static/chunks/0t5bc7buy7sx9.js +0 -156
- package/.next/standalone/.next/static/chunks/0umlolnxs~j3r.js +0 -1
- package/.next/standalone/.next/static/chunks/1012fl5fxholx.js +0 -1
- package/.next/standalone/.next/static/chunks/17isnstdq92js.css +0 -5
- /package/.next/standalone/.next/static/{PA-vcrW5iM2yjespdFmgx → I6ZpQF8Ua7ytNZMW5ZKWH}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{PA-vcrW5iM2yjespdFmgx → I6ZpQF8Ua7ytNZMW5ZKWH}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{PA-vcrW5iM2yjespdFmgx → I6ZpQF8Ua7ytNZMW5ZKWH}/_ssgManifest.js +0 -0
|
@@ -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":{"NEXT_PUBLIC_APP_VERSION":"2.9.
|
|
18
|
+
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"2.9.3"},"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":true,"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/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
<p>
|
|
10
10
|
<a href="https://www.npmjs.com/package/wiki-viewer"><img src="https://img.shields.io/npm/v/wiki-viewer" alt="npm version" /></a>
|
|
11
|
-
<img src="https://img.shields.io/badge/node-%3E%
|
|
11
|
+
<img src="https://img.shields.io/badge/node-%3E%3D20.9.0-brightgreen" alt="Node.js ≥20.9.0" />
|
|
12
12
|
<img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license" />
|
|
13
13
|
</p>
|
|
14
14
|
</div>
|
|
@@ -364,7 +364,9 @@ read it.
|
|
|
364
364
|
- Open a file and use **Share** to mint a link. It serves a rendered, read-only
|
|
365
365
|
view at `/share/<token>`.
|
|
366
366
|
- **Password (optional).** Protect a link with a password; only the hash is
|
|
367
|
-
stored. Visitors unlock before reading.
|
|
367
|
+
stored. Visitors unlock before reading. A successful password POST sets a
|
|
368
|
+
short-lived, scoped, `HttpOnly` cookie derived from the stored hash; the
|
|
369
|
+
password is never accepted in the URL, query string, or logs.
|
|
368
370
|
- **Expiry (optional).** Set a number of days; the link returns `410` once
|
|
369
371
|
expired.
|
|
370
372
|
- **View counts.** Each open increments a counter visible in the share dialog.
|
|
@@ -390,6 +392,10 @@ the file browser it shows a **Launch** button.
|
|
|
390
392
|
|
|
391
393
|
> Launching runs arbitrary project code on the host. Only launch apps you
|
|
392
394
|
> trust. Git-backed (read-only) workspaces still run apps but reject writes.
|
|
395
|
+
>
|
|
396
|
+
> In authenticated multi-user mode, starting or stopping an app requires admin
|
|
397
|
+
> privilege. Set `WIKI_ALLOW_APP_RUNNER=1` to explicitly allow non-admins to
|
|
398
|
+
> launch apps in their workspaces.
|
|
393
399
|
|
|
394
400
|
## Auth and multi-user mode
|
|
395
401
|
|
|
@@ -705,7 +711,7 @@ Note: `AGENT_BEARER_TOKEN` (legacy single-secret mode) does nothing now. The ser
|
|
|
705
711
|
|
|
706
712
|
### Prerequisites
|
|
707
713
|
|
|
708
|
-
- **Node.js** ≥
|
|
714
|
+
- **Node.js** ≥ 20.9.0
|
|
709
715
|
- **pnpm** — `npm install -g pnpm`
|
|
710
716
|
|
|
711
717
|
### Run from source
|
|
@@ -728,7 +734,7 @@ The dev server supports hot reload.
|
|
|
728
734
|
| `pnpm build` | Production build |
|
|
729
735
|
| `pnpm start` | Production server (after `build`) |
|
|
730
736
|
| `pnpm wiki` | CLI entry point (after `build`) |
|
|
731
|
-
| `pnpm test` | Run the proof + auth test suite (
|
|
737
|
+
| `pnpm test` | Run the proof + auth test suite (636 tests, floor 624) |
|
|
732
738
|
|
|
733
739
|
### All environment variables
|
|
734
740
|
|
|
@@ -746,6 +752,7 @@ The dev server supports hot reload.
|
|
|
746
752
|
| `WIKI_OWNER_HOSTS` | csv: extra hostnames trusted for CSRF Origin check | `localhost,127.0.0.1` |
|
|
747
753
|
| `WIKI_ALLOW_INSECURE` | Set to `1` to bypass the prod-https guard (dev / CI only) | unset |
|
|
748
754
|
| `WIKI_ADMIN_EMAILS` | csv: emails treated as admins (seed/override; otherwise first signup is admin) | unset |
|
|
755
|
+
| `WIKI_ALLOW_APP_RUNNER`| Set to `1` to let non-admins launch node apps (host code execution; multi-user risk) | unset |
|
|
749
756
|
| `AGENT_RATE_LIMIT` | Max mutation ops per minute per agent identity | `60` |
|
|
750
757
|
| `WIKI_SSH_PASSWORD` | Password for a `--ssh-password` CLI mount (avoids the interactive prompt) | unset |
|
|
751
758
|
|
|
@@ -878,7 +885,7 @@ wiki-viewer/
|
|
|
878
885
|
│ │ ├── app-runner.ts Launches and supervises node-app child processes
|
|
879
886
|
│ │ └── proof/ Agent protocol core (ops-applier, registry, file-lock)
|
|
880
887
|
│ ├── stores/ Zustand state
|
|
881
|
-
│ ├── tests/proof/ Node test runner suite (
|
|
888
|
+
│ ├── tests/proof/ Node test runner suite (636 tests, floor 624)
|
|
882
889
|
│ └── middleware.ts Cookie-presence gate for UI routes
|
|
883
890
|
├── public/
|
|
884
891
|
├── next.config.ts
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
4
|
+
|
|
5
|
+
export const configDir = path.join(os.homedir(), ".wiki-viewer");
|
|
6
|
+
export const configPath = path.join(configDir, "config.json");
|
|
7
|
+
export const logDir = path.join(configDir, "logs");
|
|
8
|
+
|
|
9
|
+
export function loadConfig() {
|
|
10
|
+
if (!existsSync(configPath)) return {};
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(readFileSync(configPath, "utf8"));
|
|
13
|
+
} catch {
|
|
14
|
+
console.error(`Warning: could not parse ${configPath}, ignoring it`);
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function saveConfig(cfg) {
|
|
20
|
+
mkdirSync(configDir, { recursive: true });
|
|
21
|
+
writeFileSync(configPath, JSON.stringify(cfg, null, 2) + "\n");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Pull repeatable `--env KEY=VALUE` (or `-e KEY=VALUE`) pairs out of an argv
|
|
25
|
+
// list. Returns the collected map; the caller has already parsed the rest.
|
|
26
|
+
export function parseEnvFlags(args) {
|
|
27
|
+
const env = {};
|
|
28
|
+
for (let i = 0; i < args.length; i++) {
|
|
29
|
+
if (args[i] === "--env" || args[i] === "-e") {
|
|
30
|
+
const pair = args[++i];
|
|
31
|
+
if (!pair || !pair.includes("=")) {
|
|
32
|
+
console.error(`Error: --env expects KEY=VALUE (got: ${pair ?? "(nothing)"})`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
const idx = pair.indexOf("=");
|
|
36
|
+
env[pair.slice(0, idx)] = pair.slice(idx + 1);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return env;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function configCommand(args) {
|
|
43
|
+
const cfg = loadConfig();
|
|
44
|
+
|
|
45
|
+
if (args.length === 0 || args[0] === "show" || args[0] === "list") {
|
|
46
|
+
if (!existsSync(configPath)) {
|
|
47
|
+
console.log(`No config yet at ${configPath}`);
|
|
48
|
+
console.log(`Create one with: wiki-viewer service install [dir] [options] [--env KEY=VALUE]`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
console.log(configPath);
|
|
52
|
+
console.log(JSON.stringify(cfg, null, 2));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (args[0] === "set") {
|
|
57
|
+
const pairs = args.slice(1);
|
|
58
|
+
if (pairs.length === 0) {
|
|
59
|
+
console.error("Usage: wiki-viewer config set KEY=VALUE [KEY=VALUE ...]");
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
cfg.env = cfg.env ?? {};
|
|
63
|
+
for (const pair of pairs) {
|
|
64
|
+
const idx = pair.indexOf("=");
|
|
65
|
+
if (idx < 0) { console.error(`Error: expected KEY=VALUE (got: ${pair})`); process.exit(1); }
|
|
66
|
+
cfg.env[pair.slice(0, idx)] = pair.slice(idx + 1);
|
|
67
|
+
}
|
|
68
|
+
saveConfig(cfg);
|
|
69
|
+
console.log(`Updated env in ${configPath}: ${pairs.map((p) => p.split("=")[0]).join(", ")}`);
|
|
70
|
+
if (serviceIsInstalled()) console.log("Run `wiki-viewer service restart` to apply.");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (args[0] === "unset") {
|
|
75
|
+
const keys = args.slice(1);
|
|
76
|
+
if (keys.length === 0) { console.error("Usage: wiki-viewer config unset KEY [KEY ...]"); process.exit(1); }
|
|
77
|
+
cfg.env = cfg.env ?? {};
|
|
78
|
+
for (const k of keys) delete cfg.env[k];
|
|
79
|
+
saveConfig(cfg);
|
|
80
|
+
console.log(`Removed from env: ${keys.join(", ")}`);
|
|
81
|
+
if (serviceIsInstalled()) console.log("Run `wiki-viewer service restart` to apply.");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (args[0] === "path") { console.log(configPath); return; }
|
|
86
|
+
|
|
87
|
+
console.error(`Unknown config command: ${args[0]}`);
|
|
88
|
+
console.error("Try: show | set KEY=VALUE | unset KEY | path");
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// configCommand needs to know whether a service is installed to prompt the user
|
|
93
|
+
// to restart it after an env change. Importing the full service module from
|
|
94
|
+
// config.js would create a circular dependency, so we keep a tiny local check.
|
|
95
|
+
function serviceIsInstalled() {
|
|
96
|
+
const SERVICE_NAME = "wiki-viewer";
|
|
97
|
+
const LAUNCHD_LABEL = "com.wiki-viewer";
|
|
98
|
+
if (process.platform === "linux") {
|
|
99
|
+
return existsSync(path.join(os.homedir(), ".config", "systemd", "user", `${SERVICE_NAME}.service`));
|
|
100
|
+
}
|
|
101
|
+
if (process.platform === "darwin") {
|
|
102
|
+
return existsSync(path.join(os.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`));
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createInterface } from "node:readline";
|
|
2
|
+
import { stdin, stdout } from "node:process";
|
|
3
|
+
|
|
4
|
+
// A prompt helper that survives piped (non-TTY) stdin. node:readline/promises
|
|
5
|
+
// closes the stream between awaited questions when input is piped, so we buffer
|
|
6
|
+
// every line via the 'line' event and hand them out one at a time instead.
|
|
7
|
+
export function makePrompter() {
|
|
8
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
9
|
+
const queue = [];
|
|
10
|
+
const waiters = [];
|
|
11
|
+
let closed = false;
|
|
12
|
+
|
|
13
|
+
rl.on("line", (line) => {
|
|
14
|
+
if (waiters.length) waiters.shift()(line);
|
|
15
|
+
else queue.push(line);
|
|
16
|
+
});
|
|
17
|
+
rl.on("close", () => {
|
|
18
|
+
closed = true;
|
|
19
|
+
while (waiters.length) waiters.shift()(null);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const nextLine = () =>
|
|
23
|
+
new Promise((resolve) => {
|
|
24
|
+
if (queue.length) resolve(queue.shift());
|
|
25
|
+
else if (closed) resolve(null);
|
|
26
|
+
else waiters.push(resolve);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const prompt = async (text) => {
|
|
30
|
+
stdout.write(text);
|
|
31
|
+
const line = await nextLine();
|
|
32
|
+
return line == null ? "" : line;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return { prompt, close: () => rl.close() };
|
|
36
|
+
}
|
package/bin/cli/serve.js
ADDED
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import { spawn, execFileSync, execSync } from "node:child_process";
|
|
2
|
+
import { createServer as createHttpsServer } from "node:https";
|
|
3
|
+
import { request as httpRequest } from "node:http";
|
|
4
|
+
import { createServer as createNetServer } from "node:net";
|
|
5
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, rmSync } from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import os from "node:os";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { makePrompter } from "./prompt.js";
|
|
10
|
+
import { configDir, loadConfig, parseEnvFlags } from "./config.js";
|
|
11
|
+
import {
|
|
12
|
+
looksLikeSshTarget,
|
|
13
|
+
parseSshTarget,
|
|
14
|
+
buildSshfsArgs,
|
|
15
|
+
} from "../shared/ssh-target.js";
|
|
16
|
+
|
|
17
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
export const appRoot = path.resolve(__dirname, "..", "..");
|
|
19
|
+
export const serverJs = path.join(appRoot, ".next", "standalone", "server.js");
|
|
20
|
+
|
|
21
|
+
// Env vars the app reads that the bin can derive or manage on the user's behalf.
|
|
22
|
+
// Everything else in config.env is passed through verbatim.
|
|
23
|
+
const LOCAL_HOSTS = new Set(["localhost", "127.0.0.1", "::1", ""]);
|
|
24
|
+
|
|
25
|
+
const mountsDir = path.join(configDir, "mounts");
|
|
26
|
+
let activeMount = null;
|
|
27
|
+
|
|
28
|
+
export function parseServeArgs(args) {
|
|
29
|
+
let port = process.env.PORT;
|
|
30
|
+
let host = process.env.HOSTNAME;
|
|
31
|
+
let useHttps;
|
|
32
|
+
let userSpecifiedPort = false;
|
|
33
|
+
let userSpecifiedHost = false;
|
|
34
|
+
let rootDir;
|
|
35
|
+
let noAuth;
|
|
36
|
+
let sshKey;
|
|
37
|
+
let sshPort;
|
|
38
|
+
let sshPassword;
|
|
39
|
+
let sshReadOnly;
|
|
40
|
+
|
|
41
|
+
for (let i = 0; i < args.length; i++) {
|
|
42
|
+
const a = args[i];
|
|
43
|
+
if (a === "-p" || a === "--port") { port = args[++i] ?? port; userSpecifiedPort = true; }
|
|
44
|
+
else if (a === "-H" || a === "--host") { host = args[++i] ?? host; userSpecifiedHost = true; }
|
|
45
|
+
else if (a === "-e" || a === "--env") { i++; } // consumed by parseEnvFlags
|
|
46
|
+
else if (a === "--https") useHttps = true;
|
|
47
|
+
else if (a === "--no-auth") noAuth = true;
|
|
48
|
+
else if (a === "--ssh-key") sshKey = args[++i];
|
|
49
|
+
else if (a === "--ssh-port") sshPort = args[++i];
|
|
50
|
+
else if (a === "--ssh-password") sshPassword = true;
|
|
51
|
+
else if (a === "--ssh-readonly") sshReadOnly = true;
|
|
52
|
+
else if (!a.startsWith("-") && rootDir === undefined) rootDir = a;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { rootDir, port, host, useHttps, userSpecifiedPort, userSpecifiedHost, noAuth, sshKey, sshPort, sshPassword: Boolean(sshPassword), sshReadOnly: Boolean(sshReadOnly) };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ── ssh (sshfs) targets ──────────────────────────────────────────────────────
|
|
59
|
+
// Symmetry with the local-directory arg: `wiki-viewer user@host:/path` mounts a
|
|
60
|
+
// remote directory over sshfs and serves it as ROOT_DIR — no local clone. The
|
|
61
|
+
// mount is ephemeral (under ~/.wiki-viewer/mounts) and unmounted on exit. Auth:
|
|
62
|
+
// ssh-agent/host keys by default, --ssh-key <path>, or --ssh-password.
|
|
63
|
+
|
|
64
|
+
function isMountedSync(mp) {
|
|
65
|
+
try {
|
|
66
|
+
if (process.platform === "linux") {
|
|
67
|
+
const m = readFileSync("/proc/mounts", "utf8");
|
|
68
|
+
return m.split("\n").some((l) => { const p = l.split(" "); return p[1] === mp && /fuse/.test(p[2] || ""); });
|
|
69
|
+
}
|
|
70
|
+
const out = execFileSync("mount", [], { encoding: "utf8" });
|
|
71
|
+
return out.split("\n").some((l) => l.includes(` on ${mp} `));
|
|
72
|
+
} catch { return false; }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function unmountSync(mp) {
|
|
76
|
+
const tries = process.platform === "linux"
|
|
77
|
+
? [["fusermount", ["-u", "-z", mp]], ["umount", [mp]]]
|
|
78
|
+
: [["umount", [mp]], ["diskutil", ["unmount", "force", mp]]];
|
|
79
|
+
for (const [bin, a] of tries) { try { execFileSync(bin, a, { stdio: "ignore" }); break; } catch { /* try next */ } }
|
|
80
|
+
try { rmSync(mp, { recursive: false, force: true }); } catch { /* best-effort */ }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function registerMountCleanup() {
|
|
84
|
+
const cleanup = () => { if (activeMount) { const mp = activeMount; activeMount = null; unmountSync(mp); } };
|
|
85
|
+
process.on("exit", cleanup);
|
|
86
|
+
for (const sig of ["SIGINT", "SIGTERM", "SIGHUP"]) {
|
|
87
|
+
process.on(sig, () => { cleanup(); process.exit(0); });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function mountSshTarget({ targetStr, port, keyPath, password, readOnly }) {
|
|
92
|
+
const target = parseSshTarget(targetStr);
|
|
93
|
+
if (!target) {
|
|
94
|
+
console.error(`Error: invalid SSH target '${targetStr}'. Use the form user@host:/abs/path.`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
try { execFileSync("sshfs", ["--version"], { stdio: "ignore" }); }
|
|
98
|
+
catch {
|
|
99
|
+
console.error("Error: sshfs not found. Install sshfs + FUSE (e.g. `apt install sshfs`, `brew install macfuse sshfs`).");
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
mkdirSync(mountsDir, { recursive: true });
|
|
104
|
+
const mp = path.join(mountsDir, `cli-${process.pid}`);
|
|
105
|
+
if (isMountedSync(mp)) unmountSync(mp);
|
|
106
|
+
mkdirSync(mp, { recursive: true });
|
|
107
|
+
|
|
108
|
+
const args = buildSshfsArgs({ target, mountpoint: mp, port, keyPath, password, readOnly });
|
|
109
|
+
registerMountCleanup();
|
|
110
|
+
await new Promise((resolve, reject) => {
|
|
111
|
+
const child = spawn("sshfs", args, { stdio: ["pipe", "ignore", "pipe"] });
|
|
112
|
+
let err = "";
|
|
113
|
+
const t = setTimeout(() => { child.kill("SIGKILL"); reject(new Error("sshfs mount timed out after 25s")); }, 25_000);
|
|
114
|
+
child.stderr.on("data", (d) => { err += d.toString(); });
|
|
115
|
+
child.on("error", (e) => { clearTimeout(t); reject(e); });
|
|
116
|
+
child.on("close", (code) => { clearTimeout(t); code === 0 ? resolve() : reject(new Error(err.trim() || `sshfs exited ${code}`)); });
|
|
117
|
+
if (password != null) child.stdin.write(password + "\n");
|
|
118
|
+
child.stdin.end();
|
|
119
|
+
}).catch((e) => {
|
|
120
|
+
console.error(`Error: sshfs mount failed: ${e.message}`);
|
|
121
|
+
try { unmountSync(mp); } catch { /* ignore */ }
|
|
122
|
+
process.exit(1);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
if (!isMountedSync(mp)) {
|
|
126
|
+
console.error("Error: sshfs reported success but the mount is not live.");
|
|
127
|
+
unmountSync(mp);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
activeMount = mp;
|
|
131
|
+
return mp;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function promptLine(text) {
|
|
135
|
+
const io = makePrompter();
|
|
136
|
+
const ans = await io.prompt(text);
|
|
137
|
+
io.close();
|
|
138
|
+
return ans;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ── config file ────────────────────────────────────────────────────────────
|
|
142
|
+
|
|
143
|
+
// Ad-hoc serve: CLI flags + built-in defaults. The run *shape* (dir/host/port)
|
|
144
|
+
// does NOT read the config file, so an installed service never silently alters
|
|
145
|
+
// a one-off invocation. App-level env (config.env) is still read, because those
|
|
146
|
+
// are settings about the app itself (allowlists, OAuth) rather than the bind.
|
|
147
|
+
export function resolveServeOptions(args) {
|
|
148
|
+
const cli = parseServeArgs(args);
|
|
149
|
+
const cfg = loadConfig();
|
|
150
|
+
const isSsh = cli.rootDir != null && looksLikeSshTarget(cli.rootDir);
|
|
151
|
+
return {
|
|
152
|
+
rootDir: cli.rootDir && !isSsh ? path.resolve(cli.rootDir) : null,
|
|
153
|
+
sshTarget: isSsh ? cli.rootDir : null,
|
|
154
|
+
sshKey: cli.sshKey, sshPort: cli.sshPort, sshPassword: cli.sshPassword, sshReadOnly: cli.sshReadOnly,
|
|
155
|
+
port: String(cli.port ?? "3000"),
|
|
156
|
+
host: cli.host ?? "localhost",
|
|
157
|
+
useHttps: Boolean(cli.useHttps),
|
|
158
|
+
userSpecifiedPort: cli.userSpecifiedPort,
|
|
159
|
+
configEnv: { ...(cfg.env ?? {}), ...(cli.noAuth ? { WIKI_NO_AUTH: "1" } : {}), ...parseEnvFlags(args) },
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Service run: config file is the source of truth. CLI flags (if any) still win
|
|
164
|
+
// so the unit/plist could pass overrides, but normally there are none.
|
|
165
|
+
// Precedence: explicit CLI flags > config file > built-in defaults.
|
|
166
|
+
export function resolveRunOptions(args) {
|
|
167
|
+
const cli = parseServeArgs(args);
|
|
168
|
+
const cfg = loadConfig();
|
|
169
|
+
|
|
170
|
+
const rootDir = cli.rootDir ?? cfg.rootDir ?? null;
|
|
171
|
+
const port = cli.port ?? cfg.port ?? "3000";
|
|
172
|
+
const host = cli.host ?? cfg.host ?? "localhost";
|
|
173
|
+
const useHttps = cli.useHttps ?? cfg.https ?? false;
|
|
174
|
+
const userSpecifiedPort = cli.userSpecifiedPort || cfg.port != null;
|
|
175
|
+
|
|
176
|
+
const isSsh = rootDir != null && looksLikeSshTarget(rootDir);
|
|
177
|
+
return {
|
|
178
|
+
rootDir: rootDir && !isSsh ? path.resolve(rootDir) : null,
|
|
179
|
+
sshTarget: isSsh ? rootDir : null,
|
|
180
|
+
sshKey: cli.sshKey ?? cfg.ssh?.key,
|
|
181
|
+
sshPort: cli.sshPort ?? cfg.ssh?.port,
|
|
182
|
+
sshPassword: cli.sshPassword,
|
|
183
|
+
sshReadOnly: cli.sshReadOnly || Boolean(cfg.ssh?.readOnly),
|
|
184
|
+
port: String(port),
|
|
185
|
+
host,
|
|
186
|
+
useHttps: Boolean(useHttps),
|
|
187
|
+
userSpecifiedPort,
|
|
188
|
+
configEnv: { ...(cfg.env ?? {}), ...(cli.noAuth ? { WIKI_NO_AUTH: "1" } : {}), ...parseEnvFlags(args) },
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// ── environment resolution ───────────────────────────────────────────────────
|
|
193
|
+
|
|
194
|
+
export function isLocalHost(h) {
|
|
195
|
+
return LOCAL_HOSTS.has(h);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Build the env for the spawned server.
|
|
199
|
+
// Precedence (highest first):
|
|
200
|
+
// 1. the shell environment the user launched us with (explicit override)
|
|
201
|
+
// 2. config.env from ~/.wiki-viewer/config.json
|
|
202
|
+
// 3. values derived by the bin from the run options (e.g. BETTER_AUTH_URL)
|
|
203
|
+
export function computeServerEnv({ host, port, useHttps, configEnv }) {
|
|
204
|
+
const warnings = [];
|
|
205
|
+
const derived = {};
|
|
206
|
+
|
|
207
|
+
const scheme = useHttps ? "https" : "http";
|
|
208
|
+
const urlHost = isLocalHost(host) || host === "0.0.0.0" ? "localhost" : host;
|
|
209
|
+
const isSecureContext = useHttps || isLocalHost(host);
|
|
210
|
+
|
|
211
|
+
derived.BETTER_AUTH_URL = `${scheme}://${urlHost}:${port}`;
|
|
212
|
+
|
|
213
|
+
if (!isSecureContext) {
|
|
214
|
+
derived.WIKI_ALLOW_INSECURE = "1";
|
|
215
|
+
warnings.push(
|
|
216
|
+
`Serving plain HTTP on a non-local host (${host}). Browsers treat this as\n` +
|
|
217
|
+
` an insecure context: login cookies, service workers and PDF.js will not\n` +
|
|
218
|
+
` work reliably, and OAuth callbacks will fail.\n` +
|
|
219
|
+
` Fix: re-run with --https, or put a TLS-terminating proxy in front and set\n` +
|
|
220
|
+
` BETTER_AUTH_URL to its public https:// URL (see "env" in ${path.join(configDir, "config.json")}).`,
|
|
221
|
+
);
|
|
222
|
+
} else if (isLocalHost(host) && !useHttps) {
|
|
223
|
+
derived.WIKI_ALLOW_INSECURE = "1";
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const env = { ...derived, ...configEnv };
|
|
227
|
+
|
|
228
|
+
// Note when the shell overrode a derived/config value so the user isn't
|
|
229
|
+
// surprised that --host/--port didn't change the auth URL.
|
|
230
|
+
if (process.env.BETTER_AUTH_URL && process.env.BETTER_AUTH_URL !== env.BETTER_AUTH_URL) {
|
|
231
|
+
warnings.push(
|
|
232
|
+
`BETTER_AUTH_URL is set in your shell (${process.env.BETTER_AUTH_URL}) and\n` +
|
|
233
|
+
` overrides the derived/config value.`,
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return { env, warnings };
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ── HTTPS cert generation ──────────────────────────────────────────────────
|
|
241
|
+
|
|
242
|
+
export function ensureCerts(host) {
|
|
243
|
+
const dir = path.join(configDir, "certs");
|
|
244
|
+
mkdirSync(dir, { recursive: true });
|
|
245
|
+
const keyPath = path.join(dir, "key.pem");
|
|
246
|
+
const certPath = path.join(dir, "cert.pem");
|
|
247
|
+
if (existsSync(keyPath) && existsSync(certPath)) {
|
|
248
|
+
return { key: readFileSync(keyPath), cert: readFileSync(certPath) };
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
execSync("mkcert -version", { stdio: "ignore" });
|
|
252
|
+
execSync(`mkcert -install 2>/dev/null; mkcert -key-file "${keyPath}" -cert-file "${certPath}" localhost 127.0.0.1 "${host}"`, { stdio: "pipe" });
|
|
253
|
+
console.log("🔒 Trusted cert via mkcert");
|
|
254
|
+
} catch {
|
|
255
|
+
try {
|
|
256
|
+
execSync(
|
|
257
|
+
`openssl req -x509 -newkey rsa:2048 -keyout "${keyPath}" -out "${certPath}" -days 825 -nodes -subj "/CN=localhost"`,
|
|
258
|
+
{ stdio: "ignore" },
|
|
259
|
+
);
|
|
260
|
+
console.log("🔒 Self-signed cert (browser will warn once — click through)");
|
|
261
|
+
} catch {
|
|
262
|
+
console.error("Error: --https requires mkcert or openssl");
|
|
263
|
+
process.exit(1);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return { key: readFileSync(keyPath), cert: readFileSync(certPath) };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// ── port availability helpers ──────────────────────────────────────────────
|
|
270
|
+
|
|
271
|
+
export function isPortAvailable(p, h) {
|
|
272
|
+
return new Promise((resolve) => {
|
|
273
|
+
const s = createNetServer();
|
|
274
|
+
s.once("error", () => resolve(false));
|
|
275
|
+
s.once("listening", () => s.close(() => resolve(true)));
|
|
276
|
+
s.listen(Number(p), h);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export async function findNextAvailablePort(startPort, h) {
|
|
281
|
+
let p = Number(startPort);
|
|
282
|
+
while (!(await isPortAvailable(p, h))) p++;
|
|
283
|
+
return String(p);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export function freePort() {
|
|
287
|
+
return new Promise((resolve) => {
|
|
288
|
+
const s = createNetServer();
|
|
289
|
+
s.listen(0, "127.0.0.1", () => {
|
|
290
|
+
const { port: p } = s.address();
|
|
291
|
+
s.close(() => resolve(p));
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function getNetworkAddress() {
|
|
297
|
+
for (const ifaces of Object.values(os.networkInterfaces())) {
|
|
298
|
+
for (const iface of ifaces ?? []) {
|
|
299
|
+
if (iface.family === "IPv4" && !iface.internal) return iface.address;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// ── start ──────────────────────────────────────────────────────────────────
|
|
306
|
+
|
|
307
|
+
export async function start(opts) {
|
|
308
|
+
const { useHttps, configEnv = {} } = opts;
|
|
309
|
+
let resolvedRoot = opts.rootDir;
|
|
310
|
+
let { port, host, userSpecifiedPort } = opts;
|
|
311
|
+
|
|
312
|
+
if (!existsSync(serverJs)) {
|
|
313
|
+
console.error("Error: pre-built server not found at", serverJs);
|
|
314
|
+
console.error("This is a bug – please report it at https://github.com/anh-chu/wiki-viewer/issues");
|
|
315
|
+
process.exit(1);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// SSH target: mount it over sshfs and serve the mount point as ROOT_DIR.
|
|
319
|
+
if (opts.sshTarget) {
|
|
320
|
+
let password = null;
|
|
321
|
+
if (opts.sshPassword) {
|
|
322
|
+
password = process.env.WIKI_SSH_PASSWORD
|
|
323
|
+
?? await promptLine(`SSH password for ${opts.sshTarget}: `);
|
|
324
|
+
}
|
|
325
|
+
console.log(`🔗 Mounting ${opts.sshTarget} over SSH…`);
|
|
326
|
+
resolvedRoot = await mountSshTarget({
|
|
327
|
+
targetStr: opts.sshTarget,
|
|
328
|
+
port: opts.sshPort,
|
|
329
|
+
keyPath: opts.sshKey,
|
|
330
|
+
password,
|
|
331
|
+
readOnly: opts.sshReadOnly,
|
|
332
|
+
});
|
|
333
|
+
console.log(` mounted at ${resolvedRoot}${opts.sshReadOnly ? " (read-only)" : ""}`);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (resolvedRoot) {
|
|
337
|
+
console.log(`📂 ${resolvedRoot}`);
|
|
338
|
+
} else {
|
|
339
|
+
console.log("📂 No directory specified — open the browser to choose one");
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Auto-select next free port when user didn't specify one
|
|
343
|
+
if (!userSpecifiedPort) {
|
|
344
|
+
const available = await isPortAvailable(Number(port), host);
|
|
345
|
+
if (!available) {
|
|
346
|
+
const original = port;
|
|
347
|
+
port = await findNextAvailablePort(Number(port) + 1, host);
|
|
348
|
+
console.log(`⚠️ Port ${original} in use → using ${port} (pass -p <port> to override)`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const internalPort = useHttps ? String(await freePort()) : port;
|
|
353
|
+
const internalHost = useHttps ? "127.0.0.1" : host;
|
|
354
|
+
|
|
355
|
+
const { env: appEnv, warnings } = computeServerEnv({ host, port, useHttps, configEnv });
|
|
356
|
+
for (const w of warnings) console.log(`\n⚠️ ${w}`);
|
|
357
|
+
|
|
358
|
+
const child = spawn(process.execPath, [serverJs], {
|
|
359
|
+
cwd: path.join(appRoot, ".next", "standalone"),
|
|
360
|
+
stdio: "inherit",
|
|
361
|
+
env: {
|
|
362
|
+
...appEnv,
|
|
363
|
+
...process.env,
|
|
364
|
+
...(resolvedRoot ? { ROOT_DIR: resolvedRoot } : {}),
|
|
365
|
+
PORT: internalPort,
|
|
366
|
+
HOSTNAME: internalHost,
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
371
|
+
|
|
372
|
+
if (useHttps) {
|
|
373
|
+
const { key, cert } = ensureCerts(host);
|
|
374
|
+
|
|
375
|
+
const proxy = createHttpsServer({ key, cert }, (req, res) => {
|
|
376
|
+
const options = {
|
|
377
|
+
hostname: internalHost,
|
|
378
|
+
port: Number(internalPort),
|
|
379
|
+
path: req.url,
|
|
380
|
+
method: req.method,
|
|
381
|
+
headers: req.headers,
|
|
382
|
+
};
|
|
383
|
+
const upstream = httpRequest(options, (upRes) => {
|
|
384
|
+
res.writeHead(upRes.statusCode, upRes.headers);
|
|
385
|
+
upRes.pipe(res);
|
|
386
|
+
});
|
|
387
|
+
upstream.on("error", () => res.destroy());
|
|
388
|
+
req.pipe(upstream);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
setTimeout(() => {
|
|
392
|
+
proxy.listen(Number(port), host, () => {
|
|
393
|
+
const scheme = "https";
|
|
394
|
+
const displayHost = host === "0.0.0.0" ? "localhost" : host;
|
|
395
|
+
console.log(`\n ➜ Local: ${scheme}://${displayHost}:${port}`);
|
|
396
|
+
const netAddr = getNetworkAddress();
|
|
397
|
+
if (netAddr && host !== "localhost" && host !== "127.0.0.1") {
|
|
398
|
+
console.log(` ➜ Network: ${scheme}://${netAddr}:${port}`);
|
|
399
|
+
}
|
|
400
|
+
console.log(`\n Listening on ${host}:${port} (--host / -H, --port / -p to rebind)\n`);
|
|
401
|
+
});
|
|
402
|
+
}, 1_000);
|
|
403
|
+
} else {
|
|
404
|
+
const scheme = "http";
|
|
405
|
+
const displayHost = host === "0.0.0.0" ? "localhost" : host;
|
|
406
|
+
console.log(`\n ➜ Local: ${scheme}://${displayHost}:${port}`);
|
|
407
|
+
const netAddr = getNetworkAddress();
|
|
408
|
+
if (netAddr && host !== "localhost" && host !== "127.0.0.1") {
|
|
409
|
+
console.log(` ➜ Network: ${scheme}://${netAddr}:${port}`);
|
|
410
|
+
}
|
|
411
|
+
console.log(`\n Listening on ${host}:${port} (--host / -H, --port / -p to rebind)\n`);
|
|
412
|
+
}
|
|
413
|
+
}
|