six-degrees 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +10 -0
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +39 -11
- package/.next/standalone/.next/required-server-files.json +4 -1
- package/.next/standalone/.next/routes-manifest.json +60 -0
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -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/_tree.segment.rsc +1 -1
- 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/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +10 -10
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +9 -9
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/admin-delete/route.js +3 -2
- package/.next/standalone/.next/server/app/api/admin-delete/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/admin-update/route.js +3 -2
- package/.next/standalone/.next/server/app/api/admin-update/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/bridges/route.js +3 -2
- package/.next/standalone/.next/server/app/api/bridges/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/bulk-import/route.js +3 -2
- package/.next/standalone/.next/server/app/api/bulk-import/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js +9 -0
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/company-scores/legacy/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/company-scores/route.js +3 -2
- package/.next/standalone/.next/server/app/api/company-scores/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/connections/route.js +3 -2
- package/.next/standalone/.next/server/app/api/connections/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/data/export/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/export/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/export/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/export/route.js +7 -0
- package/.next/standalone/.next/server/app/api/data/export/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/export/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/export/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/data/import/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/import/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/import/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/import/route.js +8 -0
- package/.next/standalone/.next/server/app/api/data/import/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/import/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/import/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/data/restart/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/restart/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/restart/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/restart/route.js +8 -0
- package/.next/standalone/.next/server/app/api/data/restart/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/restart/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/restart/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/data/reveal/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/reveal/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/reveal/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/reveal/route.js +7 -0
- package/.next/standalone/.next/server/app/api/data/reveal/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/reveal/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/reveal/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/data/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/data/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/data/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/data/route.js +7 -0
- package/.next/standalone/.next/server/app/api/data/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/data/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/data/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/delete-cluster/route.js +3 -2
- package/.next/standalone/.next/server/app/api/delete-cluster/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/route.js +2 -2
- package/.next/standalone/.next/server/app/api/ingest/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/network/route.js +3 -2
- package/.next/standalone/.next/server/app/api/network/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/notifications/route.js +3 -2
- package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/outreach/route.js +3 -2
- package/.next/standalone/.next/server/app/api/outreach/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/queue/route.js +3 -2
- package/.next/standalone/.next/server/app/api/queue/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/scraper/route.js +3 -2
- package/.next/standalone/.next/server/app/api/scraper/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/settings/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/settings/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/settings/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/settings/route.js +9 -0
- package/.next/standalone/.next/server/app/api/settings/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/settings/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/settings/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js +8 -0
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/settings/sector-preview/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route/build-manifest.json +12 -0
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js +8 -0
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/settings/sector-suggestions/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/setup-profile/route.js +3 -2
- package/.next/standalone/.next/server/app/api/setup-profile/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/unlock/route.js +3 -2
- package/.next/standalone/.next/server/app/api/unlock/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/update/route.js +1 -1
- package/.next/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/update-images/route.js +3 -2
- package/.next/standalone/.next/server/app/api/update-images/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/users/route.js +3 -2
- package/.next/standalone/.next/server/app/api/users/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/avatars/[file]/route.js +2 -1
- package/.next/standalone/.next/server/app/avatars/[file]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/favicon.ico/route.js +2 -1
- package/.next/standalone/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/import/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/import/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/import.html +1 -1
- package/.next/standalone/.next/server/app/import.rsc +12 -12
- package/.next/standalone/.next/server/app/import.segments/_full.segment.rsc +12 -12
- package/.next/standalone/.next/server/app/import.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/import.segments/import/__PAGE__.segment.rsc +11 -11
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +12 -12
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +11 -11
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +12 -12
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/launch/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/launch/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/launch.html +2 -2
- package/.next/standalone/.next/server/app/launch.rsc +12 -12
- package/.next/standalone/.next/server/app/launch.segments/_full.segment.rsc +12 -12
- package/.next/standalone/.next/server/app/launch.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/launch.segments/launch/__PAGE__.segment.rsc +11 -11
- 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/paths/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/paths/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/paths.html +1 -1
- package/.next/standalone/.next/server/app/paths.rsc +12 -12
- package/.next/standalone/.next/server/app/paths.segments/_full.segment.rsc +12 -12
- package/.next/standalone/.next/server/app/paths.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/paths.segments/paths/__PAGE__.segment.rsc +11 -11
- package/.next/standalone/.next/server/app/profile/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/profile/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/profile.html +1 -1
- package/.next/standalone/.next/server/app/profile.rsc +12 -12
- package/.next/standalone/.next/server/app/profile.segments/_full.segment.rsc +12 -12
- package/.next/standalone/.next/server/app/profile.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/profile.segments/profile/__PAGE__.segment.rsc +11 -11
- package/.next/standalone/.next/server/app/queue/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/queue/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/queue.html +1 -1
- package/.next/standalone/.next/server/app/queue.rsc +12 -12
- package/.next/standalone/.next/server/app/queue.segments/_full.segment.rsc +12 -12
- package/.next/standalone/.next/server/app/queue.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/queue.segments/queue/__PAGE__.segment.rsc +11 -11
- package/.next/standalone/.next/server/app/settings/page/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/settings/page/build-manifest.json +20 -0
- package/.next/standalone/.next/server/app/settings/page/next-font-manifest.json +11 -0
- package/.next/standalone/.next/server/app/settings/page/react-loadable-manifest.json +1 -0
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/settings/page.js +13 -0
- package/.next/standalone/.next/server/app/settings/page.js.map +5 -0
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/settings.html +1 -0
- package/.next/standalone/.next/server/app/settings.meta +26 -0
- package/.next/standalone/.next/server/app/settings.rsc +24 -0
- package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +24 -0
- package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +4 -0
- package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +28 -0
- package/.next/standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup.html +1 -1
- package/.next/standalone/.next/server/app/setup.rsc +12 -12
- package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +12 -12
- package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +11 -11
- package/.next/standalone/.next/server/app-paths-manifest.json +10 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-rnla2._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__00la_y0._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07t47cm._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cj5jqc._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e0fei3._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0i5hdu4._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljcioj._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljnyho._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o5-tcg._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qrnous._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t3v1a1._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uag-k5._.js +8 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0um1uey._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wmexuc._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xu34sz._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__133knx1._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__14ou7j5._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__15-17hl._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__16iu0hv._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__19b7mig._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1bbcwub._.js +8 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1eris29._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1gjo_cq._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1kbl21f._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qcm08_._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rphsdk._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1t3rugi._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1w25q0m._.js +3 -0
- package/.next/standalone/.next/server/chunks/_072jl0y._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0lw8_i0._.js +3 -0
- package/.next/standalone/.next/server/chunks/_1_fynia._.js +21 -3
- package/.next/standalone/.next/server/chunks/_1fn30_l._.js +3 -0
- package/.next/standalone/.next/server/chunks/_1itd1o_._.js +2 -1
- package/.next/standalone/.next/server/chunks/_1iwkh8t._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1mxn_lb._.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_company-scores_legacy_route_actions_1ncspu_.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_export_route_actions_1lkimty.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_import_route_actions_1eji0kd.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_restart_route_actions_00_-u6o.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_reveal_route_actions_0-moqtn.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_data_route_actions_0j0w5ep.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_settings_route_actions_1bpm9ac.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_settings_sector-preview_route_actions_0w79454.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_settings_sector-suggestions_route_actions_1eoqugp.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_db-client_15le7cw.js +155 -0
- package/.next/standalone/.next/server/chunks/{lib_rpc_0mc73lk.js → lib_rpc_00tx2sm.js} +1 -1
- package/.next/standalone/.next/server/chunks/lib_rpc_02-qa4d.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_02ndsg2.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_08q5vp6.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0_8i3ft.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0c9d9ti.js +5 -2
- package/.next/standalone/.next/server/chunks/lib_rpc_0huvw-3.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0ip2vdh.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0jzisgh.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_0yi9xvd.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1jyhd0o.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1kn59-i.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1q2jkza.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1vpm1sk.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_rpc_1x6p_31.js +3 -0
- package/.next/standalone/.next/server/chunks/node_modules_next_1zc5q0a._.js +158 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0mocm6d._.js → [root-of-the-server]__0an6blh._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m0255u._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0bipr5s._.js → [root-of-the-server]__1z1j3ek._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_07u8byv._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_08r_mlf._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0ggabjc._.js → _0942v8n._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1djpk8t._.js → _0hl_t7r._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0tb83dw._.js +132 -0
- package/.next/standalone/.next/server/chunks/ssr/_1-87bs1._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_17gui6a._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_settings_page_actions_11x4dq5.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_launch_page_19t0dyd.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_page_1fazqbf.js +4 -4
- package/.next/standalone/.next/server/chunks/ssr/app_profile_page_0u3-l5y.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_queue_page_0c6znd6.js +5 -5
- package/.next/standalone/.next/server/chunks/ssr/app_settings_page_1f8mjj_.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_setup_page_1-282zx.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/lib_0i8v-s3._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_1f8t_rp._.js +23 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_1nkgb45._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_01xbj_9._.js → node_modules_1wax83z._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_00nap8h._.js → node_modules_next_dist_1bunoni._.js} +2 -2
- package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0pco7a6._.js +2 -2
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/middleware-manifest.json +15 -7
- package/.next/standalone/.next/server/next-font-manifest.js +1 -1
- package/.next/standalone/.next/server/next-font-manifest.json +4 -0
- 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/prefetch-hints.json +14 -0
- 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/06x3jiiz96m5t.js +1 -0
- package/.next/standalone/.next/static/chunks/{34at5d2ifl62i.js → 0ngx9s6-zgshe.js} +5 -5
- package/.next/standalone/.next/static/chunks/0q-_khndfxubv.js +2 -0
- package/.next/standalone/.next/static/chunks/1c79veqedvubt.js +1 -0
- package/.next/standalone/.next/static/chunks/1chp3nx45meg5.js +44 -0
- package/.next/standalone/.next/static/chunks/1irqj0lf-fu3d.js +1 -0
- package/.next/standalone/.next/static/chunks/1uadqylrod5_v.js +1 -0
- package/.next/standalone/.next/static/chunks/23u0zclgwpc4d.js +1 -0
- package/.next/standalone/.next/static/chunks/289ktj97di6zg.js +1 -0
- package/.next/standalone/.next/static/chunks/2b3lmf8e6uj8m.js +16 -0
- package/.next/standalone/.next/static/chunks/2jz311xl1pp_8.js +1 -0
- package/.next/standalone/.next/static/chunks/3npq5yd7c4dmn.js +2 -0
- package/.next/standalone/.next/static/qqqcxvzBUizkECrT4swyK/_clientMiddlewareManifest.js +14 -0
- package/.next/standalone/CHANGELOG.md +298 -0
- package/.next/standalone/CONTRIBUTING.md +5 -2
- package/.next/standalone/README.md +138 -30
- package/.next/standalone/SECURITY.md +117 -10
- package/.next/standalone/app/api/company-scores/legacy/route.js +32 -0
- package/.next/standalone/app/api/company-scores/route.js +20 -11
- package/.next/standalone/app/api/data/export/route.js +49 -0
- package/.next/standalone/app/api/data/import/route.js +83 -0
- package/.next/standalone/app/api/data/restart/route.js +37 -0
- package/.next/standalone/app/api/data/reveal/route.js +14 -0
- package/.next/standalone/app/api/data/route.js +39 -0
- package/.next/standalone/app/api/ingest/route.js +15 -47
- package/.next/standalone/app/api/scraper/route.js +264 -125
- package/.next/standalone/app/api/settings/route.js +58 -0
- package/.next/standalone/app/api/settings/sector-preview/route.js +38 -0
- package/.next/standalone/app/api/settings/sector-suggestions/route.js +20 -0
- package/.next/standalone/app/api/update/route.js +188 -23
- package/.next/standalone/app/avatars/[file]/route.js +4 -2
- package/.next/standalone/app/components/CompanyScores.js +28 -7
- package/.next/standalone/app/components/EmptyState.js +8 -0
- package/.next/standalone/app/components/ForceGraph.js +39 -35
- package/.next/standalone/app/components/LegacyScoresCard.js +129 -0
- package/.next/standalone/app/components/Sidebar.js +11 -10
- package/.next/standalone/app/components/UpdatePanel.js +306 -119
- package/.next/standalone/app/components/UserProvider.js +4 -3
- package/.next/standalone/app/components/settings/DataSection.js +437 -0
- package/.next/standalone/app/components/settings/SectorSection.js +445 -0
- package/.next/standalone/app/components/ui.js +62 -0
- package/.next/standalone/app/launch/page.js +30 -20
- package/.next/standalone/app/page.js +13 -0
- package/.next/standalone/app/paths/page.js +12 -4
- package/.next/standalone/app/profile/page.js +41 -8
- package/.next/standalone/app/queue/page.js +8 -2
- package/.next/standalone/app/settings/page.js +96 -0
- package/.next/standalone/app/setup/page.js +32 -16
- package/.next/standalone/bin/args.mjs +44 -0
- package/.next/standalone/bin/six-degrees.mjs +9 -15
- package/.next/standalone/lib/companies.js +44 -119
- package/.next/standalone/lib/csv.js +8 -0
- package/.next/standalone/lib/data-export.js +170 -0
- package/.next/standalone/lib/data-folder.js +238 -0
- package/.next/standalone/lib/data-import.js +878 -0
- package/.next/standalone/lib/db-client.js +48 -3
- package/.next/standalone/lib/durable.js +73 -0
- package/.next/standalone/lib/gate.js +90 -1
- package/.next/standalone/lib/ingest.js +40 -0
- package/.next/standalone/lib/legacy-offer.js +185 -0
- package/.next/standalone/lib/legacy-scores.js +77 -0
- package/.next/standalone/lib/linkedin-limits.js +124 -1
- package/.next/standalone/lib/rpc.js +121 -13
- package/.next/standalone/lib/sample-stats.js +16 -0
- package/.next/standalone/lib/scan-progress.js +13 -0
- package/.next/standalone/lib/scan-state.js +53 -0
- package/.next/standalone/lib/scanner-python.js +685 -0
- package/.next/standalone/lib/scanner-setup.js +104 -0
- package/.next/standalone/lib/scoring.js +747 -138
- package/.next/standalone/lib/scraper-client.js +9 -5
- package/.next/standalone/lib/sector-directory.js +1532 -0
- package/.next/standalone/lib/sector-focus.js +163 -0
- package/.next/standalone/lib/sector-labels.js +81 -0
- package/.next/standalone/lib/settings-effects.js +59 -0
- package/.next/standalone/lib/settings.js +83 -0
- package/.next/standalone/lib/updater-job.js +838 -0
- package/.next/standalone/lib/updater.js +494 -0
- package/.next/standalone/middleware.js +25 -28
- package/.next/standalone/next.config.mjs +19 -3
- package/.next/standalone/package-lock.json +2 -2
- package/.next/standalone/package.json +1 -2
- package/.next/standalone/scripts/apply-update.sh +482 -0
- package/.next/standalone/scripts/build-app.mjs +251 -9
- package/.next/standalone/scripts/requirements.txt +106 -4
- package/.next/standalone/scripts/test-release-server.mjs +143 -0
- package/.next/standalone/server.js +1 -1
- package/.next/static/chunks/06x3jiiz96m5t.js +1 -0
- package/.next/static/chunks/{34at5d2ifl62i.js → 0ngx9s6-zgshe.js} +5 -5
- package/.next/static/chunks/0q-_khndfxubv.js +2 -0
- package/.next/static/chunks/1c79veqedvubt.js +1 -0
- package/.next/static/chunks/1chp3nx45meg5.js +44 -0
- package/.next/static/chunks/1irqj0lf-fu3d.js +1 -0
- package/.next/static/chunks/1uadqylrod5_v.js +1 -0
- package/.next/static/chunks/23u0zclgwpc4d.js +1 -0
- package/.next/static/chunks/289ktj97di6zg.js +1 -0
- package/.next/static/chunks/2b3lmf8e6uj8m.js +16 -0
- package/.next/static/chunks/2jz311xl1pp_8.js +1 -0
- package/.next/static/chunks/3npq5yd7c4dmn.js +2 -0
- package/.next/static/qqqcxvzBUizkECrT4swyK/_clientMiddlewareManifest.js +14 -0
- package/CHANGELOG.md +298 -0
- package/README.md +138 -30
- package/SECURITY.md +117 -10
- package/bin/args.mjs +44 -0
- package/bin/six-degrees.mjs +9 -15
- package/lib/companies.js +44 -119
- package/lib/csv.js +8 -0
- package/lib/data-export.js +170 -0
- package/lib/data-folder.js +238 -0
- package/lib/data-import.js +878 -0
- package/lib/db-client.js +48 -3
- package/lib/durable.js +73 -0
- package/lib/gate.js +90 -1
- package/lib/ingest.js +40 -0
- package/lib/legacy-offer.js +185 -0
- package/lib/legacy-scores.js +77 -0
- package/lib/linkedin-limits.js +124 -1
- package/lib/rpc.js +121 -13
- package/lib/sample-stats.js +16 -0
- package/lib/scan-progress.js +13 -0
- package/lib/scan-state.js +53 -0
- package/lib/scanner-python.js +685 -0
- package/lib/scanner-setup.js +104 -0
- package/lib/scoring.js +747 -138
- package/lib/scraper-client.js +9 -5
- package/lib/sector-directory.js +1532 -0
- package/lib/sector-focus.js +163 -0
- package/lib/sector-labels.js +81 -0
- package/lib/settings-effects.js +59 -0
- package/lib/settings.js +83 -0
- package/lib/updater-job.js +838 -0
- package/lib/updater.js +494 -0
- package/package.json +1 -2
- package/scripts/requirements.txt +106 -4
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jrmmj-._.js +0 -150
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qx548g._.js +0 -151
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1an3leo._.js +0 -150
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1m8zedk._.js +0 -155
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1zor0ys._.js +0 -3
- package/.next/standalone/.next/server/chunks/_0_rp-01._.js +0 -3
- package/.next/standalone/.next/server/chunks/_0hzdk79._.js +0 -3
- package/.next/standalone/.next/server/chunks/_0ow7u5r._.js +0 -3
- package/.next/standalone/.next/server/chunks/_0t0zc2d._.js +0 -3
- package/.next/standalone/.next/server/chunks/_0wa631d._.js +0 -3
- package/.next/standalone/.next/server/chunks/_13ccnao._.js +0 -3
- package/.next/standalone/.next/server/chunks/_13es063._.js +0 -3
- package/.next/standalone/.next/server/chunks/_142872j._.js +0 -3
- package/.next/standalone/.next/server/chunks/_18wsb_a._.js +0 -8
- package/.next/standalone/.next/server/chunks/_1e-4h5h._.js +0 -3
- package/.next/standalone/.next/server/chunks/_1gvvd7n._.js +0 -158
- package/.next/standalone/.next/server/chunks/_1moda66._.js +0 -3
- package/.next/standalone/.next/server/chunks/_1p6ghzv._.js +0 -3
- package/.next/standalone/.next/server/chunks/_1xmmi_v._.js +0 -3
- package/.next/standalone/.next/server/chunks/_1z-yrlf._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0bf3x4q._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_paths_page_1ol90m7.js +0 -4
- package/.next/standalone/.next/static/ZGTiDrZ5NHGETgGdlhssu/_clientMiddlewareManifest.js +0 -6
- package/.next/standalone/.next/static/chunks/0jk64vo17avsb.js +0 -1
- package/.next/standalone/.next/static/chunks/0s65dsrthylo6.js +0 -2
- package/.next/standalone/.next/static/chunks/0uyfdhi8dek85.js +0 -16
- package/.next/standalone/.next/static/chunks/220-ne82aus0c.js +0 -44
- package/.next/standalone/.next/static/chunks/229haorf0f19b.js +0 -2
- package/.next/standalone/.next/static/chunks/2g54uafnwuakc.js +0 -1
- package/.next/standalone/.next/static/chunks/2spwqs6b6dx13.js +0 -1
- package/.next/standalone/.next/static/chunks/38dlepuubiox0.js +0 -1
- package/.next/standalone/scripts/score-connections.sql +0 -80
- package/.next/standalone/scripts/score_new_connections.sql +0 -77
- package/.next/standalone/site/app.js +0 -84
- package/.next/standalone/site/index.html +0 -221
- package/.next/standalone/site/style.css +0 -155
- package/.next/standalone/site/video/install-mac-poster.jpg +0 -0
- package/.next/standalone/site/video/install-mac.mp4 +0 -0
- package/.next/standalone/site/video/linux-poster.jpg +0 -0
- package/.next/standalone/site/video/linux.mp4 +0 -0
- package/.next/standalone/site/video/scan-poster.jpg +0 -0
- package/.next/standalone/site/video/scan.mp4 +0 -0
- package/.next/static/ZGTiDrZ5NHGETgGdlhssu/_clientMiddlewareManifest.js +0 -6
- package/.next/static/chunks/0jk64vo17avsb.js +0 -1
- package/.next/static/chunks/0s65dsrthylo6.js +0 -2
- package/.next/static/chunks/0uyfdhi8dek85.js +0 -16
- package/.next/static/chunks/220-ne82aus0c.js +0 -44
- package/.next/static/chunks/229haorf0f19b.js +0 -2
- package/.next/static/chunks/2g54uafnwuakc.js +0 -1
- package/.next/static/chunks/2spwqs6b6dx13.js +0 -1
- package/.next/static/chunks/38dlepuubiox0.js +0 -1
- package/scripts/score_new_connections.sql +0 -77
- /package/.next/standalone/.next/static/{ZGTiDrZ5NHGETgGdlhssu → qqqcxvzBUizkECrT4swyK}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{ZGTiDrZ5NHGETgGdlhssu → qqqcxvzBUizkECrT4swyK}/_ssgManifest.js +0 -0
- /package/.next/static/{ZGTiDrZ5NHGETgGdlhssu → qqqcxvzBUizkECrT4swyK}/_buildManifest.js +0 -0
- /package/.next/static/{ZGTiDrZ5NHGETgGdlhssu → qqqcxvzBUizkECrT4swyK}/_ssgManifest.js +0 -0
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
//
|
|
13
13
|
// What this removes: installing Node, cloning, npm install, and typing a
|
|
14
14
|
// command. The Node runtime is bundled, so the app has no prerequisites at all
|
|
15
|
-
// for the CSV path — download, double-click, drop in your export.
|
|
15
|
+
// for the CSV path — download, double-click, drop in your export. The Electron
|
|
16
|
+
// app also carries the scanner's own Python with its packages installed
|
|
17
|
+
// (bundlePython, DESKTOP.md D2), so scanning needs no install step either.
|
|
16
18
|
//
|
|
17
|
-
// What it does NOT remove:
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
19
|
+
// What it does NOT remove: Google Chrome, which the scanner drives. It stays a
|
|
20
|
+
// runtime prerequisite and the Scan page already detects it. Bundling a
|
|
21
|
+
// Chromium instead would make the scanner MORE detectable, not less, which
|
|
22
|
+
// defeats the point of driving the user's real browser.
|
|
21
23
|
//
|
|
22
24
|
// Unsigned, because notarisation needs a paid Apple Developer account. macOS
|
|
23
25
|
// will refuse the first launch; the user allows it once in System Settings.
|
|
@@ -25,13 +27,24 @@
|
|
|
25
27
|
// separate "app is damaged" failure that unsigned arm64 binaries otherwise hit.
|
|
26
28
|
|
|
27
29
|
import { execFileSync } from 'node:child_process';
|
|
28
|
-
import {
|
|
30
|
+
import { createHash } from 'node:crypto';
|
|
31
|
+
import {
|
|
32
|
+
mkdirSync, rmSync, cpSync, writeFileSync, existsSync, chmodSync, readFileSync, symlinkSync, lstatSync, renameSync,
|
|
33
|
+
readlinkSync, readdirSync, openSync, readSync, closeSync, realpathSync,
|
|
34
|
+
} from 'node:fs';
|
|
29
35
|
import path from 'node:path';
|
|
30
36
|
import os from 'node:os';
|
|
31
37
|
import { fileURLToPath } from 'node:url';
|
|
38
|
+
import {
|
|
39
|
+
standaloneBuild, downloadVerified, machoSlices, machoSlice, megabytes, IMPORTS,
|
|
40
|
+
} from '../lib/scanner-python.js';
|
|
32
41
|
|
|
33
42
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
34
43
|
const pkg = JSON.parse(readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
|
|
44
|
+
// The oldest macOS the app runs on: the bundled Node 24 needs 13.5 (Electron
|
|
45
|
+
// itself needs 13). Written into Info.plist, and every program in the bundled
|
|
46
|
+
// Python is checked against it (checkPython).
|
|
47
|
+
const MACOS_MIN = '13.5';
|
|
35
48
|
|
|
36
49
|
const NODE_VERSION = process.env.BUNDLE_NODE || 'v24.21.0';
|
|
37
50
|
const ARCH = process.env.BUNDLE_ARCH || (os.arch() === 'x64' ? 'x64' : 'arm64');
|
|
@@ -134,9 +147,13 @@ try {
|
|
|
134
147
|
for (const rel of untracked) console.log(` ${rel}`);
|
|
135
148
|
}
|
|
136
149
|
} catch { /* not a git checkout: nothing to compare against */ }
|
|
137
|
-
// The
|
|
150
|
+
// The files the app runs from scripts/, copied by name so the app never
|
|
151
|
+
// depends on what Next's tracing happens to bring along (TRAPS §27): the
|
|
152
|
+
// scanner the Scan page runs, and apply-update.sh, the in-app updater's helper.
|
|
153
|
+
// The helper ships inside the app, so the version that swaps the app is the one
|
|
154
|
+
// the user is running, never a script fetched from the main branch.
|
|
138
155
|
for (const rel of ['scripts/scrape.py', 'scripts/image_store.py', 'scripts/requirements.txt',
|
|
139
|
-
'scripts/
|
|
156
|
+
'scripts/audit-avatars.mjs', 'scripts/apply-update.sh']) {
|
|
140
157
|
const from = path.join(ROOT, rel);
|
|
141
158
|
if (existsSync(from)) {
|
|
142
159
|
mkdirSync(path.join(SERVER_DIR, path.dirname(rel)), { recursive: true });
|
|
@@ -171,6 +188,8 @@ export SIX_DEGREES_BIND=127.0.0.1
|
|
|
171
188
|
export NEXT_TELEMETRY_DISABLED=1
|
|
172
189
|
export SIX_DEGREES_ROOT="$HERE/app"
|
|
173
190
|
export SIX_DEGREES_INSTALL=mac-app
|
|
191
|
+
# This app's own bundle, for the in-app updater (lib/updater.js runningBundle).
|
|
192
|
+
export SIX_DEGREES_APP="$(cd "$HERE/../.." && pwd)"
|
|
174
193
|
export HOSTNAME=127.0.0.1
|
|
175
194
|
|
|
176
195
|
# Walk up from 6363 so a second copy does not fight the first.
|
|
@@ -308,7 +327,7 @@ async function buildElectronShell() {
|
|
|
308
327
|
darwinDarkModeSupport: true,
|
|
309
328
|
// The bundled Node 24 needs macOS 13.5 (Electron itself needs 13), so say
|
|
310
329
|
// so, and macOS explains it instead of the app failing to start.
|
|
311
|
-
extendInfo: { LSMinimumSystemVersion:
|
|
330
|
+
extendInfo: { LSMinimumSystemVersion: MACOS_MIN },
|
|
312
331
|
osxSign: false, // signed ad hoc below, after everything is in place
|
|
313
332
|
});
|
|
314
333
|
console.log(` Electron ${electronVersion} (${ARCH})`);
|
|
@@ -316,14 +335,237 @@ async function buildElectronShell() {
|
|
|
316
335
|
renameSync(path.join(built, `${APP_NAME}.app`), APP);
|
|
317
336
|
rmSync(STAGE, { recursive: true, force: true });
|
|
318
337
|
|
|
338
|
+
// Put straight into the finished app, so its links are made where they stay
|
|
339
|
+
// and nothing copies them again (TRAPS §37).
|
|
340
|
+
await bundlePython(path.join(APP, 'Contents', 'Resources'));
|
|
341
|
+
|
|
319
342
|
step('Signing (ad-hoc)');
|
|
320
343
|
// Electron's framework and helpers must all carry the same kind of signature,
|
|
321
344
|
// or macOS refuses to load them; re-signing the whole bundle ad hoc does that.
|
|
345
|
+
// --deep reaches nested bundles, not loose programs and libraries in
|
|
346
|
+
// Resources: the Python's were signed one by one first (signPython), and this
|
|
347
|
+
// seals them into the app's signature with everything else.
|
|
322
348
|
run('codesign', ['--force', '--deep', '--sign', '-', APP]);
|
|
323
349
|
run('codesign', ['--verify', '--deep', '--strict', APP]);
|
|
324
350
|
console.log(' signed ad-hoc and verified — no Apple account needed, still unnotarised');
|
|
325
351
|
}
|
|
326
352
|
|
|
353
|
+
// ---- the scanner's Python (Electron app only; DESKTOP.md D2) ------------------
|
|
354
|
+
// A standalone CPython from python-build-standalone, with the scanner's packages
|
|
355
|
+
// installed, at Contents/Resources/python. desktop/main.mjs names it to the
|
|
356
|
+
// server (SIX_DEGREES_PYTHON), which runs the scanner on it before any other
|
|
357
|
+
// Python: no install step, and scanning works offline.
|
|
358
|
+
//
|
|
359
|
+
// Pinned twice: the Python by the release and SHA-256 in lib/scanner-python.js,
|
|
360
|
+
// the packages by the hash of every file in scripts/requirements.txt. Downloads
|
|
361
|
+
// are cached in ~/.cache/six-degrees-build like Node's, and checked every build.
|
|
362
|
+
// Built on a Mac with the same chip (release.yml has one job per chip): pip runs
|
|
363
|
+
// this Python to install into it.
|
|
364
|
+
async function bundlePython(resources) {
|
|
365
|
+
const build = standaloneBuild(`darwin-${ARCH}`);
|
|
366
|
+
const xy = build.version.split('.').slice(0, 2).join('.');
|
|
367
|
+
const py = path.join(resources, 'python');
|
|
368
|
+
const lib = path.join(py, 'lib', `python${xy}`);
|
|
369
|
+
|
|
370
|
+
step(`Fetching Python ${build.version} (${ARCH})`);
|
|
371
|
+
const archive = path.join(CACHE, build.file);
|
|
372
|
+
if (existsSync(archive) && sha256File(archive) === build.sha256) {
|
|
373
|
+
console.log(' using the cached download (its SHA-256 matches the pinned one)');
|
|
374
|
+
} else {
|
|
375
|
+
rmSync(archive, { force: true });
|
|
376
|
+
await downloadVerified(build.url, archive, { sha256: build.sha256, size: build.size, idleMs: 60000 });
|
|
377
|
+
console.log(` downloaded ${megabytes(build.size)} MB; its SHA-256 matches the pinned one`);
|
|
378
|
+
}
|
|
379
|
+
rmSync(py, { recursive: true, force: true });
|
|
380
|
+
run('tar', ['-xzf', archive, '-C', resources]);
|
|
381
|
+
const python = path.join(py, 'bin', 'python3');
|
|
382
|
+
// Only this Python's own packages and settings: nothing from the build
|
|
383
|
+
// machine's user site-packages, PYTHONPATH or pip configuration.
|
|
384
|
+
const env = {
|
|
385
|
+
HOME: os.homedir(), TMPDIR: os.tmpdir(), PATH: '/usr/bin:/bin:/usr/sbin:/sbin', LANG: 'en_US.UTF-8',
|
|
386
|
+
PYTHONNOUSERSITE: '1', PYTHONDONTWRITEBYTECODE: '1',
|
|
387
|
+
};
|
|
388
|
+
try {
|
|
389
|
+
execFileSync(python, ['-c', 'pass'], { env, stdio: 'ignore' });
|
|
390
|
+
} catch {
|
|
391
|
+
console.error(`\n ✗ The ${ARCH} Python can't run on this Mac. Build on a Mac with that chip (release.yml does), or install Rosetta for an Intel build.\n`);
|
|
392
|
+
process.exit(1);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
step('Installing the scanner\'s packages into it');
|
|
396
|
+
run(python, ['-s', '-m', 'pip', '--isolated', 'install', '--disable-pip-version-check', '--no-input',
|
|
397
|
+
'--no-warn-script-location', '--no-compile', '--index-url', 'https://pypi.org/simple',
|
|
398
|
+
'--cache-dir', path.join(CACHE, 'pip'), '--require-hashes', '--only-binary', ':all:',
|
|
399
|
+
'-r', path.join(ROOT, 'scripts', 'requirements.txt')], { env });
|
|
400
|
+
run(python, ['-s', '-m', 'pip', '--isolated', 'check', '--disable-pip-version-check'], { env });
|
|
401
|
+
|
|
402
|
+
const full = duKb(py);
|
|
403
|
+
trimPython(py, lib, xy);
|
|
404
|
+
const trimmed = duKb(py);
|
|
405
|
+
const shared = shareDriverNode(lib, resources);
|
|
406
|
+
signPython(py);
|
|
407
|
+
checkPython(py, lib, env);
|
|
408
|
+
console.log(` Python ${build.version} and the scanner's packages: ${Math.round(full / 1024)} MB installed, `
|
|
409
|
+
+ `${Math.round(trimmed / 1024)} MB after trimming, ${Math.round(duKb(py) / 1024)} MB in the app`
|
|
410
|
+
+ (shared ? ' (Playwright runs on the app\'s own Node)' : ''));
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function sha256File(file) {
|
|
414
|
+
return createHash('sha256').update(readFileSync(file)).digest('hex');
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function duKb(dir) {
|
|
418
|
+
return Number.parseInt(execFileSync('du', ['-sk', dir]).toString(), 10) || 0;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Every file under `dir`, not following links.
|
|
422
|
+
function* walk(dir) {
|
|
423
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
424
|
+
const at = path.join(dir, entry.name);
|
|
425
|
+
if (entry.isDirectory()) yield* walk(at);
|
|
426
|
+
else yield { at, entry };
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// The Mach-O programs and libraries under `dir`, as { file, slices, head }.
|
|
431
|
+
function machoFiles(dir) {
|
|
432
|
+
const found = [];
|
|
433
|
+
for (const { at, entry } of walk(dir)) {
|
|
434
|
+
if (!entry.isFile()) continue;
|
|
435
|
+
const head = readAt(at, 0, 65536);
|
|
436
|
+
const slices = machoSlices(head);
|
|
437
|
+
if (slices.length) found.push({ file: at, slices });
|
|
438
|
+
}
|
|
439
|
+
return found;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function readAt(file, offset, length) {
|
|
443
|
+
const fd = openSync(file, 'r');
|
|
444
|
+
try {
|
|
445
|
+
const buf = Buffer.alloc(length);
|
|
446
|
+
const n = readSync(fd, buf, 0, length, offset);
|
|
447
|
+
return buf.subarray(0, n);
|
|
448
|
+
} finally {
|
|
449
|
+
closeSync(fd);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// What the scanner never uses, taken out to keep the download small. None of
|
|
454
|
+
// it is imported by scrape.py or its packages (checkPython proves the imports
|
|
455
|
+
// still load, and CI runs the scanner's pure functions on this Python):
|
|
456
|
+
// - bin/ keeps only the interpreter. pip's console scripts (idna, normalizer,
|
|
457
|
+
// playwright) name the build machine's path in their first line, and pip
|
|
458
|
+
// itself goes below: nothing installs into the app once it is built.
|
|
459
|
+
// - IDLE, tkinter and Tcl/Tk, turtle, lib2to3, ensurepip, the C headers and
|
|
460
|
+
// build files, man pages, test suites, and bytecode: without
|
|
461
|
+
// __pycache__ a module is compiled as it is imported (about 0.3 s for the
|
|
462
|
+
// scanner's), and ownPythonEnv never lets it write any into the app.
|
|
463
|
+
// - libpython's shared library: the interpreter has Python built in, so it is
|
|
464
|
+
// kept only if something inside links to it.
|
|
465
|
+
function trimPython(py, lib, xy) {
|
|
466
|
+
step('Trimming what the scanner never uses');
|
|
467
|
+
const keepInBin = new Set([`python${xy}`, 'python3', 'python']);
|
|
468
|
+
for (const name of readdirSync(path.join(py, 'bin'))) {
|
|
469
|
+
if (!keepInBin.has(name)) rmSync(path.join(py, 'bin', name), { recursive: true, force: true });
|
|
470
|
+
}
|
|
471
|
+
const remove = [
|
|
472
|
+
'include', 'share', 'lib/pkgconfig',
|
|
473
|
+
...readdirSync(path.join(py, 'lib')).filter((n) => /^(libtcl|libtk|tcl|tk|itcl|thread)/.test(n)).map((n) => `lib/${n}`),
|
|
474
|
+
...['idlelib', 'tkinter', 'turtledemo', 'turtle.py', 'lib2to3', 'ensurepip', 'test', 'idle_test', `config-${xy}-darwin`]
|
|
475
|
+
.map((n) => path.relative(py, path.join(lib, n))),
|
|
476
|
+
...readdirSync(path.join(lib, 'lib-dynload')).filter((n) => n.startsWith('_tkinter.')).map((n) => path.relative(py, path.join(lib, 'lib-dynload', n))),
|
|
477
|
+
...readdirSync(path.join(lib, 'site-packages')).filter((n) => n === 'pip' || /^pip-.*\.dist-info$/.test(n))
|
|
478
|
+
.map((n) => path.relative(py, path.join(lib, 'site-packages', n))),
|
|
479
|
+
];
|
|
480
|
+
for (const rel of remove) rmSync(path.join(py, rel), { recursive: true, force: true });
|
|
481
|
+
for (const dir of [...findDirs(py, (n) => n === '__pycache__'), ...findDirs(path.join(lib, 'site-packages'), (n) => n === 'tests')]) {
|
|
482
|
+
rmSync(dir, { recursive: true, force: true });
|
|
483
|
+
}
|
|
484
|
+
const libpython = path.join(py, 'lib', `libpython${xy}.dylib`);
|
|
485
|
+
if (existsSync(libpython)) {
|
|
486
|
+
const users = machoFiles(py).filter((m) => m.file !== libpython
|
|
487
|
+
&& m.slices.some((s) => (machoSlice(readAt(m.file, s.offset, 65536)) || { dylibs: [] }).dylibs.some((d) => d.endsWith(`/libpython${xy}.dylib`))));
|
|
488
|
+
if (users.length) console.log(` keeping libpython${xy}.dylib: ${path.relative(py, users[0].file)} links to it`);
|
|
489
|
+
else rmSync(libpython);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
function findDirs(dir, match) {
|
|
494
|
+
const found = [];
|
|
495
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
496
|
+
if (!entry.isDirectory()) continue;
|
|
497
|
+
const at = path.join(dir, entry.name);
|
|
498
|
+
if (match(entry.name)) found.push(at);
|
|
499
|
+
else found.push(...findDirs(at, match));
|
|
500
|
+
}
|
|
501
|
+
return found;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Playwright's driver carries its own Node (about 120 MB). When that is byte
|
|
505
|
+
// for byte the Node the app already bundles for its server (Playwright 1.63
|
|
506
|
+
// ships Node 24.21.0, the version build-app pins), the driver's becomes a link
|
|
507
|
+
// to the app's: the same program, about 40 MB less to download. When they
|
|
508
|
+
// differ, the driver keeps its own. Resolves whether it shared.
|
|
509
|
+
function shareDriverNode(lib, resources) {
|
|
510
|
+
const driverNode = path.join(lib, 'site-packages', 'playwright', 'driver', 'node');
|
|
511
|
+
const appNode = path.join(resources, 'node');
|
|
512
|
+
if (!existsSync(driverNode) || !existsSync(appNode)) return false;
|
|
513
|
+
if (sha256File(driverNode) !== sha256File(appNode)) {
|
|
514
|
+
console.log(' Playwright\'s Node differs from the app\'s, so the driver keeps its own');
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
rmSync(driverNode);
|
|
518
|
+
symlinkSync(path.relative(path.dirname(driverNode), appNode), driverNode);
|
|
519
|
+
if (realpathSync(driverNode) !== realpathSync(appNode)) throw new Error('The driver\'s link to the app\'s Node is wrong.');
|
|
520
|
+
return true;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Every program and library in the Python, signed ad hoc like the rest of the
|
|
524
|
+
// app. On Apple Silicon unsigned code isn't allowed to run at all.
|
|
525
|
+
function signPython(py) {
|
|
526
|
+
const files = machoFiles(py).map((m) => m.file);
|
|
527
|
+
for (let i = 0; i < files.length; i += 64) {
|
|
528
|
+
// Its only chatter is "replacing existing signature", once a file.
|
|
529
|
+
mustRun('codesign', ['--force', '--sign', '-', ...files.slice(i, i + 64)], process.env, 'Signing the app\'s Python failed');
|
|
530
|
+
}
|
|
531
|
+
console.log(` signed ${files.length} programs and libraries ad hoc`);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// The Python as the app will run it: every program is for this chip and this
|
|
535
|
+
// app's oldest macOS, the imports load (the compiled parts too: TRAPS §30), and
|
|
536
|
+
// Playwright's driver starts. Any failure fails the build.
|
|
537
|
+
function checkPython(py, lib, env) {
|
|
538
|
+
step('Checking the Python inside the app');
|
|
539
|
+
const newer = (v) => {
|
|
540
|
+
const [a, b] = [String(v).split('.').map(Number), MACOS_MIN.split('.').map(Number)];
|
|
541
|
+
return (a[0] - b[0] || (a[1] || 0) - (b[1] || 0)) > 0;
|
|
542
|
+
};
|
|
543
|
+
for (const m of machoFiles(py)) {
|
|
544
|
+
const slice = m.slices.find((s) => s.arch === ARCH);
|
|
545
|
+
const rel = path.relative(py, m.file);
|
|
546
|
+
if (!slice) throw new Error(`${rel} isn't built for ${ARCH}.`);
|
|
547
|
+
const info = machoSlice(readAt(m.file, slice.offset, 65536));
|
|
548
|
+
if (info?.minos && newer(info.minos)) throw new Error(`${rel} needs macOS ${info.minos}; the app promises ${MACOS_MIN}.`);
|
|
549
|
+
}
|
|
550
|
+
const python = path.join(py, 'bin', 'python3');
|
|
551
|
+
console.log(` ${mustRun(python, ['-s', '-c', `${IMPORTS}; import sys; from importlib.metadata import version as v; `
|
|
552
|
+
+ 'print("Python", sys.version.split()[0], "· Playwright", v("playwright"), "· requests", v("requests"), "· Pillow", v("pillow"))'],
|
|
553
|
+
env, 'The scanner\'s packages don\'t load in the app\'s Python')}`);
|
|
554
|
+
const driver = path.join(lib, 'site-packages', 'playwright', 'driver');
|
|
555
|
+
console.log(` Playwright's driver starts: ${mustRun(path.join(driver, 'node'), [path.join(driver, 'package', 'cli.js'), '--version'],
|
|
556
|
+
env, 'Playwright\'s driver doesn\'t start')}`);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// What a check printed, or the build stops with what went wrong.
|
|
560
|
+
function mustRun(file, args, env, what) {
|
|
561
|
+
try {
|
|
562
|
+
return execFileSync(file, args, { env, stdio: ['ignore', 'pipe', 'pipe'] }).toString().trim();
|
|
563
|
+
} catch (err) {
|
|
564
|
+
console.error(`\n ✗ ${what}:\n${String(err.stderr || err.message).trim().split('\n').slice(-8).map((l) => ` ${l}`).join('\n')}\n`);
|
|
565
|
+
process.exit(1);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
327
569
|
// The app icon, from an SVG: sharp (already here, Next depends on it) draws it
|
|
328
570
|
// at 1024px, sips makes the sizes macOS wants, iconutil packs them.
|
|
329
571
|
async function makeIcns(svg, out) {
|
|
@@ -1,4 +1,106 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
# The scanner's Python packages (scripts/scrape.py), pinned to exact versions,
|
|
2
|
+
# with the SHA-256 of every file pip may install for each. The same file goes
|
|
3
|
+
# into the Python inside the Mac app when it is built (scripts/build-app.mjs),
|
|
4
|
+
# and into the scanner's own environment when the Scan page sets one up.
|
|
5
|
+
#
|
|
6
|
+
# To change a version, edit its line and run
|
|
7
|
+
# node scripts/pin-python-packages.mjs
|
|
8
|
+
# which rewrites the hashes from PyPI. Every dependency is listed: once hashes
|
|
9
|
+
# are used, pip refuses anything that isn't.
|
|
10
|
+
|
|
11
|
+
--only-binary :all:
|
|
12
|
+
--require-hashes
|
|
13
|
+
|
|
14
|
+
# Drives the user's own Google Chrome (channel="chrome"), so no browser is downloaded.
|
|
15
|
+
# Its wheel carries Playwright's driver, which it needs.
|
|
16
|
+
playwright==1.63.0 \
|
|
17
|
+
--hash=sha256:354e15b29503565fc598b89f16fbe070459343bef9d7498a93e304864000c6a7 \
|
|
18
|
+
--hash=sha256:84c540759e8e7f01e690e197e04060f48899d37cea322299f255843273d3385d \
|
|
19
|
+
--hash=sha256:ad21bc07516b187965a7521c5cf0df0bd657b17482eaad74335272d35a2b07de \
|
|
20
|
+
--hash=sha256:c89fc4736502a1f0fac2c8ca5d10c0cbc1c669f1f4774a2d8507a43140e4d53f \
|
|
21
|
+
--hash=sha256:fd1aa00631d44d55e56e0975bf3f3f285fac4a9fd2813183f0c12a488f1a1b24
|
|
22
|
+
|
|
23
|
+
# Playwright's own dependencies: greenlet, pyee, and pyee's typing-extensions.
|
|
24
|
+
greenlet==3.5.6 \
|
|
25
|
+
--hash=sha256:1c20ea32a73d17b9b60e3371240e17b0068120c98a5ec01a224a7dd8c89733ba \
|
|
26
|
+
--hash=sha256:45bfd2b51e38aaa5f9849f114d9c7c1d75f69187c849b3549cd64c465283abfa \
|
|
27
|
+
--hash=sha256:8cddea1b8339451c2fb3388e138347b6126744f33b611bdb55b7357361cfef46 \
|
|
28
|
+
--hash=sha256:95e7c44d072db623a1aab04ce488cf9533294a77ed9d072cd503a3596f4106ac \
|
|
29
|
+
--hash=sha256:975736b002ed080d124cf81a79cb7e05cb26d6b3f5c7a7b651c0fcce70353aa1 \
|
|
30
|
+
--hash=sha256:9a09d59bef1db94f384b5bcc2d523694d338f3df6b757aeeaf7baca5d0c0be88 \
|
|
31
|
+
--hash=sha256:a5876d0a60355af98d535c47f6cd6eb0f8a432396dab26845d380b92f8412422 \
|
|
32
|
+
--hash=sha256:a6a4b98a9132e0f45c9fc245a63894cfd8c45fb7a0d6bffc5eab3ec327cf7324 \
|
|
33
|
+
--hash=sha256:b7d501d5eb5d4f67207df364752ad697465b834268744be7581c18d81d35d41d \
|
|
34
|
+
--hash=sha256:c59acfa8eb73a1e0d484392dc002bdf001fd4ce73394e0132df3d1ab6093d7cb \
|
|
35
|
+
--hash=sha256:c75116c9de79949de23006e2d9b35ee82874c594fcf5c0311b439acaa14b8441 \
|
|
36
|
+
--hash=sha256:e85880b538e59a59f55117b81f208a6660ad5ac328aad9305f812d9b8bc67a0f \
|
|
37
|
+
--hash=sha256:eed88b64a5e5da72d6a71cdc5aaeefaa5ced9b748f8d19f89800b339961dad39 \
|
|
38
|
+
--hash=sha256:f96f0e30b5a95c7631b12bfe214cbc90ec8fe8cfa36920596c10514a65743519 \
|
|
39
|
+
--hash=sha256:f98e8215e172f567ce80eeaed9107fb4d32b6c44f26983d9b8334658136a205a
|
|
40
|
+
|
|
41
|
+
pyee==13.0.1 \
|
|
42
|
+
--hash=sha256:af2f8fede4171ef667dfded53f96e2ed0d6e6bd7ee3bb46437f77e3b57689228
|
|
43
|
+
|
|
44
|
+
typing-extensions==4.16.0 \
|
|
45
|
+
--hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8
|
|
46
|
+
|
|
47
|
+
requests==2.34.2 \
|
|
48
|
+
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0
|
|
49
|
+
|
|
50
|
+
# requests' own dependencies: certifi, charset-normalizer, idna, urllib3.
|
|
51
|
+
certifi==2026.7.22 \
|
|
52
|
+
--hash=sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775
|
|
53
|
+
|
|
54
|
+
charset-normalizer==3.5.1 \
|
|
55
|
+
--hash=sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90 \
|
|
56
|
+
--hash=sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0 \
|
|
57
|
+
--hash=sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2 \
|
|
58
|
+
--hash=sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa \
|
|
59
|
+
--hash=sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f \
|
|
60
|
+
--hash=sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3 \
|
|
61
|
+
--hash=sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6 \
|
|
62
|
+
--hash=sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a \
|
|
63
|
+
--hash=sha256:96eefc178f8636b9c760c5829345307fd81cfae9ab1e80997dbddeb0f54ee9a3 \
|
|
64
|
+
--hash=sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99 \
|
|
65
|
+
--hash=sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488 \
|
|
66
|
+
--hash=sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08 \
|
|
67
|
+
--hash=sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c \
|
|
68
|
+
--hash=sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8 \
|
|
69
|
+
--hash=sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2 \
|
|
70
|
+
--hash=sha256:d1ee1e296209fdce05b81b663250eefa02213a2da7b41bf26f7829b8ba3545aa \
|
|
71
|
+
--hash=sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d \
|
|
72
|
+
--hash=sha256:e9fbdce1e47394b09bc9f26ab117dfc8d6491977a11d86f592bb42c779db2fda \
|
|
73
|
+
--hash=sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30
|
|
74
|
+
|
|
75
|
+
idna==3.20 \
|
|
76
|
+
--hash=sha256:ab7ae7122974553370f0bdb919e1a960b2cd1bc1ef0276416d896db81c14582c
|
|
77
|
+
|
|
78
|
+
urllib3==2.8.0 \
|
|
79
|
+
--hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3
|
|
80
|
+
|
|
81
|
+
# Profile photos (scripts/image_store.py).
|
|
82
|
+
pillow==12.3.0 \
|
|
83
|
+
--hash=sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756 \
|
|
84
|
+
--hash=sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3 \
|
|
85
|
+
--hash=sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd \
|
|
86
|
+
--hash=sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b \
|
|
87
|
+
--hash=sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6 \
|
|
88
|
+
--hash=sha256:5594fc43d548a7ed94949d139aa1341b270f1863f11cfd37f5a6c8b778a6b67f \
|
|
89
|
+
--hash=sha256:6c0016e7b354317c4e9e525b937ac8596c38d2d232b419529b9cd7a1cd46e39a \
|
|
90
|
+
--hash=sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91 \
|
|
91
|
+
--hash=sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66 \
|
|
92
|
+
--hash=sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965 \
|
|
93
|
+
--hash=sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8 \
|
|
94
|
+
--hash=sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd \
|
|
95
|
+
--hash=sha256:bcc33feacfaefce60c12fd500a277533bdc02b10a19f7f6d348763d8140bbba7 \
|
|
96
|
+
--hash=sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35 \
|
|
97
|
+
--hash=sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9 \
|
|
98
|
+
--hash=sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0 \
|
|
99
|
+
--hash=sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321 \
|
|
100
|
+
--hash=sha256:f0606c8bf2cdefea14a43530f7657cbbb7ecf1c4222512492ef4a4434a9501ec \
|
|
101
|
+
--hash=sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65 \
|
|
102
|
+
--hash=sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7
|
|
103
|
+
|
|
104
|
+
# Windows only: Python there has no time zone database (docs/brain/DESKTOP.md D3).
|
|
105
|
+
tzdata==2026.4 ; sys_platform == "win32" \
|
|
106
|
+
--hash=sha256:c2169a8b0a7a5e9674da5a135ccdfb2b3e671b333ed9fed17b41f73c34476e81
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// A pretend GitHub release, served on 127.0.0.1, for testing the Mac app's
|
|
3
|
+
// in-app update without GitHub: tests/updater-job.test.mjs, a browser check of
|
|
4
|
+
// Settings → Updates, and a CI step that updates one build to the next.
|
|
5
|
+
//
|
|
6
|
+
// node scripts/test-release-server.mjs --dir DIR [--version X.Y.Z] [--port 3303]
|
|
7
|
+
//
|
|
8
|
+
// It serves every .dmg in DIR as that version's release assets, with a
|
|
9
|
+
// SHA256SUMS made from them, the way release.yml publishes a release:
|
|
10
|
+
//
|
|
11
|
+
// GET /repos/<owner/repo>/releases/latest the release, as GitHub describes it
|
|
12
|
+
// GET /<owner/repo>/releases/download/v<version>/<name> an asset
|
|
13
|
+
//
|
|
14
|
+
// Point the app at it with SIX_DEGREES_TEST_RELEASES=<the address it prints>.
|
|
15
|
+
// The app honours that only for a 127.0.0.1 address (lib/updater.js
|
|
16
|
+
// releaseSource). It is never set by the app, and nothing here ships in it.
|
|
17
|
+
|
|
18
|
+
import { createServer } from 'node:http';
|
|
19
|
+
import { createHash } from 'node:crypto';
|
|
20
|
+
import fs from 'node:fs';
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
import { fileURLToPath } from 'node:url';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Start the server. `release` (also settable later with setRelease) is:
|
|
26
|
+
* version '0.2.2'
|
|
27
|
+
* assets [{ name, data: Buffer } | { name, file: path }]
|
|
28
|
+
* sums the SHA256SUMS text; computed from the assets when left out, and
|
|
29
|
+
* null for a release published without one
|
|
30
|
+
* stall an asset name: send half of it, then nothing (a dead connection)
|
|
31
|
+
* prerelease, draft, tag as GitHub would say them
|
|
32
|
+
* Every request is recorded in `requests` (method and path).
|
|
33
|
+
*/
|
|
34
|
+
export async function startTestReleaseServer({ slug, port = 0, release = null } = {}) {
|
|
35
|
+
if (!/^[\w.-]+\/[\w.-]+$/.test(String(slug))) throw new Error(`Not an owner/repo: ${slug}`);
|
|
36
|
+
let current = release;
|
|
37
|
+
const requests = [];
|
|
38
|
+
const open = new Set();
|
|
39
|
+
|
|
40
|
+
const bytesOf = (asset) => (asset.data ? asset.data : fs.readFileSync(asset.file));
|
|
41
|
+
const sizeOf = (asset) => (asset.data ? asset.data.length : fs.statSync(asset.file).size);
|
|
42
|
+
const sumsOf = (r) => {
|
|
43
|
+
if (r.sums === null) return null;
|
|
44
|
+
if (typeof r.sums === 'string') return r.sums;
|
|
45
|
+
return r.assets.map((a) => `${createHash('sha256').update(bytesOf(a)).digest('hex')} ${a.name}`).join('\n') + '\n';
|
|
46
|
+
};
|
|
47
|
+
const tagOf = (r) => r.tag || `v${r.version}`;
|
|
48
|
+
|
|
49
|
+
const server = createServer((req, res) => {
|
|
50
|
+
try {
|
|
51
|
+
handle(req, res);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
// A file that went missing, say: answer like a failing server, don't die.
|
|
54
|
+
if (!res.headersSent) res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
55
|
+
res.end(String(err.message));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
function handle(req, res) {
|
|
59
|
+
requests.push(`${req.method} ${req.url}`);
|
|
60
|
+
const r = current;
|
|
61
|
+
const url = new URL(req.url, 'http://127.0.0.1');
|
|
62
|
+
const send = (status, body, type = 'application/json') => {
|
|
63
|
+
res.writeHead(status, { 'Content-Type': type, 'Content-Length': Buffer.byteLength(body) });
|
|
64
|
+
res.end(body);
|
|
65
|
+
};
|
|
66
|
+
if (!r) return send(404, JSON.stringify({ message: 'Not Found' }));
|
|
67
|
+
const origin = `http://127.0.0.1:${server.address().port}`;
|
|
68
|
+
const base = `${origin}/${slug}/releases/download/${encodeURIComponent(tagOf(r))}/`;
|
|
69
|
+
const sums = sumsOf(r);
|
|
70
|
+
|
|
71
|
+
if (url.pathname === `/repos/${slug}/releases/latest`) {
|
|
72
|
+
const assets = r.assets.map((a) => ({ name: a.name, size: sizeOf(a), browser_download_url: base + encodeURIComponent(a.name) }));
|
|
73
|
+
if (sums !== null) assets.push({ name: 'SHA256SUMS', size: Buffer.byteLength(sums), browser_download_url: `${base}SHA256SUMS` });
|
|
74
|
+
return send(200, JSON.stringify({
|
|
75
|
+
tag_name: tagOf(r),
|
|
76
|
+
html_url: `${origin}/${slug}/releases/tag/${encodeURIComponent(tagOf(r))}`,
|
|
77
|
+
draft: Boolean(r.draft),
|
|
78
|
+
prerelease: Boolean(r.prerelease),
|
|
79
|
+
assets,
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
const prefix = `/${slug}/releases/download/${encodeURIComponent(tagOf(r))}/`;
|
|
83
|
+
if (url.pathname.startsWith(prefix)) {
|
|
84
|
+
const name = decodeURIComponent(url.pathname.slice(prefix.length));
|
|
85
|
+
if (name === 'SHA256SUMS' && sums !== null) return send(200, sums, 'text/plain');
|
|
86
|
+
const asset = r.assets.find((a) => a.name === name);
|
|
87
|
+
if (!asset) return send(404, 'Not Found', 'text/plain');
|
|
88
|
+
const body = bytesOf(asset);
|
|
89
|
+
res.writeHead(200, { 'Content-Type': 'application/octet-stream', 'Content-Length': body.length });
|
|
90
|
+
if (r.stall === name) {
|
|
91
|
+
res.write(body.subarray(0, Math.floor(body.length / 2))); // then nothing, until the client gives up
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
return res.end(body);
|
|
95
|
+
}
|
|
96
|
+
return send(404, JSON.stringify({ message: 'Not Found' }));
|
|
97
|
+
}
|
|
98
|
+
server.on('connection', (socket) => { open.add(socket); socket.on('close', () => open.delete(socket)); });
|
|
99
|
+
await new Promise((resolve, reject) => {
|
|
100
|
+
server.once('error', reject);
|
|
101
|
+
server.listen(port, '127.0.0.1', resolve); // this computer only, never another address
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
origin: `http://127.0.0.1:${server.address().port}`,
|
|
105
|
+
requests,
|
|
106
|
+
setRelease(next) { current = next; },
|
|
107
|
+
close() {
|
|
108
|
+
for (const socket of open) socket.destroy();
|
|
109
|
+
return new Promise((resolve) => server.close(() => resolve()));
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ── from the command line ──
|
|
115
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
116
|
+
const arg = (name) => {
|
|
117
|
+
const i = process.argv.indexOf(`--${name}`);
|
|
118
|
+
return i > 0 ? process.argv[i + 1] : undefined;
|
|
119
|
+
};
|
|
120
|
+
const dir = arg('dir');
|
|
121
|
+
if (!dir) {
|
|
122
|
+
console.error('Usage: node scripts/test-release-server.mjs --dir DIR [--version X.Y.Z] [--port 3303]');
|
|
123
|
+
process.exit(2);
|
|
124
|
+
}
|
|
125
|
+
const names = fs.readdirSync(dir).filter((n) => n.endsWith('.dmg')).sort();
|
|
126
|
+
const version = arg('version') || names.map((n) => n.match(/^Six-Degrees-(\d+(?:\.\d+)+)-(?:arm64|x64)\.dmg$/)?.[1]).find(Boolean);
|
|
127
|
+
if (!names.length || !version) {
|
|
128
|
+
console.error(`No Six-Degrees-<version>-<chip>.dmg in ${dir} (or pass --version).`);
|
|
129
|
+
process.exit(2);
|
|
130
|
+
}
|
|
131
|
+
const pkg = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
132
|
+
const slug = String(pkg.repository?.url || '').match(/github\.com[/:]([^/]+\/[^/.#?]+)/)?.[1];
|
|
133
|
+
const served = await startTestReleaseServer({
|
|
134
|
+
slug,
|
|
135
|
+
port: Number(arg('port') || 0),
|
|
136
|
+
release: { version, assets: names.map((name) => ({ name, file: path.join(dir, name) })) },
|
|
137
|
+
});
|
|
138
|
+
console.log(`A pretend release ${version} of ${slug}: ${names.join(', ')}, SHA256SUMS`);
|
|
139
|
+
console.log(`SIX_DEGREES_TEST_RELEASES=${served.origin}`);
|
|
140
|
+
const stop = () => served.close().then(() => process.exit(0));
|
|
141
|
+
process.on('SIGINT', stop);
|
|
142
|
+
process.on('SIGTERM', stop);
|
|
143
|
+
}
|
|
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
|
|
|
9
9
|
const hostname = process.env.HOSTNAME || '0.0.0.0'
|
|
10
10
|
|
|
11
11
|
let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
|
|
12
|
-
const nextConfig = {"env":{},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.mjs","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"instrumentationClientInject":[],"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/six-degrees/six-degrees","enablePrerenderSourceMaps":true,"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":true,"coldCacheBadge":false,"devValidationWorker":true,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"dynamicOnHover":false,"useOffline":false,"varyParams":true,"optimisticRouting":true,"instrumentationClientRouterTransitionEvents":false,"prefetchInlining":{"maxSize":2048,"maxBundleSize":10240},"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptOperationCache":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"devMemoryThresholdRestart":true,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"requestInsights":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":true,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":true,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"serverComponentsHmrCancellation":false,"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":true,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","turbopackMemoryEvictionMode":"auto","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"],"useCacheTimeout":54,"instantInsights":{"validationLevel":"warning"},"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.mjs","outputFileTracingExcludes":{"*":["dist/*.app/**","dist/*.dmg","dist/staging/**","dist/electron-stage/**","docs/**","tests/**",".git/**","*.log","scripts/dmg/**","desktop/**","node_modules/electron/**","node_modules/@electron/**"]},"serverExternalPackages":["node:sqlite"],"repoRoot":"/home/runner/work/six-degrees/six-degrees","turbopack":{"root":"/home/runner/work/six-degrees/six-degrees"},"distDirRoot":".next"}
|
|
12
|
+
const nextConfig = {"env":{},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.mjs","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"instrumentationClientInject":[],"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/six-degrees/six-degrees","enablePrerenderSourceMaps":true,"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":true,"coldCacheBadge":false,"devValidationWorker":true,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"dynamicOnHover":false,"useOffline":false,"varyParams":true,"optimisticRouting":true,"instrumentationClientRouterTransitionEvents":false,"prefetchInlining":{"maxSize":2048,"maxBundleSize":10240},"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptOperationCache":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"devMemoryThresholdRestart":true,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"requestInsights":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":true,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":true,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"serverComponentsHmrCancellation":false,"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":true,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","turbopackMemoryEvictionMode":"auto","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"],"useCacheTimeout":54,"instantInsights":{"validationLevel":"warning"},"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.mjs","outputFileTracingExcludes":{"*":["dist/*.app/**","dist/*.dmg","dist/staging/**","dist/electron-stage/**","docs/**","tests/**",".git",".git/**","*.log","scripts/dmg/**","scripts/pin-python-packages.mjs","desktop/**","node_modules/electron/**","node_modules/@electron/**","site/**"]},"serverExternalPackages":["node:sqlite"],"repoRoot":"/home/runner/work/six-degrees/six-degrees","turbopack":{"root":"/home/runner/work/six-degrees/six-degrees"},"distDirRoot":".next"}
|
|
13
13
|
|
|
14
14
|
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
|
|
15
15
|
|