diff --git a/cli/dist/lib/development_server/index.js b/cli/dist/lib/development_server/index.js index 6f026c0ab..229ae06c9 100644 --- a/cli/dist/lib/development_server/index.js +++ b/cli/dist/lib/development_server/index.js @@ -1,12 +1,12 @@ -import h from"chalk";import N from"child_process";import k from"fs";import"os";import w,{dirname as R}from"path";import{fileURLToPath as D}from"url";import I from"util";import m from"./check_if_port_occupied.js";import i from"../cli_log.js";import f from"./get_database_process_ids.js";import $ from"../get_platform_safe_path.js";import y from"../kill_port_process.js";import u from"../load_settings.js";import j from"../loader.js";import g from"../path_exists.js";import v from"../required_files.js";import O from"./start_app_server.js";import x from"./start_databases.js";import H from"./start_hmr_server.js";import C from"./watch_for_changes/index.js";import P from"../constants.js";import S from"./kill_process_ids.js";import A,{run_tests_integrated as T}from"./run_tests.js";import L from"../debounce.js";import V from"./databases/download_database_binary.js";const{stat:G}=k.promises,M=I.promisify(N.exec),_=parseInt(process?.version?.split(".")[0]?.replace("v",""),10),J=D(import.meta.url),l=R(J),d=[],q=async(s=!1)=>{const t=f();await A({watch:s,__dirname:l,process_ids:[...d,...t],cleanup_process:process.cleanup_process})},U=(s=[],t=0,r="")=>{const o=["--no-warnings"];t<19&&o.push("--experimental-specifier-resolution=node");const e=N.fork(w.resolve(`${r}/cleanup.js`),[],{detached:!0,silent:!0});process.cleanup_process=e,process.on("SIGINT",async()=>{const c=f();e.send(JSON.stringify({process_ids:[...s,...c]})),process.exit()}),process.on("SIGTERM",async()=>{const c=f();e.send(JSON.stringify({process_ids:[...s,...c]})),process.exit()})},F=async(s=[])=>{const t=s?.find(a=>a?.path?.match(P.SETTINGS_FILE_NAME_REGEX)?.length>0),r=s?.find(a=>a?.path?.includes("i18n")),o=s?.find(a=>a?.path?.includes("index.html")),e=s?.find(a=>a?.path?.includes("index.css")||a?.path?.includes("css/")),c=s?.find(a=>a?.path?.includes("index.client.js"));process.hmr_server_process.send(JSON.stringify({type:"FILE_CHANGE",settings:t?await u(process.env.NODE_ENV):null,i18n_change:!!r,index_html_change:!!o,index_css_change:!!e,index_client_change:!!c}))},B=(s=0,t=!1,r={},o=[],e=!1)=>{process.hmr_server_process.on("message",async c=>{["HAS_HMR_CONNECTIONS","HAS_NO_HMR_CONNECTIONS","HMR_UPDATE_COMPLETE"].includes(c?.type)||process.loader.print(c),c?.type==="HAS_HMR_CONNECTIONS"&&(process.hmr_server_process.has_connections=!0),c?.type==="HAS_NO_HMR_CONNECTIONS"&&(process.hmr_server_process.has_connections=!1),c?.type==="HMR_UPDATE_COMPLETE"&&process.app_server_process&&!process.app_server_restarting&&(process.app_server_restarting=!0,b(s,t,r,o,e))})},K=()=>{process.hmr_server_process.on("error",s=>{i(s.toString(),{level:"danger",docs:"https://github.com/cheatcode/joystick"})}),process.hmr_server_process.stdout.on("data",s=>{console.log(s.toString())}),process.hmr_server_process.stderr.on("data",s=>{i(s.toString(),{level:"danger",docs:"https://github.com/cheatcode/joystick"})})},Y=(s=0,t="",r=!1,o={},e=[],c=!1)=>{process.hmr_server_process=H(s,t),d.push(process.hmr_server_process?.pid),K(),B(s,r,o,e,c)},z=async(s={})=>{const t=await u(process.env.NODE_ENV),r=t?.config?.databases?JSON.stringify(t?.config?.databases):"",o=s?.config?.databases?JSON.stringify(s?.config?.databases):"";return r!==o},b=async(s=0,t=!1,r=null,o=[],e=!1)=>{L(async()=>{if(await z(r)){const a=f();i(`Database configuration has changed in settings.${process.env.NODE_ENV}.json. Please restart your app to add, change, or remove databases.`,{level:"danger",docs:"https://cheatcode.co/docs/joystick/structure"}),S([process.hmr_server_process?.pid,process.app_server_process?.pid,...a]),process.exit(0)}else S([...process.app_server_process.external_process_ids||[]]),await y(process.env.PORT),E(s,t,o,e)},300)},X=(s=!1,t=!1,r=!1)=>{process.app_server_process.external_process_ids=[],process.app_server_process.on("message",o=>{o?.external_process_id&&(process.app_server_process.external_process_ids=[...process.app_server_process.external_process_ids||[],o?.external_process_id])}),process.app_server_process.on("error",o=>{r||i(o.toString(),{level:"danger",docs:"https://github.com/cheatcode/joystick"})}),process.app_server_process.stdout.on("data",async o=>{const e=o.toString(),c=e.includes("App running at:");if(r){process.loader.print(e);return}e&&c&&process.env.NODE_ENV!=="test"&&process.loader.print(e),e&&!c&&!e.includes("BUILD_ERROR")&&console.log(e),e&&c&&process.env.NODE_ENV==="test"&&q(s),e&&c&&t&&process.env.NODE_ENV!=="test"&&setTimeout(async()=>{try{await T({__dirname:l})}catch(a){console.error("Error running integrated tests:",a)}},2e3)}),process.app_server_process.stderr.on("data",o=>{i(o.toString(),{level:"danger",docs:"https://cheatcode.co/docs/joystick"})})},E=(s=0,t=!1,r=[],o=!1,e=!1)=>{process.app_server_process=O(s,t,r),d.push(process.app_server_process?.pid),X(t,o,e),process.app_server_restarting=!1},Q=async(s={})=>{const t=s?.config?.databases?.map((r={})=>r?.provider);for(let r=0;r{process.title=s?.environment==="test"?"joystick_test":"joystick",process.project_folder=w.basename(process.cwd()),process.loader=new j,s?.environment==="test"&&(console.log(""),process.loader.print(`Initializing test environment... -`)),process.env.LOGS_PATH=s?.logs||null,process.env.NODE_ENV=s?.environment||"development",process.env.PORT=t,process.env.IS_DEBUG_MODE=s?.debug},Z=(s=2600)=>{i(`Port ${s} is already occupied. To start Joystick on this port, clear it and try again.`,{level:"danger"}),process.exit(0)},ss=(s=2600)=>parseInt(s||2600,10),es=async()=>{const s=$(`${process.cwd()}/.joystick/build`);await g(s)&&await M(`${process.platform==="win32"?"rmdir /s /q":"rm -rf"} ${s}`)},ts=async()=>{const s=[];for(let t=0;t0){const t=s?.filter(e=>e.type==="file"),r=s?.filter(e=>e.type==="directory");let o=`The following paths are missing and required in a Joystick project: +import f from"chalk";import E from"child_process";import v from"fs";import"os";import T,{dirname as P}from"path";import{fileURLToPath as L}from"url";import I from"util";import O from"./check_if_port_occupied.js";import i from"../cli_log.js";import h from"./get_database_process_ids.js";import H from"../get_platform_safe_path.js";import y from"../kill_port_process.js";import g from"../load_settings.js";import $ from"../loader.js";import u from"../path_exists.js";import w from"../required_files.js";import m from"./start_app_server.js";import S from"./start_databases.js";import j from"./start_hmr_server.js";import G from"./watch_for_changes/index.js";import V from"../constants.js";import R from"./kill_process_ids.js";import A,{run_tests_integrated as x}from"./run_tests.js";import J from"../debounce.js";import C from"./databases/download_database_binary.js";const{stat:U}=v.promises,M=I.promisify(E.exec),d=parseInt(process?.version?.split(".")[0]?.replace("v",""),10),q=L(import.meta.url),l=P(q),p=[],F=async(s=!1)=>{const t=h();await A({watch:s,__dirname:l,process_ids:[...p,...t],cleanup_process:process.cleanup_process})},K=(s=[],t=0,r="")=>{const o=["--no-warnings"];t<19&&o.push("--experimental-specifier-resolution=node");const e=E.fork(T.resolve(`${r}/cleanup.js`),[],{detached:!0,silent:!0});process.cleanup_process=e,process.on("SIGINT",async()=>{const c=h();e.send(JSON.stringify({process_ids:[...s,...c]})),process.exit()}),process.on("SIGTERM",async()=>{const c=h();e.send(JSON.stringify({process_ids:[...s,...c]})),process.exit()})},Y=async(s=[])=>{const t=s?.find(a=>a?.path?.match(V.SETTINGS_FILE_NAME_REGEX)?.length>0),r=s?.find(a=>a?.path?.includes("i18n")),o=s?.find(a=>a?.path?.includes("index.html")),e=s?.find(a=>a?.path?.includes("index.css")||a?.path?.includes("css/")),c=s?.find(a=>a?.path?.includes("index.client.js"));process.hmr_server_process.send(JSON.stringify({type:"FILE_CHANGE",settings:t?await g(process.env.NODE_ENV):null,i18n_change:!!r,index_html_change:!!o,index_css_change:!!e,index_client_change:!!c}))},B=(s=0,t=!1,r={},o=[],e=!1)=>{process.hmr_server_process.on("message",async c=>{["HAS_HMR_CONNECTIONS","HAS_NO_HMR_CONNECTIONS","HMR_UPDATE_COMPLETE"].includes(c?.type)||process.loader.print(c),c?.type==="HAS_HMR_CONNECTIONS"&&(process.hmr_server_process.has_connections=!0),c?.type==="HAS_NO_HMR_CONNECTIONS"&&(process.hmr_server_process.has_connections=!1),c?.type==="HMR_UPDATE_COMPLETE"&&process.app_server_process&&!process.app_server_restarting&&(process.app_server_restarting=!0,b(s,t,r,o,e))})},z=()=>{process.hmr_server_process.on("error",s=>{i(s.toString(),{level:"danger",docs:"https://github.com/cheatcode/joystick"})}),process.hmr_server_process.stdout.on("data",s=>{console.log(s.toString())}),process.hmr_server_process.stderr.on("data",s=>{i(s.toString(),{level:"danger",docs:"https://github.com/cheatcode/joystick"})})},X=(s=0,t="",r=!1,o={},e=[],c=!1)=>{process.hmr_server_process=j(s,t),p.push(process.hmr_server_process?.pid),z(),B(s,r,o,e,c)},Q=async(s={})=>{const t=await g(process.env.NODE_ENV),r=t?.config?.databases?JSON.stringify(t?.config?.databases):"",o=s?.config?.databases?JSON.stringify(s?.config?.databases):"";return r!==o},b=async(s=0,t=!1,r=null,o=[],e=!1)=>{J(async()=>{if(await Q(r)){const a=h();i(`Database configuration has changed in settings.${process.env.NODE_ENV}.json. Please restart your app to add, change, or remove databases.`,{level:"danger",docs:"https://cheatcode.co/docs/joystick/structure"}),R([process.hmr_server_process?.pid,process.app_server_process?.pid,...a]),process.exit(0)}else{R([...process.app_server_process.external_process_ids||[]]),await y(process.env.PORT);const a=await g(process.env.NODE_ENV);process.app_server_process=m(s,t,o,{NODE_ENV:process.env.NODE_ENV,PORT:process.env.PORT,LOGS_PATH:process.env.LOGS_PATH,ROOT_URL:process.env.ROOT_URL,JOYSTICK_SETTINGS:JSON.stringify(a)}),p.push(process.app_server_process?.pid),k(t,e,!1),process.app_server_restarting=!1}},300)},k=(s=!1,t=!1,r=!1)=>{process.app_server_process.external_process_ids=[],process.app_server_process.on("message",o=>{o?.external_process_id&&(process.app_server_process.external_process_ids=[...process.app_server_process.external_process_ids||[],o?.external_process_id])}),process.app_server_process.on("error",o=>{r||i(o.toString(),{level:"danger",docs:"https://github.com/cheatcode/joystick"})}),process.app_server_process.stdout.on("data",async o=>{const e=o.toString(),c=e.includes("App running at:");if(r){process.loader.print(e);return}e&&c&&process.env.NODE_ENV!=="test"&&process.loader.print(e),e&&!c&&!e.includes("BUILD_ERROR")&&console.log(e),e&&c&&process.env.NODE_ENV==="test"&&F(s),e&&c&&t&&process.env.NODE_ENV!=="test"&&setTimeout(async()=>{try{await x({__dirname:l})}catch(a){console.error("Error running integrated tests:",a)}},2e3)}),process.app_server_process.stderr.on("data",o=>{i(o.toString(),{level:"danger",docs:"https://cheatcode.co/docs/joystick"})})},W=(s=0,t=!1,r=[],o=!1,e=!1,c={})=>{process.app_server_process=m(s,t,r,{NODE_ENV:process.env.NODE_ENV,PORT:process.env.PORT,LOGS_PATH:process.env.LOGS_PATH,ROOT_URL:process.env.ROOT_URL,JOYSTICK_SETTINGS:JSON.stringify(c)}),p.push(process.app_server_process?.pid),k(t,o,e),process.app_server_restarting=!1},Z=async(s={})=>{const t=s?.config?.databases?.map((r={})=>r?.provider);for(let r=0;r{process.title=s?.environment==="test"?"joystick_test":"joystick",process.project_folder=T.basename(process.cwd()),process.loader=new $,s?.environment==="test"&&(console.log(""),process.loader.print(`Initializing test environment... +`)),process.env.LOGS_PATH=s?.logs||null,process.env.NODE_ENV=s?.environment||"development",process.env.PORT=t,process.env.IS_DEBUG_MODE=s?.debug},es=(s=2600)=>{i(`Port ${s} is already occupied. To start Joystick on this port, clear it and try again.`,{level:"danger"}),process.exit(0)},ts=(s=2600)=>parseInt(s||2600,10),rs=async()=>{const s=H(`${process.cwd()}/.joystick/build`);await u(s)&&await M(`${process.platform==="win32"?"rmdir /s /q":"rm -rf"} ${s}`)},os=async()=>{const s=[];for(let t=0;t0){const t=s?.filter(e=>e.type==="file"),r=s?.filter(e=>e.type==="directory");let o=`The following paths are missing and required in a Joystick project: -`;if(t?.length>0){o+=` ${h.yellow(">")} Required Files: +`;if(t?.length>0){o+=` ${f.yellow(">")} Required Files: -`;for(let e=0;e0?` -`:""}`)}`}}if(r?.length>0){o+=` ${h.yellow(">")} Required Directories: +`:""}`)}`}}if(r?.length>0){o+=` ${f.yellow(">")} Required Directories: -`;for(let e=0;e{const s=await g(`${process.cwd()}/.joystick`),t=await g(`${process.cwd()}/tests`);process.env.NODE_ENV==="test"&&(!s||!t)&&(i("joystick test must be run in a directory with a .joystick folder and tests folder.",{level:"danger",docs:"https://cheatcode.co/docs/joystick/cli/test"}),process.exit(0)),process.env.NODE_ENV!=="test"&&!s&&(i("joystick start must be run in a directory with a .joystick folder.",{level:"danger",docs:"https://cheatcode.co/docs/joystick/cli/start"}),process.exit(0))},os=async(s={})=>{await rs(),await ts(),await es();const t=ss(s?.port),r=await m(t),o=await m(t+1);r&&Z(t),o&&y(t),W(s,t);const e=await u(process.env.NODE_ENV);await Q(e),await x({environment:process.env.NODE_ENV,port:t,settings:e}),s?.tests&&s?.environment!=="test"&&(await m(1977)&&await y(1977),setTimeout(async()=>{try{const a=await u("test");await x({environment:"test",port:1977,settings:a});const n=O(_,!1,s?.imports||[],{NODE_ENV:"test",PORT:1977,LOGS_PATH:process.env.LOGS_PATH,ROOT_URL:process.env.ROOT_URL,JOYSTICK_SETTINGS:process.env.JOYSTICK_SETTINGS});d.push(n?.pid),process.test_app_server_process=n,n.external_process_ids=[],n.on("message",p=>{p?.external_process_id&&(n.external_process_ids=[...n.external_process_ids||[],p?.external_process_id],d.push(p?.external_process_id))}),n.on("error",p=>{}),n.stdout.on("data",async p=>{}),n.stderr.on("data",p=>{})}catch(a){console.error("Error starting test server:",a)}},100)),s?._is_test_server?E(_,!1,s?.imports||[],!1,!0):C({hot_module_reload:(c=[])=>F(c),restart_app_server:()=>b(_,s?.watch,e,s?.imports,s?.tests),start_app_server:()=>E(_,s?.watch,s?.imports,s?.tests,s?._is_test_server),start_hmr_server:s?.environment!=="test"?()=>Y(_,l,s?.watch,e,s?.imports,s?.tests):null,run_tests:s?.tests?async()=>{setTimeout(async()=>{try{await T({__dirname:l})}catch(c){console.error("Error running tests after file change:",c)}},2e3)}:null},{excluded_paths:e?.config?.build?.excluded_paths,custom_copy_paths:e?.config?.build?.copy_paths?.map(c=>({path:c}))||[]}),U(d,_,l)};var Is=os;export{Is as default}; +`;for(let e=0;e{const s=await u(`${process.cwd()}/.joystick`),t=await u(`${process.cwd()}/tests`);process.env.NODE_ENV==="test"&&(!s||!t)&&(i("joystick test must be run in a directory with a .joystick folder and tests folder.",{level:"danger",docs:"https://cheatcode.co/docs/joystick/cli/test"}),process.exit(0)),process.env.NODE_ENV!=="test"&&!s&&(i("joystick start must be run in a directory with a .joystick folder.",{level:"danger",docs:"https://cheatcode.co/docs/joystick/cli/start"}),process.exit(0))},as=async(s={})=>{await cs(),await os(),await rs();const t=ts(s?.port),r=await O(t),o=await O(t+1);r&&es(t),o&&y(t),ss(s,t);const e=await g(process.env.NODE_ENV);await Z(e),await S({environment:process.env.NODE_ENV,port:t,settings:e}),W(d,s?.watch,s?.imports||[],s?.tests,!1,e),s?.tests&&s?.environment!=="test"&&(await O(1977)&&await y(1977),setTimeout(async()=>{try{const a=`${process.cwd()}/settings.test.json`,D=await v.promises.readFile(a,"utf-8"),N=JSON.parse(D);await S({environment:"test",port:1977,settings:N});const n=m(d,!1,s?.imports||[],{NODE_ENV:"test",PORT:1977,LOGS_PATH:process.env.LOGS_PATH,ROOT_URL:process.env.ROOT_URL,JOYSTICK_SETTINGS:JSON.stringify(N)});p.push(n?.pid),process.test_app_server_process=n,n.external_process_ids=[],n.on("message",_=>{_?.external_process_id&&(n.external_process_ids=[...n.external_process_ids||[],_?.external_process_id],p.push(_?.external_process_id))}),n.on("error",_=>{}),n.stdout.on("data",async _=>{}),n.stderr.on("data",_=>{})}catch(a){console.error("Error starting test server:",a)}},100)),s?._is_test_server||G({hot_module_reload:(c=[])=>Y(c),restart_app_server:()=>b(d,s?.watch,e,s?.imports,s?.tests),start_app_server:()=>m(d,s?.watch,s?.imports||[],{NODE_ENV:process.env.NODE_ENV,PORT:process.env.PORT,LOGS_PATH:process.env.LOGS_PATH,ROOT_URL:process.env.ROOT_URL,JOYSTICK_SETTINGS:JSON.stringify(e)}),start_hmr_server:s?.environment!=="test"?()=>X(d,l,s?.watch,e,s?.imports,s?.tests):null,run_tests:s?.tests?async()=>{setTimeout(async()=>{try{await x({__dirname:l})}catch(c){console.error("Error running tests after file change:",c)}},2e3)}:null},{excluded_paths:e?.config?.build?.excluded_paths,custom_copy_paths:e?.config?.build?.copy_paths?.map(c=>({path:c}))||[]}),K(p,d,l)};var Is=as;export{Is as default}; //# sourceMappingURL=index.js.map diff --git a/cli/dist/lib/development_server/index.js.map b/cli/dist/lib/development_server/index.js.map index 451ec257e..a09e8fe1b 100644 --- a/cli/dist/lib/development_server/index.js.map +++ b/cli/dist/lib/development_server/index.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/lib/development_server/index.js"], - "sourcesContent": ["import chalk from 'chalk';\nimport child_process from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path, { dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport util from 'util';\nimport check_if_port_occupied from './check_if_port_occupied.js';\nimport cli_log from '../cli_log.js';\nimport get_database_process_ids from './get_database_process_ids.js';\n import get_platform_safe_path from '../get_platform_safe_path.js';\nimport kill_port_process from '../kill_port_process.js';\nimport load_settings from '../load_settings.js';\nimport Loader from '../loader.js';\nimport path_exists from '../path_exists.js';\nimport required_files from '../required_files.js';\nimport start_app_server from './start_app_server.js';\nimport start_databases from './start_databases.js';\nimport start_hmr_server from './start_hmr_server.js';\nimport watch_for_changes from './watch_for_changes/index.js';\nimport constants from '../constants.js';\nimport kill_process_ids from './kill_process_ids.js';\nimport run_tests, { run_tests_integrated } from './run_tests.js';\nimport debounce from '../debounce.js';\nimport download_database_binary from './databases/download_database_binary.js';\n\nconst { stat } = fs.promises;\nconst exec = util.promisify(child_process.exec);\n\nconst node_major_version = parseInt(\n process?.version?.split(\".\")[0]?.replace(\"v\", \"\"),\n 10\n);\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst process_ids = [];\n\nconst handle_run_tests = async (watch = false) => {\n const database_process_ids = get_database_process_ids();\n await run_tests({\n watch,\n __dirname,\n process_ids: [\n ...process_ids,\n ...database_process_ids,\n ],\n cleanup_process: process.cleanup_process,\n });\n};\n\nconst handle_signal_events = (process_ids = [], node_major_version = 0, __dirname = '') => {\n const exec_argv = [\"--no-warnings\"];\n\n if (node_major_version < 19) {\n exec_argv.push(\"--experimental-specifier-resolution=node\");\n }\n\n const cleanup_process = child_process.fork(\n path.resolve(`${__dirname}/cleanup.js`),\n [],\n {\n // NOTE: Run in detached mode so when parent process dies, the child still runs\n // and cleanup completes. Keep silent as we don't wan't/expect any messages.\n detached: true,\n silent: true,\n }\n );\n\n process.cleanup_process = cleanup_process;\n\n process.on(\"SIGINT\", async () => {\n const database_process_ids = get_database_process_ids();\n cleanup_process.send(JSON.stringify(({ process_ids: [...process_ids, ...database_process_ids] })));\n process.exit();\n });\n\n process.on(\"SIGTERM\", async () => {\n const database_process_ids = get_database_process_ids();\n cleanup_process.send(JSON.stringify(({ process_ids: [...process_ids, ...database_process_ids] })));\n process.exit();\n });\n};\n\nconst handle_signal_hmr_update = async (jobs = []) => {\n const has_settings_change = jobs?.find((job) => (job?.path?.match(constants.SETTINGS_FILE_NAME_REGEX))?.length > 0);\n const has_i18n_change = jobs?.find((job) => job?.path?.includes('i18n'));\n const has_index_html_change = jobs?.find((job) => job?.path?.includes('index.html'));\n const has_index_css_change = jobs?.find((job) => {\n return job?.path?.includes('index.css') || job?.path?.includes('css/');\n });\n const has_index_client_change = jobs?.find((job) => job?.path?.includes('index.client.js'));\n\n process.hmr_server_process.send(JSON.stringify({\n type: 'FILE_CHANGE',\n settings: has_settings_change ? await load_settings(process.env.NODE_ENV) : null,\n i18n_change: !!has_i18n_change,\n index_html_change: !!has_index_html_change,\n index_css_change: !!has_index_css_change,\n index_client_change: !!has_index_client_change,\n }));\n};\n\nconst handle_hmr_server_process_messages = (node_major_version = 0, watch = false, old_settings = {}, imports = [], run_integrated_tests = false) => {\n process.hmr_server_process.on(\"message\", async (message) => {\n const process_messages = [\n \"HAS_HMR_CONNECTIONS\",\n \"HAS_NO_HMR_CONNECTIONS\",\n \"HMR_UPDATE_COMPLETE\",\n ];\n\n if (!process_messages.includes(message?.type)) {\n process.loader.print(message);\n }\n\n if (message?.type === \"HAS_HMR_CONNECTIONS\") {\n process.hmr_server_process.has_connections = true;\n }\n\n if (message?.type === \"HAS_NO_HMR_CONNECTIONS\") {\n process.hmr_server_process.has_connections = false;\n }\n\n if (message?.type === \"HMR_UPDATE_COMPLETE\") {\n if (process.app_server_process && !process.app_server_restarting) {\n process.app_server_restarting = true;\n handle_restart_app_server(node_major_version, watch, old_settings, imports, run_integrated_tests);\n }\n }\n });\n};\n\nconst handle_hmr_server_process_stdio = () => {\n process.hmr_server_process.on(\"error\", (error) => {\n cli_log(error.toString(), {\n level: \"danger\",\n docs: \"https://github.com/cheatcode/joystick\",\n });\n });\n\n process.hmr_server_process.stdout.on(\"data\", (data) => {\n console.log(data.toString());\n });\n\n process.hmr_server_process.stderr.on(\"data\", (data) => {\n cli_log(data.toString(), {\n level: \"danger\",\n docs: \"https://github.com/cheatcode/joystick\",\n });\n });\n};\n\nconst handle_start_hmr_server = (node_major_version = 0, __dirname = '', watch = false, old_settings = {}, imports = [], run_integrated_tests = false) => {\n\tprocess.hmr_server_process = start_hmr_server(node_major_version, __dirname);\n process_ids.push(process.hmr_server_process?.pid);\n handle_hmr_server_process_stdio();\n handle_hmr_server_process_messages(node_major_version, watch, old_settings, imports, run_integrated_tests);\n};\n\nconst check_if_database_changes = async (old_settings = {}) => {\n const new_settings = await load_settings(process.env.NODE_ENV);\n const new_databse_settings = new_settings?.config?.databases ? JSON.stringify(new_settings?.config?.databases) : '';\n const old_database_settings = old_settings?.config?.databases ? JSON.stringify(old_settings?.config?.databases) : '';\n return new_databse_settings !== old_database_settings;\n};\n\nconst handle_restart_app_server = async (node_major_version = 0, watch = false, old_settings = null, imports = [], run_integrated_tests = false) => {\n debounce(async () => {\n const has_database_changes = await check_if_database_changes(old_settings);\n\n if (has_database_changes) {\n const database_process_ids = get_database_process_ids();\n\n cli_log(`Database configuration has changed in settings.${process.env.NODE_ENV}.json. Please restart your app to add, change, or remove databases.`, {\n level: \"danger\",\n docs: \"https://cheatcode.co/docs/joystick/structure\",\n });\n\n kill_process_ids([\n process.hmr_server_process?.pid,\n process.app_server_process?.pid,\n ...database_process_ids,\n ]);\n\n process.exit(0);\n } else {\n kill_process_ids([\n ...(process.app_server_process.external_process_ids || []),\n ]);\n\n await kill_port_process(process.env.PORT);\n handle_start_app_server(node_major_version, watch, imports, run_integrated_tests);\n }\n }, 300);\n};\n\nconst handle_app_server_process_stdio = (watch = false, run_integrated_tests = false, is_test_server = false) => {\n // NOTE: Default this in case we never get any external process IDs.\n process.app_server_process.external_process_ids = [];\n\n process.app_server_process.on('message', (message_from_child) => {\n if (message_from_child?.external_process_id) {\n process.app_server_process.external_process_ids = [\n ...(process.app_server_process.external_process_ids || []),\n message_from_child?.external_process_id,\n ];\n }\n });\n\n process.app_server_process.on('error', (error) => {\n if (!is_test_server) {\n cli_log(error.toString(), {\n level: \"danger\",\n docs: \"https://github.com/cheatcode/joystick\",\n });\n }\n });\n\n process.app_server_process.stdout.on(\"data\", async (data) => {\n \tconst stdout = data.toString();\n const is_startup_notification = stdout.includes(\"App running at:\");\n\n // NOTE: Suppress all test server output\n if (is_test_server) {\n process.loader.print(stdout); // temp to debug\n return;\n }\n\n // NOTE: Main server output handling\n \tif (stdout && is_startup_notification && process.env.NODE_ENV !== 'test') {\n \t\tprocess.loader.print(stdout);\n \t}\n\n if (stdout && !is_startup_notification && !stdout.includes(\"BUILD_ERROR\")) {\n console.log(stdout);\n }\n\n // NOTE: Run tests here so we can guarantee app server is running. Do a slight delay\n // to ensure that test routes are registered.\n if (stdout && is_startup_notification && process.env.NODE_ENV === 'test') {\n handle_run_tests(watch);\n }\n\n // NOTE: Run integrated tests when --tests flag is used and server has started\n if (stdout && is_startup_notification && run_integrated_tests && process.env.NODE_ENV !== 'test') {\n // NOTE: Add delay to avoid jarring UX and ensure server is fully ready\n setTimeout(async () => {\n try {\n await run_tests_integrated({\n __dirname,\n });\n } catch (error) {\n console.error('Error running integrated tests:', error);\n }\n }, 2000);\n }\n });\n\n process.app_server_process.stderr.on(\"data\", (data) => {\n // if (!is_test_server) {\n cli_log(data.toString(), {\n level: \"danger\",\n docs: \"https://cheatcode.co/docs/joystick\",\n });\n // }\n });\n};\n\nconst handle_start_app_server = (node_major_version = 0, watch = false, imports = [], run_integrated_tests = false, is_test_server = false) => {\n\tprocess.app_server_process = start_app_server(node_major_version, watch, imports);\n process_ids.push(process.app_server_process?.pid);\n handle_app_server_process_stdio(watch, run_integrated_tests, is_test_server);\n process.app_server_restarting = false;\n};\n\nconst install_missing_databases = async (settings = {}) => {\n const required_databases = settings?.config?.databases?.map((database = {}) => {\n return database?.provider;\n });\n\n for (let i = 0; i < required_databases?.length; i += 1) {\n const provider_name = required_databases[i];\n await download_database_binary(provider_name);\n }\n};\n\nconst set_process_variables = (development_server_options = {}, port = 2600) => {\n process.title = development_server_options?.environment === 'test' ? \"joystick_test\" : 'joystick';\n process.project_folder = path.basename(process.cwd());\n process.loader = new Loader();\n\n if (development_server_options?.environment === 'test') {\n console.log(''); // NOTE: Silly, but gives us better styling.\n process.loader.print(\"Initializing test environment...\\n\");\n }\n\n process.env.LOGS_PATH = development_server_options?.logs || null;\n process.env.NODE_ENV = development_server_options?.environment || \"development\";\n process.env.PORT = port;\n process.env.IS_DEBUG_MODE = development_server_options?.debug;\n};\n\nconst warn_app_port_occupied = (port = 2600) => {\n cli_log(`Port ${port} is already occupied. To start Joystick on this port, clear it and try again.`, {\n level: 'danger',\n });\n\n process.exit(0);\n};\n\nconst get_port = (port = 2600) => {\n\treturn parseInt(port || 2600, 10);\n};\n\nconst clean_up_existing_build = async () => {\n\tconst build_path = get_platform_safe_path(`${process.cwd()}/.joystick/build`);\n\n\tif (await path_exists(build_path)) {\n\t\tawait exec(`${process.platform === 'win32' ? 'rmdir /s /q' : 'rm -rf'} ${build_path}`);\n\t}\n};\n\nconst check_for_required_files = async () => {\n const missing_files = [];\n\n for (let i = 0; i < required_files?.length; i += 1) {\n const required_file = required_files[i];\n const exists = await path_exists(`${process.cwd()}/${required_file.path}`);\n const stats = exists && await stat(`${process.cwd()}/${required_file.path}`);\n\n if (required_file && required_file.type === \"file\" && (!exists || (exists && !stats.isFile()))) {\n missing_files.push({ type: 'file', path: required_file.path });\n }\n\n if (required_file && required_file.type === \"directory\" && (!exists || (exists && !stats.isDirectory()))) {\n missing_files.push({ type: 'directory', path: required_file.path });\n }\n }\n\n if (missing_files?.length > 0) {\n const files = missing_files?.filter((path) => path.type === 'file');\n const directories = missing_files?.filter((path) => path.type === 'directory');\n\n let error = `The following paths are missing and required in a Joystick project:\\n\\n`;\n\n if (files?.length > 0) {\n error += ` ${chalk.yellow('>')} Required Files:\\n\\n`;\n\n for (let i = 0; i < files?.length; i += 1) {\n const file = files[i];\n const is_last_file = i +1 === files?.length;\n error += ` ${chalk.red(`/${file.path}\\n${is_last_file && directories?.length > 0 ? '\\n' : ''}`)}`;\n }\n }\n\n if (directories?.length > 0) {\n error += ` ${chalk.yellow('>')} Required Directories:\\n\\n`;\n\n for (let i = 0; i < directories?.length; i += 1) {\n const file = directories[i];\n error += ` ${chalk.red(`/${file.path}\\n`)}`;\n }\n }\n\n cli_log(error, {\n level: \"danger\",\n docs: \"https://cheatcode.co/docs/joystick/structure\",\n });\n\n process.exit(0);\n }\n};\n\nconst warn_invalid_joystick_environment = async () => {\n const has_joystick_folder = await path_exists(`${process.cwd()}/.joystick`);\n const has_tests_folder = await path_exists(`${process.cwd()}/tests`);\n\n if (process.env.NODE_ENV === 'test' && (!has_joystick_folder || !has_tests_folder)) {\n cli_log(\n \"joystick test must be run in a directory with a .joystick folder and tests folder.\",\n {\n level: \"danger\",\n docs: \"https://cheatcode.co/docs/joystick/cli/test\",\n }\n );\n\n process.exit(0);\n }\n\n if (process.env.NODE_ENV !== 'test' && !has_joystick_folder) {\n cli_log(\n \"joystick start must be run in a directory with a .joystick folder.\",\n {\n level: \"danger\",\n docs: \"https://cheatcode.co/docs/joystick/cli/start\",\n }\n );\n\n process.exit(0);\n }\n};\n\nconst development_server = async (development_server_options = {}) => {\n await warn_invalid_joystick_environment();\n await check_for_required_files();\n\n\tawait clean_up_existing_build();\n\n\tconst port = get_port(development_server_options?.port);\n\tconst app_port_occupied = await check_if_port_occupied(port);\n const hmr_port_occupied = await check_if_port_occupied(port + 1);\n\n if (app_port_occupied) {\n \twarn_app_port_occupied(port);\n }\n\n if (hmr_port_occupied) {\n \tkill_port_process(port);\n }\n\n set_process_variables(development_server_options, port);\n\n const settings = await load_settings(process.env.NODE_ENV);\n\n await install_missing_databases(settings);\n\n await start_databases({\n environment: process.env.NODE_ENV,\n port,\n settings\n });\n\n // NOTE: If tests flag is enabled, start a separate test server on port 1977.\n if (development_server_options?.tests && development_server_options?.environment !== 'test') {\n const test_port_occupied = await check_if_port_occupied(1977);\n if (test_port_occupied) {\n await kill_port_process(1977);\n }\n\n // NOTE: Start test server directly without recursive development_server call\n setTimeout(async () => {\n try {\n // NOTE: Start test databases\n const test_settings = await load_settings('test');\n\n await start_databases({\n environment: 'test',\n port: 1977,\n settings: test_settings,\n });\n \n const test_app_server = start_app_server(node_major_version, false, development_server_options?.imports || [], {\n NODE_ENV: 'test',\n PORT: 1977,\n LOGS_PATH: process.env.LOGS_PATH,\n ROOT_URL: process.env.ROOT_URL,\n JOYSTICK_SETTINGS: process.env.JOYSTICK_SETTINGS,\n });\n\n process_ids.push(test_app_server?.pid);\n \n // NOTE: Store test server separately to avoid interfering with main server\n process.test_app_server_process = test_app_server;\n \n // NOTE: Handle test server stdio without integrated tests to avoid recursion\n test_app_server.external_process_ids = [];\n \n test_app_server.on('message', (message_from_child) => {\n if (message_from_child?.external_process_id) {\n test_app_server.external_process_ids = [\n ...(test_app_server.external_process_ids || []),\n message_from_child?.external_process_id,\n ];\n // NOTE: Also track external process IDs for cleanup\n process_ids.push(message_from_child?.external_process_id);\n }\n });\n \n test_app_server.on('error', (error) => {\n // NOTE: Suppress test server errors to avoid noise\n });\n \n test_app_server.stdout.on(\"data\", async (data) => {\n // NOTE: Suppress test server output to avoid noise\n });\n \n test_app_server.stderr.on(\"data\", (data) => {\n // NOTE: Suppress test server errors to avoid noise\n }); \n } catch (error) {\n console.error('Error starting test server:', error);\n }\n }, 100); // Small delay to let main server start first\n }\n\n // NOTE: Only set up file watching for non-test servers\n if (!development_server_options?._is_test_server) {\n watch_for_changes({\n hot_module_reload: (jobs = []) => handle_signal_hmr_update(jobs),\n restart_app_server: () => handle_restart_app_server(\n node_major_version,\n development_server_options?.watch,\n settings,\n development_server_options?.imports,\n development_server_options?.tests,\n ),\n start_app_server: () => handle_start_app_server(\n node_major_version,\n development_server_options?.watch,\n development_server_options?.imports,\n development_server_options?.tests,\n development_server_options?._is_test_server,\n ),\n start_hmr_server: development_server_options?.environment !== 'test' ? () => handle_start_hmr_server(\n node_major_version,\n __dirname,\n development_server_options?.watch,\n settings,\n development_server_options?.imports,\n development_server_options?.tests,\n ) : null,\n run_tests: development_server_options?.tests ? async () => {\n // NOTE: Add delay to avoid jarring UX when test files change\n setTimeout(async () => {\n try {\n await run_tests_integrated({\n __dirname,\n });\n } catch (error) {\n console.error('Error running tests after file change:', error);\n }\n }, 2000);\n } : null,\n }, {\n excluded_paths: settings?.config?.build?.excluded_paths,\n custom_copy_paths: settings?.config?.build?.copy_paths?.map((path) => {\n return { path };\n }) || [],\n });\n } else {\n // NOTE: For test server, just start the app server without file watching\n handle_start_app_server(\n node_major_version,\n false, // No file watching for test server\n development_server_options?.imports || [],\n false, // No integrated tests for test server\n true, // This is a test server\n );\n }\n\n handle_signal_events(process_ids, node_major_version, __dirname);\n};\n\nexport default development_server;\n"], - "mappings": "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", - "names": ["chalk", "child_process", "fs", "path", "dirname", "fileURLToPath", "util", "check_if_port_occupied", "cli_log", "get_database_process_ids", "get_platform_safe_path", "kill_port_process", "load_settings", "Loader", "path_exists", "required_files", "start_app_server", "start_databases", "start_hmr_server", "watch_for_changes", "constants", "kill_process_ids", "run_tests", "run_tests_integrated", "debounce", "download_database_binary", "stat", "exec", "node_major_version", "__filename", "__dirname", "process_ids", "handle_run_tests", "watch", "database_process_ids", "handle_signal_events", "exec_argv", "cleanup_process", "handle_signal_hmr_update", "jobs", "has_settings_change", "job", "has_i18n_change", "has_index_html_change", "has_index_css_change", "has_index_client_change", "handle_hmr_server_process_messages", "old_settings", "imports", "run_integrated_tests", "message", "handle_restart_app_server", "handle_hmr_server_process_stdio", "error", "data", "handle_start_hmr_server", "check_if_database_changes", "new_settings", "new_databse_settings", "old_database_settings", "handle_start_app_server", "handle_app_server_process_stdio", "is_test_server", "message_from_child", "stdout", "is_startup_notification", "install_missing_databases", "settings", "required_databases", "database", "i", "provider_name", "set_process_variables", "development_server_options", "port", "warn_app_port_occupied", "get_port", "clean_up_existing_build", "build_path", "check_for_required_files", "missing_files", "required_file", "exists", "stats", "files", "directories", "file", "is_last_file", "warn_invalid_joystick_environment", "has_joystick_folder", "has_tests_folder", "development_server", "app_port_occupied", "hmr_port_occupied", "test_settings", "test_app_server", "index_default"] + "sourcesContent": ["import chalk from 'chalk';\nimport child_process from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path, { dirname } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport util from 'util';\nimport check_if_port_occupied from './check_if_port_occupied.js';\nimport cli_log from '../cli_log.js';\nimport get_database_process_ids from './get_database_process_ids.js';\n import get_platform_safe_path from '../get_platform_safe_path.js';\nimport kill_port_process from '../kill_port_process.js';\nimport load_settings from '../load_settings.js';\nimport Loader from '../loader.js';\nimport path_exists from '../path_exists.js';\nimport required_files from '../required_files.js';\nimport start_app_server from './start_app_server.js';\nimport start_databases from './start_databases.js';\nimport start_hmr_server from './start_hmr_server.js';\nimport watch_for_changes from './watch_for_changes/index.js';\nimport constants from '../constants.js';\nimport kill_process_ids from './kill_process_ids.js';\nimport run_tests, { run_tests_integrated } from './run_tests.js';\nimport debounce from '../debounce.js';\nimport download_database_binary from './databases/download_database_binary.js';\n\nconst { stat } = fs.promises;\nconst exec = util.promisify(child_process.exec);\n\nconst node_major_version = parseInt(\n process?.version?.split(\".\")[0]?.replace(\"v\", \"\"),\n 10\n);\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst process_ids = [];\n\nconst handle_run_tests = async (watch = false) => {\n const database_process_ids = get_database_process_ids();\n await run_tests({\n watch,\n __dirname,\n process_ids: [\n ...process_ids,\n ...database_process_ids,\n ],\n cleanup_process: process.cleanup_process,\n });\n};\n\nconst handle_signal_events = (process_ids = [], node_major_version = 0, __dirname = '') => {\n const exec_argv = [\"--no-warnings\"];\n\n if (node_major_version < 19) {\n exec_argv.push(\"--experimental-specifier-resolution=node\");\n }\n\n const cleanup_process = child_process.fork(\n path.resolve(`${__dirname}/cleanup.js`),\n [],\n {\n // NOTE: Run in detached mode so when parent process dies, the child still runs\n // and cleanup completes. Keep silent as we don't wan't/expect any messages.\n detached: true,\n silent: true,\n }\n );\n\n process.cleanup_process = cleanup_process;\n\n process.on(\"SIGINT\", async () => {\n const database_process_ids = get_database_process_ids();\n cleanup_process.send(JSON.stringify(({ process_ids: [...process_ids, ...database_process_ids] })));\n process.exit();\n });\n\n process.on(\"SIGTERM\", async () => {\n const database_process_ids = get_database_process_ids();\n cleanup_process.send(JSON.stringify(({ process_ids: [...process_ids, ...database_process_ids] })));\n process.exit();\n });\n};\n\nconst handle_signal_hmr_update = async (jobs = []) => {\n const has_settings_change = jobs?.find((job) => (job?.path?.match(constants.SETTINGS_FILE_NAME_REGEX))?.length > 0);\n const has_i18n_change = jobs?.find((job) => job?.path?.includes('i18n'));\n const has_index_html_change = jobs?.find((job) => job?.path?.includes('index.html'));\n const has_index_css_change = jobs?.find((job) => {\n return job?.path?.includes('index.css') || job?.path?.includes('css/');\n });\n const has_index_client_change = jobs?.find((job) => job?.path?.includes('index.client.js'));\n\n process.hmr_server_process.send(JSON.stringify({\n type: 'FILE_CHANGE',\n settings: has_settings_change ? await load_settings(process.env.NODE_ENV) : null,\n i18n_change: !!has_i18n_change,\n index_html_change: !!has_index_html_change,\n index_css_change: !!has_index_css_change,\n index_client_change: !!has_index_client_change,\n }));\n};\n\nconst handle_hmr_server_process_messages = (node_major_version = 0, watch = false, old_settings = {}, imports = [], run_integrated_tests = false) => {\n process.hmr_server_process.on(\"message\", async (message) => {\n const process_messages = [\n \"HAS_HMR_CONNECTIONS\",\n \"HAS_NO_HMR_CONNECTIONS\",\n \"HMR_UPDATE_COMPLETE\",\n ];\n\n if (!process_messages.includes(message?.type)) {\n process.loader.print(message);\n }\n\n if (message?.type === \"HAS_HMR_CONNECTIONS\") {\n process.hmr_server_process.has_connections = true;\n }\n\n if (message?.type === \"HAS_NO_HMR_CONNECTIONS\") {\n process.hmr_server_process.has_connections = false;\n }\n\n if (message?.type === \"HMR_UPDATE_COMPLETE\") {\n if (process.app_server_process && !process.app_server_restarting) {\n process.app_server_restarting = true;\n handle_restart_app_server(node_major_version, watch, old_settings, imports, run_integrated_tests);\n }\n }\n });\n};\n\nconst handle_hmr_server_process_stdio = () => {\n process.hmr_server_process.on(\"error\", (error) => {\n cli_log(error.toString(), {\n level: \"danger\",\n docs: \"https://github.com/cheatcode/joystick\",\n });\n });\n\n process.hmr_server_process.stdout.on(\"data\", (data) => {\n console.log(data.toString());\n });\n\n process.hmr_server_process.stderr.on(\"data\", (data) => {\n cli_log(data.toString(), {\n level: \"danger\",\n docs: \"https://github.com/cheatcode/joystick\",\n });\n });\n};\n\nconst handle_start_hmr_server = (node_major_version = 0, __dirname = '', watch = false, old_settings = {}, imports = [], run_integrated_tests = false) => {\n\tprocess.hmr_server_process = start_hmr_server(node_major_version, __dirname);\n process_ids.push(process.hmr_server_process?.pid);\n handle_hmr_server_process_stdio();\n handle_hmr_server_process_messages(node_major_version, watch, old_settings, imports, run_integrated_tests);\n};\n\nconst check_if_database_changes = async (old_settings = {}) => {\n const new_settings = await load_settings(process.env.NODE_ENV);\n const new_databse_settings = new_settings?.config?.databases ? JSON.stringify(new_settings?.config?.databases) : '';\n const old_database_settings = old_settings?.config?.databases ? JSON.stringify(old_settings?.config?.databases) : '';\n return new_databse_settings !== old_database_settings;\n};\n\nconst handle_restart_app_server = async (node_major_version = 0, watch = false, old_settings = null, imports = [], run_integrated_tests = false) => {\n debounce(async () => {\n const has_database_changes = await check_if_database_changes(old_settings);\n\n if (has_database_changes) {\n const database_process_ids = get_database_process_ids();\n\n cli_log(`Database configuration has changed in settings.${process.env.NODE_ENV}.json. Please restart your app to add, change, or remove databases.`, {\n level: \"danger\",\n docs: \"https://cheatcode.co/docs/joystick/structure\",\n });\n\n kill_process_ids([\n process.hmr_server_process?.pid,\n process.app_server_process?.pid,\n ...database_process_ids,\n ]);\n\n process.exit(0);\n } else {\n kill_process_ids([\n ...(process.app_server_process.external_process_ids || []),\n ]);\n\n await kill_port_process(process.env.PORT);\n const current_settings = await load_settings(process.env.NODE_ENV);\n process.app_server_process = start_app_server(node_major_version, watch, imports, {\n NODE_ENV: process.env.NODE_ENV,\n PORT: process.env.PORT,\n LOGS_PATH: process.env.LOGS_PATH,\n ROOT_URL: process.env.ROOT_URL,\n JOYSTICK_SETTINGS: JSON.stringify(current_settings),\n });\n process_ids.push(process.app_server_process?.pid);\n handle_app_server_process_stdio(watch, run_integrated_tests, false);\n process.app_server_restarting = false;\n }\n }, 300);\n};\n\nconst handle_app_server_process_stdio = (watch = false, run_integrated_tests = false, is_test_server = false) => {\n // NOTE: Default this in case we never get any external process IDs.\n process.app_server_process.external_process_ids = [];\n\n process.app_server_process.on('message', (message_from_child) => {\n if (message_from_child?.external_process_id) {\n process.app_server_process.external_process_ids = [\n ...(process.app_server_process.external_process_ids || []),\n message_from_child?.external_process_id,\n ];\n }\n });\n\n process.app_server_process.on('error', (error) => {\n if (!is_test_server) {\n cli_log(error.toString(), {\n level: \"danger\",\n docs: \"https://github.com/cheatcode/joystick\",\n });\n }\n });\n\n process.app_server_process.stdout.on(\"data\", async (data) => {\n \tconst stdout = data.toString();\n const is_startup_notification = stdout.includes(\"App running at:\");\n\n // NOTE: Suppress all test server output\n if (is_test_server) {\n process.loader.print(stdout); // temp to debug\n return;\n }\n\n // NOTE: Main server output handling\n \tif (stdout && is_startup_notification && process.env.NODE_ENV !== 'test') {\n \t\tprocess.loader.print(stdout);\n \t}\n\n if (stdout && !is_startup_notification && !stdout.includes(\"BUILD_ERROR\")) {\n console.log(stdout);\n }\n\n // NOTE: Run tests here so we can guarantee app server is running. Do a slight delay\n // to ensure that test routes are registered.\n if (stdout && is_startup_notification && process.env.NODE_ENV === 'test') {\n handle_run_tests(watch);\n }\n\n // NOTE: Run integrated tests when --tests flag is used and server has started\n if (stdout && is_startup_notification && run_integrated_tests && process.env.NODE_ENV !== 'test') {\n // NOTE: Add delay to avoid jarring UX and ensure server is fully ready\n setTimeout(async () => {\n try {\n await run_tests_integrated({\n __dirname,\n });\n } catch (error) {\n console.error('Error running integrated tests:', error);\n }\n }, 2000);\n }\n });\n\n process.app_server_process.stderr.on(\"data\", (data) => {\n // if (!is_test_server) {\n cli_log(data.toString(), {\n level: \"danger\",\n docs: \"https://cheatcode.co/docs/joystick\",\n });\n // }\n });\n};\n\nconst handle_start_app_server = (node_major_version = 0, watch = false, imports = [], run_integrated_tests = false, is_test_server = false, settings = {}) => {\n\tprocess.app_server_process = start_app_server(node_major_version, watch, imports, {\n NODE_ENV: process.env.NODE_ENV,\n PORT: process.env.PORT,\n LOGS_PATH: process.env.LOGS_PATH,\n ROOT_URL: process.env.ROOT_URL,\n JOYSTICK_SETTINGS: JSON.stringify(settings),\n });\n process_ids.push(process.app_server_process?.pid);\n handle_app_server_process_stdio(watch, run_integrated_tests, is_test_server);\n process.app_server_restarting = false;\n};\n\nconst install_missing_databases = async (settings = {}) => {\n const required_databases = settings?.config?.databases?.map((database = {}) => {\n return database?.provider;\n });\n\n for (let i = 0; i < required_databases?.length; i += 1) {\n const provider_name = required_databases[i];\n await download_database_binary(provider_name);\n }\n};\n\nconst set_process_variables = (development_server_options = {}, port = 2600) => {\n process.title = development_server_options?.environment === 'test' ? \"joystick_test\" : 'joystick';\n process.project_folder = path.basename(process.cwd());\n process.loader = new Loader();\n\n if (development_server_options?.environment === 'test') {\n console.log(''); // NOTE: Silly, but gives us better styling.\n process.loader.print(\"Initializing test environment...\\n\");\n }\n\n process.env.LOGS_PATH = development_server_options?.logs || null;\n process.env.NODE_ENV = development_server_options?.environment || \"development\";\n process.env.PORT = port;\n process.env.IS_DEBUG_MODE = development_server_options?.debug;\n};\n\nconst warn_app_port_occupied = (port = 2600) => {\n cli_log(`Port ${port} is already occupied. To start Joystick on this port, clear it and try again.`, {\n level: 'danger',\n });\n\n process.exit(0);\n};\n\nconst get_port = (port = 2600) => {\n\treturn parseInt(port || 2600, 10);\n};\n\nconst clean_up_existing_build = async () => {\n\tconst build_path = get_platform_safe_path(`${process.cwd()}/.joystick/build`);\n\n\tif (await path_exists(build_path)) {\n\t\tawait exec(`${process.platform === 'win32' ? 'rmdir /s /q' : 'rm -rf'} ${build_path}`);\n\t}\n};\n\nconst check_for_required_files = async () => {\n const missing_files = [];\n\n for (let i = 0; i < required_files?.length; i += 1) {\n const required_file = required_files[i];\n const exists = await path_exists(`${process.cwd()}/${required_file.path}`);\n const stats = exists && await stat(`${process.cwd()}/${required_file.path}`);\n\n if (required_file && required_file.type === \"file\" && (!exists || (exists && !stats.isFile()))) {\n missing_files.push({ type: 'file', path: required_file.path });\n }\n\n if (required_file && required_file.type === \"directory\" && (!exists || (exists && !stats.isDirectory()))) {\n missing_files.push({ type: 'directory', path: required_file.path });\n }\n }\n\n if (missing_files?.length > 0) {\n const files = missing_files?.filter((path) => path.type === 'file');\n const directories = missing_files?.filter((path) => path.type === 'directory');\n\n let error = `The following paths are missing and required in a Joystick project:\\n\\n`;\n\n if (files?.length > 0) {\n error += ` ${chalk.yellow('>')} Required Files:\\n\\n`;\n\n for (let i = 0; i < files?.length; i += 1) {\n const file = files[i];\n const is_last_file = i +1 === files?.length;\n error += ` ${chalk.red(`/${file.path}\\n${is_last_file && directories?.length > 0 ? '\\n' : ''}`)}`;\n }\n }\n\n if (directories?.length > 0) {\n error += ` ${chalk.yellow('>')} Required Directories:\\n\\n`;\n\n for (let i = 0; i < directories?.length; i += 1) {\n const file = directories[i];\n error += ` ${chalk.red(`/${file.path}\\n`)}`;\n }\n }\n\n cli_log(error, {\n level: \"danger\",\n docs: \"https://cheatcode.co/docs/joystick/structure\",\n });\n\n process.exit(0);\n }\n};\n\nconst warn_invalid_joystick_environment = async () => {\n const has_joystick_folder = await path_exists(`${process.cwd()}/.joystick`);\n const has_tests_folder = await path_exists(`${process.cwd()}/tests`);\n\n if (process.env.NODE_ENV === 'test' && (!has_joystick_folder || !has_tests_folder)) {\n cli_log(\n \"joystick test must be run in a directory with a .joystick folder and tests folder.\",\n {\n level: \"danger\",\n docs: \"https://cheatcode.co/docs/joystick/cli/test\",\n }\n );\n\n process.exit(0);\n }\n\n if (process.env.NODE_ENV !== 'test' && !has_joystick_folder) {\n cli_log(\n \"joystick start must be run in a directory with a .joystick folder.\",\n {\n level: \"danger\",\n docs: \"https://cheatcode.co/docs/joystick/cli/start\",\n }\n );\n\n process.exit(0);\n }\n};\n\nconst development_server = async (development_server_options = {}) => {\n await warn_invalid_joystick_environment();\n await check_for_required_files();\n\n\tawait clean_up_existing_build();\n\n\tconst port = get_port(development_server_options?.port);\n\tconst app_port_occupied = await check_if_port_occupied(port);\n const hmr_port_occupied = await check_if_port_occupied(port + 1);\n\n if (app_port_occupied) {\n \twarn_app_port_occupied(port);\n }\n\n if (hmr_port_occupied) {\n \tkill_port_process(port);\n }\n\n set_process_variables(development_server_options, port);\n\n const settings = await load_settings(process.env.NODE_ENV);\n\n await install_missing_databases(settings);\n\n await start_databases({\n environment: process.env.NODE_ENV,\n port,\n settings\n });\n\n // NOTE: Start the main app server first\n handle_start_app_server(\n node_major_version,\n development_server_options?.watch,\n development_server_options?.imports || [],\n development_server_options?.tests, // Pass tests flag for integrated test running\n false, // This is not a test server\n settings, // Pass the loaded settings\n );\n\n // NOTE: If tests flag is enabled, start a separate test server on port 1977.\n if (development_server_options?.tests && development_server_options?.environment !== 'test') {\n const test_port_occupied = await check_if_port_occupied(1977);\n if (test_port_occupied) {\n await kill_port_process(1977);\n }\n\n // NOTE: Start test server directly without recursive development_server call\n setTimeout(async () => {\n try {\n // NOTE: Load test settings without contaminating global process.env.JOYSTICK_SETTINGS\n const test_settings_file_path = `${process.cwd()}/settings.test.json`;\n const test_settings_raw = await fs.promises.readFile(test_settings_file_path, 'utf-8');\n const test_settings = JSON.parse(test_settings_raw);\n\n await start_databases({\n environment: 'test',\n port: 1977,\n settings: test_settings,\n });\n \n const test_app_server = start_app_server(node_major_version, false, development_server_options?.imports || [], {\n NODE_ENV: 'test',\n PORT: 1977,\n LOGS_PATH: process.env.LOGS_PATH,\n ROOT_URL: process.env.ROOT_URL,\n JOYSTICK_SETTINGS: JSON.stringify(test_settings),\n });\n\n process_ids.push(test_app_server?.pid);\n \n // NOTE: Store test server separately to avoid interfering with main server\n process.test_app_server_process = test_app_server;\n \n // NOTE: Handle test server stdio without integrated tests to avoid recursion\n test_app_server.external_process_ids = [];\n \n test_app_server.on('message', (message_from_child) => {\n if (message_from_child?.external_process_id) {\n test_app_server.external_process_ids = [\n ...(test_app_server.external_process_ids || []),\n message_from_child?.external_process_id,\n ];\n // NOTE: Also track external process IDs for cleanup\n process_ids.push(message_from_child?.external_process_id);\n }\n });\n \n test_app_server.on('error', (error) => {\n // NOTE: Suppress test server errors to avoid noise\n });\n \n test_app_server.stdout.on(\"data\", async (data) => {\n // NOTE: Suppress test server output to avoid noise\n });\n \n test_app_server.stderr.on(\"data\", (data) => {\n // NOTE: Suppress test server errors to avoid noise\n }); \n } catch (error) {\n console.error('Error starting test server:', error);\n }\n }, 100); // Small delay to let main server start first\n }\n\n // NOTE: Only set up file watching for non-test servers\n if (!development_server_options?._is_test_server) {\n watch_for_changes({\n hot_module_reload: (jobs = []) => handle_signal_hmr_update(jobs),\n restart_app_server: () => handle_restart_app_server(\n node_major_version,\n development_server_options?.watch,\n settings,\n development_server_options?.imports,\n development_server_options?.tests,\n ),\n start_app_server: () => start_app_server(node_major_version, development_server_options?.watch, development_server_options?.imports || [], {\n NODE_ENV: process.env.NODE_ENV,\n PORT: process.env.PORT,\n LOGS_PATH: process.env.LOGS_PATH,\n ROOT_URL: process.env.ROOT_URL,\n JOYSTICK_SETTINGS: JSON.stringify(settings),\n }),\n start_hmr_server: development_server_options?.environment !== 'test' ? () => handle_start_hmr_server(\n node_major_version,\n __dirname,\n development_server_options?.watch,\n settings,\n development_server_options?.imports,\n development_server_options?.tests,\n ) : null,\n run_tests: development_server_options?.tests ? async () => {\n // NOTE: Add delay to avoid jarring UX when test files change\n setTimeout(async () => {\n try {\n await run_tests_integrated({\n __dirname,\n });\n } catch (error) {\n console.error('Error running tests after file change:', error);\n }\n }, 2000);\n } : null,\n }, {\n excluded_paths: settings?.config?.build?.excluded_paths,\n custom_copy_paths: settings?.config?.build?.copy_paths?.map((path) => {\n return { path };\n }) || [],\n });\n }\n\n handle_signal_events(process_ids, node_major_version, __dirname);\n};\n\nexport default development_server;\n"], + "mappings": "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", + "names": ["chalk", "child_process", "fs", "path", "dirname", "fileURLToPath", "util", "check_if_port_occupied", "cli_log", "get_database_process_ids", "get_platform_safe_path", "kill_port_process", "load_settings", "Loader", "path_exists", "required_files", "start_app_server", "start_databases", "start_hmr_server", "watch_for_changes", "constants", "kill_process_ids", "run_tests", "run_tests_integrated", "debounce", "download_database_binary", "stat", "exec", "node_major_version", "__filename", "__dirname", "process_ids", "handle_run_tests", "watch", "database_process_ids", "handle_signal_events", "exec_argv", "cleanup_process", "handle_signal_hmr_update", "jobs", "has_settings_change", "job", "has_i18n_change", "has_index_html_change", "has_index_css_change", "has_index_client_change", "handle_hmr_server_process_messages", "old_settings", "imports", "run_integrated_tests", "message", "handle_restart_app_server", "handle_hmr_server_process_stdio", "error", "data", "handle_start_hmr_server", "check_if_database_changes", "new_settings", "new_databse_settings", "old_database_settings", "current_settings", "handle_app_server_process_stdio", "is_test_server", "message_from_child", "stdout", "is_startup_notification", "handle_start_app_server", "settings", "install_missing_databases", "required_databases", "database", "i", "provider_name", "set_process_variables", "development_server_options", "port", "warn_app_port_occupied", "get_port", "clean_up_existing_build", "build_path", "check_for_required_files", "missing_files", "required_file", "exists", "stats", "files", "directories", "file", "is_last_file", "warn_invalid_joystick_environment", "has_joystick_folder", "has_tests_folder", "development_server", "app_port_occupied", "hmr_port_occupied", "test_settings_file_path", "test_settings_raw", "test_settings", "test_app_server", "index_default"] } diff --git a/cli/dist/lib/load_settings.js b/cli/dist/lib/load_settings.js index 38abba64f..a4f740012 100644 --- a/cli/dist/lib/load_settings.js +++ b/cli/dist/lib/load_settings.js @@ -1,2 +1,2 @@ -import n from"fs";import r from"./cli_log.js";import c from"./is_valid_json_string.js";import a from"./path_exists.js";const{readFile:l}=n.promises,f=async(t=null)=>{const s=`${process.cwd()}/settings.${t}.json`;await a(s)||(r(`A settings file could not be found for this environment (${t}). Create a settings.${t}.json file at the root of your project and restart Joystick.`,{level:"danger",docs:"https://github.com/cheatcode/joystick#settings"}),process.exit(0));const e=await l(s,"utf-8"),o=c(e);o||(r(`Failed to parse settings file. Double-check the syntax in your settings.${t}.json file at the root of your project and restart Joystick.`,{level:"danger",docs:"https://github.com/cheatcode/joystick#settings",tools:[{title:"JSON Linter",url:"https://jsonlint.com/"}]}),process.exit(0));const i=o?e:"{}";return process.env.JOYSTICK_SETTINGS=i,JSON.parse(i)};var u=f;export{u as default}; +import n from"fs";import i from"./cli_log.js";import r from"./is_valid_json_string.js";import a from"./path_exists.js";const{readFile:c}=n.promises,l=async(t=null)=>{const s=`${process.cwd()}/settings.${t}.json`;await a(s)||(i(`A settings file could not be found for this environment (${t}). Create a settings.${t}.json file at the root of your project and restart Joystick.`,{level:"danger",docs:"https://github.com/cheatcode/joystick#settings"}),process.exit(0));const e=await c(s,"utf-8"),o=r(e);return o||(i(`Failed to parse settings file. Double-check the syntax in your settings.${t}.json file at the root of your project and restart Joystick.`,{level:"danger",docs:"https://github.com/cheatcode/joystick#settings",tools:[{title:"JSON Linter",url:"https://jsonlint.com/"}]}),process.exit(0)),JSON.parse(o?e:"{}")};var u=l;export{u as default}; //# sourceMappingURL=load_settings.js.map diff --git a/cli/dist/lib/load_settings.js.map b/cli/dist/lib/load_settings.js.map index 121a08e28..19dc844ab 100644 --- a/cli/dist/lib/load_settings.js.map +++ b/cli/dist/lib/load_settings.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/lib/load_settings.js"], - "sourcesContent": ["import fs from 'fs';\nimport cli_log from './cli_log.js';\nimport is_valid_json_string from './is_valid_json_string.js';\nimport path_exists from './path_exists.js';\n\nconst { readFile } = fs.promises;\n\nconst load_settings = async (environment = null) => {\n const settings_file_path = `${process.cwd()}/settings.${environment}.json`;\n const has_settings_file = await path_exists(settings_file_path);\n\n if (!has_settings_file) {\n cli_log(`A settings file could not be found for this environment (${environment}). Create a settings.${environment}.json file at the root of your project and restart Joystick.`, {\n level: 'danger',\n docs: 'https://github.com/cheatcode/joystick#settings',\n });\n\n process.exit(0);\n }\n\n const raw_settings_file = await readFile(settings_file_path, \"utf-8\");\n const is_valid_json = is_valid_json_string(raw_settings_file);\n\n if (!is_valid_json) {\n cli_log(`Failed to parse settings file. Double-check the syntax in your settings.${environment}.json file at the root of your project and restart Joystick.`, {\n level: 'danger',\n docs: 'https://github.com/cheatcode/joystick#settings',\n tools: [\n { title: 'JSON Linter', url: 'https://jsonlint.com/' }\n ],\n });\n process.exit(0);\n }\n\n const settings_file = is_valid_json ? raw_settings_file : \"{}\";\n\n // NOTE: Child process will inherit this env var from this parent process.\n process.env.JOYSTICK_SETTINGS = settings_file;\n\n return JSON.parse(settings_file);\n};\n\nexport default load_settings;\n"], - "mappings": "AAAA,OAAOA,MAAQ,KACf,OAAOC,MAAa,eACpB,OAAOC,MAA0B,4BACjC,OAAOC,MAAiB,mBAExB,KAAM,CAAE,SAAAC,CAAS,EAAIJ,EAAG,SAElBK,EAAgB,MAAOC,EAAc,OAAS,CAClD,MAAMC,EAAqB,GAAG,QAAQ,IAAI,CAAC,aAAaD,CAAW,QACzC,MAAMH,EAAYI,CAAkB,IAG5DN,EAAQ,4DAA4DK,CAAW,wBAAwBA,CAAW,+DAAgE,CAChL,MAAO,SACP,KAAM,gDACR,CAAC,EAED,QAAQ,KAAK,CAAC,GAGhB,MAAME,EAAoB,MAAMJ,EAASG,EAAoB,OAAO,EAC9DE,EAAgBP,EAAqBM,CAAiB,EAEvDC,IACHR,EAAQ,2EAA2EK,CAAW,+DAAgE,CAC5J,MAAO,SACP,KAAM,iDACN,MAAO,CACL,CAAE,MAAO,cAAe,IAAK,uBAAwB,CACvD,CACF,CAAC,EACD,QAAQ,KAAK,CAAC,GAGhB,MAAMI,EAAgBD,EAAgBD,EAAoB,KAG1D,eAAQ,IAAI,kBAAoBE,EAEzB,KAAK,MAAMA,CAAa,CACjC,EAEA,IAAOC,EAAQN", - "names": ["fs", "cli_log", "is_valid_json_string", "path_exists", "readFile", "load_settings", "environment", "settings_file_path", "raw_settings_file", "is_valid_json", "settings_file", "load_settings_default"] + "sourcesContent": ["import fs from 'fs';\nimport cli_log from './cli_log.js';\nimport is_valid_json_string from './is_valid_json_string.js';\nimport path_exists from './path_exists.js';\n\nconst { readFile } = fs.promises;\n\nconst load_settings = async (environment = null) => {\n const settings_file_path = `${process.cwd()}/settings.${environment}.json`;\n const has_settings_file = await path_exists(settings_file_path);\n\n if (!has_settings_file) {\n cli_log(`A settings file could not be found for this environment (${environment}). Create a settings.${environment}.json file at the root of your project and restart Joystick.`, {\n level: 'danger',\n docs: 'https://github.com/cheatcode/joystick#settings',\n });\n\n process.exit(0);\n }\n\n const raw_settings_file = await readFile(settings_file_path, \"utf-8\");\n const is_valid_json = is_valid_json_string(raw_settings_file);\n\n if (!is_valid_json) {\n cli_log(`Failed to parse settings file. Double-check the syntax in your settings.${environment}.json file at the root of your project and restart Joystick.`, {\n level: 'danger',\n docs: 'https://github.com/cheatcode/joystick#settings',\n tools: [\n { title: 'JSON Linter', url: 'https://jsonlint.com/' }\n ],\n });\n process.exit(0);\n }\n\n const settings_file = is_valid_json ? raw_settings_file : \"{}\";\n\n return JSON.parse(settings_file);\n};\n\nexport default load_settings;\n"], + "mappings": "AAAA,OAAOA,MAAQ,KACf,OAAOC,MAAa,eACpB,OAAOC,MAA0B,4BACjC,OAAOC,MAAiB,mBAExB,KAAM,CAAE,SAAAC,CAAS,EAAIJ,EAAG,SAElBK,EAAgB,MAAOC,EAAc,OAAS,CAClD,MAAMC,EAAqB,GAAG,QAAQ,IAAI,CAAC,aAAaD,CAAW,QACzC,MAAMH,EAAYI,CAAkB,IAG5DN,EAAQ,4DAA4DK,CAAW,wBAAwBA,CAAW,+DAAgE,CAChL,MAAO,SACP,KAAM,gDACR,CAAC,EAED,QAAQ,KAAK,CAAC,GAGhB,MAAME,EAAoB,MAAMJ,EAASG,EAAoB,OAAO,EAC9DE,EAAgBP,EAAqBM,CAAiB,EAE5D,OAAKC,IACHR,EAAQ,2EAA2EK,CAAW,+DAAgE,CAC5J,MAAO,SACP,KAAM,iDACN,MAAO,CACL,CAAE,MAAO,cAAe,IAAK,uBAAwB,CACvD,CACF,CAAC,EACD,QAAQ,KAAK,CAAC,GAKT,KAAK,MAFUG,EAAgBD,EAAoB,IAE3B,CACjC,EAEA,IAAOE,EAAQL", + "names": ["fs", "cli_log", "is_valid_json_string", "path_exists", "readFile", "load_settings", "environment", "settings_file_path", "raw_settings_file", "is_valid_json", "load_settings_default"] } diff --git a/cli/package-lock.json b/cli/package-lock.json index d9ed977e1..6f7b3112c 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -1,12 +1,12 @@ { "name": "@joystick.js/cli", - "version": "0.0.0-canary.2160", + "version": "1.0.0-rc.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@joystick.js/cli", - "version": "0.0.0-canary.2160", + "version": "1.0.0-rc.1", "license": "SAUCR", "dependencies": { "@babel/code-frame": "^7.23.5", @@ -17,7 +17,7 @@ "chokidar": "^3.5.3", "esbuild": "^0.25.2", "esbuild-plugin-svg": "^0.1.0", - "form-data": "^4.0.2", + "form-data": "^4.0.4", "inquirer": "^9.2.12", "mongodb": "^6.16.0", "node-fetch": "^3.3.2", @@ -2227,14 +2227,14 @@ } }, "node_modules/form-data": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", - "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", - "license": "MIT", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -5735,13 +5735,14 @@ } }, "form-data": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", - "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, diff --git a/cli/package.json b/cli/package.json index c8d1dbfe4..865ad7568 100644 --- a/cli/package.json +++ b/cli/package.json @@ -2,7 +2,7 @@ "name": "@joystick.js/cli", "type": "module", "version": "1.0.0-rc.1", - "canary_version": "0.0.0-canary.2160", + "canary_version": "0.0.0-canary.2168", "description": "The CLI for Joystick.", "main": "dist/index.js", "bin": { @@ -25,7 +25,7 @@ "chokidar": "^3.5.3", "esbuild": "^0.25.2", "esbuild-plugin-svg": "^0.1.0", - "form-data": "^4.0.2", + "form-data": "^4.0.4", "inquirer": "^9.2.12", "mongodb": "^6.16.0", "node-fetch": "^3.3.2", diff --git a/cli/src/lib/development_server/index.js b/cli/src/lib/development_server/index.js index fc0080802..6b0a522d9 100644 --- a/cli/src/lib/development_server/index.js +++ b/cli/src/lib/development_server/index.js @@ -190,7 +190,17 @@ const handle_restart_app_server = async (node_major_version = 0, watch = false, ]); await kill_port_process(process.env.PORT); - handle_start_app_server(node_major_version, watch, imports, run_integrated_tests); + const current_settings = await load_settings(process.env.NODE_ENV); + process.app_server_process = start_app_server(node_major_version, watch, imports, { + NODE_ENV: process.env.NODE_ENV, + PORT: process.env.PORT, + LOGS_PATH: process.env.LOGS_PATH, + ROOT_URL: process.env.ROOT_URL, + JOYSTICK_SETTINGS: JSON.stringify(current_settings), + }); + process_ids.push(process.app_server_process?.pid); + handle_app_server_process_stdio(watch, run_integrated_tests, false); + process.app_server_restarting = false; } }, 300); }; @@ -267,8 +277,14 @@ const handle_app_server_process_stdio = (watch = false, run_integrated_tests = f }); }; -const handle_start_app_server = (node_major_version = 0, watch = false, imports = [], run_integrated_tests = false, is_test_server = false) => { - process.app_server_process = start_app_server(node_major_version, watch, imports); +const handle_start_app_server = (node_major_version = 0, watch = false, imports = [], run_integrated_tests = false, is_test_server = false, settings = {}) => { + process.app_server_process = start_app_server(node_major_version, watch, imports, { + NODE_ENV: process.env.NODE_ENV, + PORT: process.env.PORT, + LOGS_PATH: process.env.LOGS_PATH, + ROOT_URL: process.env.ROOT_URL, + JOYSTICK_SETTINGS: JSON.stringify(settings), + }); process_ids.push(process.app_server_process?.pid); handle_app_server_process_stdio(watch, run_integrated_tests, is_test_server); process.app_server_restarting = false; @@ -431,6 +447,16 @@ const development_server = async (development_server_options = {}) => { settings }); + // NOTE: Start the main app server first + handle_start_app_server( + node_major_version, + development_server_options?.watch, + development_server_options?.imports || [], + development_server_options?.tests, // Pass tests flag for integrated test running + false, // This is not a test server + settings, // Pass the loaded settings + ); + // NOTE: If tests flag is enabled, start a separate test server on port 1977. if (development_server_options?.tests && development_server_options?.environment !== 'test') { const test_port_occupied = await check_if_port_occupied(1977); @@ -441,8 +467,10 @@ const development_server = async (development_server_options = {}) => { // NOTE: Start test server directly without recursive development_server call setTimeout(async () => { try { - // NOTE: Start test databases - const test_settings = await load_settings('test'); + // NOTE: Load test settings without contaminating global process.env.JOYSTICK_SETTINGS + const test_settings_file_path = `${process.cwd()}/settings.test.json`; + const test_settings_raw = await fs.promises.readFile(test_settings_file_path, 'utf-8'); + const test_settings = JSON.parse(test_settings_raw); await start_databases({ environment: 'test', @@ -455,7 +483,7 @@ const development_server = async (development_server_options = {}) => { PORT: 1977, LOGS_PATH: process.env.LOGS_PATH, ROOT_URL: process.env.ROOT_URL, - JOYSTICK_SETTINGS: process.env.JOYSTICK_SETTINGS, + JOYSTICK_SETTINGS: JSON.stringify(test_settings), }); process_ids.push(test_app_server?.pid); @@ -505,13 +533,13 @@ const development_server = async (development_server_options = {}) => { development_server_options?.imports, development_server_options?.tests, ), - start_app_server: () => handle_start_app_server( - node_major_version, - development_server_options?.watch, - development_server_options?.imports, - development_server_options?.tests, - development_server_options?._is_test_server, - ), + start_app_server: () => start_app_server(node_major_version, development_server_options?.watch, development_server_options?.imports || [], { + NODE_ENV: process.env.NODE_ENV, + PORT: process.env.PORT, + LOGS_PATH: process.env.LOGS_PATH, + ROOT_URL: process.env.ROOT_URL, + JOYSTICK_SETTINGS: JSON.stringify(settings), + }), start_hmr_server: development_server_options?.environment !== 'test' ? () => handle_start_hmr_server( node_major_version, __dirname, @@ -538,15 +566,6 @@ const development_server = async (development_server_options = {}) => { return { path }; }) || [], }); - } else { - // NOTE: For test server, just start the app server without file watching - handle_start_app_server( - node_major_version, - false, // No file watching for test server - development_server_options?.imports || [], - false, // No integrated tests for test server - true, // This is a test server - ); } handle_signal_events(process_ids, node_major_version, __dirname); diff --git a/cli/src/lib/load_settings.js b/cli/src/lib/load_settings.js index af5bb8cb3..0b53c4171 100644 --- a/cli/src/lib/load_settings.js +++ b/cli/src/lib/load_settings.js @@ -34,9 +34,6 @@ const load_settings = async (environment = null) => { const settings_file = is_valid_json ? raw_settings_file : "{}"; - // NOTE: Child process will inherit this env var from this parent process. - process.env.JOYSTICK_SETTINGS = settings_file; - return JSON.parse(settings_file); }; diff --git a/node/dist/app/index.js b/node/dist/app/index.js index 0654e128b..955fa5262 100644 --- a/node/dist/app/index.js +++ b/node/dist/app/index.js @@ -1 +1 @@ -import j from"http";import x from"fs";import k from"./api/accounts/authenticated.js";import v from"./api/accounts/login.js";import $ from"./api/accounts/logout.js";import O from"./api/accounts/recover_password.js";import q from"./api/accounts/reset_password.js";import E from"./api/accounts/signup.js";import F from"./api/accounts/user.js";import N from"./api/accounts/verify_email.js";import R from"./api/test/accounts/delete.js";import S from"./api/test/accounts/signup.js";import D from"./api/test/bootstrap.js";import I from"./api/test/process.js";import A from"./api/test/queues.js";import T from"./databases/mongodb/create_indexes.js";import P from"./databases/postgresql/create_indexes.js";import W from"./databases/postgresql/create_tables.js";import d from"../lib/dynamic_import.js";import U from"./generate_machine_id.js";import C from"./generate_process_id.js";import J from"../lib/get_browser_safe_request.js";import u from"../lib/get_joystick_build_path.js";import g from"./databases/get_target_database_connection.js";import L from"./handle_process_errors.js";import B from"./settings/load.js";import H from"../lib/parse_route_pattern.js";import p from"../lib/path_exists.js";import V from"./push/index.js";import Y from"./push/logger.js";import z from"./queues/index.js";import f from"../lib/read_mod_component_css.js";import y from"../lib/read_mod_global_css.js";import K from"./register_app_options.js";import Q from"./cron_jobs/register.js";import G from"./databases/register_database.js";import M from"./api/register_getters.js";import X from"./routes/register_route_from_function.js";import Z from"./routes/register_route_from_object.js";import tt from"./api/register_setters.js";import st from"./uploaders/register.js";import et from"./websockets/register.js";import ot from"./ssr/index.js";import it from"./start_express.js";import at from"./start_node_as_cluster.js";import rt from"../lib/strip_preceeding_slash.js";import m from"../lib/types.js";import nt from"../lib/websocket_client.js";const{readFile:_,readdir:h}=x.promises,pt=B();class ct{constructor(t={}){j.globalAgent.maxSockets=1/0,L(t?.events),K(this,t),this.generate_machine_id(),this.generate_process_id(),process.title=process.env.NODE_ENV==="test"?"joystick_test_app":"joystick_app",process.joystick={app_options:t,external_process_ids:[],track_external_process:(s="")=>{process.send({external_process_id:s}),process.joystick.external_process_ids.push(s)}}}async connect_databases(){const t=pt?.config?.databases;for(let s=0;so?.provider===i?.provider)?.length>1;await G(o,e,r)}if(t?.length>0){const s=g("queues"),o=g("users");process.databases._queues=s?.connection,process.databases._users=o?.connection;const e=[s,o],r=e?.filter(a=>a?.provider==="mongodb")?.map(a=>a?.database_type);await T(r);const i=e?.filter(a=>a?.provider==="postgresql")?.map(a=>a?.database_type);await W(i),await P(i)}}async generate_machine_id(){this.joystick_machine_id=await U()}async generate_process_id(){this.joystick_process_id=await C()}async load_translations(){const t=u();if(!await p(t))return;process._joystick_translations={normal:{files:[],path:`${t}i18n`,cache:{}},email:{files:[],path:`${t}i18n/email`,cache:{}}};const s=async o=>{const e=process._joystick_translations[o];if(await p(e.path))try{const r=await h(e.path);e.files=r.filter(i=>i.endsWith(".js"));for(const i of e.files){const a=`${e.path}/${i}`;try{const n=await d(a);e.cache[i]=n}catch(n){console.warn(`Failed to load translation file: ${a}`,n.message)}}}catch(r){console.warn(`Failed to scan translation directory: ${e.path}`,r.message)}};await s("normal"),await s("email")}async load_email_templates(){const s=`${u()}email`;if(await p(s)){process._joystick_email_templates={},process._joystick_email_base_files={};try{const o=await h(s),e=o.filter(i=>i.endsWith(".js"));for(const i of e){const a=`${s}/${i}`,n=i.replace(".js","");try{const c=await d(a);process._joystick_email_templates[n]=c}catch(c){console.warn(`Failed to load email template: ${a}`,c.message)}}const r=o.filter(i=>i.startsWith("base")&&(i.endsWith(".html")||i.endsWith(".css")));for(const i of r){const a=`${s}/${i}`;try{const n=await _(a,"utf-8");process._joystick_email_base_files[i]=n}catch(n){console.warn(`Failed to load email base file: ${a}`,n.message)}}}catch(o){console.warn(`Failed to scan email templates directory: ${s}`,o.message)}}}async load_ui(){const t=u();if(!await p(t))return;process._joystick_html=await _("index.html","utf-8"),process._joystick_components={};const s=async e=>{try{const r=await h(e,{withFileTypes:!0});for(const i of r)if(i.isDirectory()){const n=`${`${e}/${i.name}`}/index.js`;if(await p(n))try{const c=await d(n),b=n.replace(`${t}`,"");process._joystick_components[b]=c}catch(c){console.warn(`Failed to load component: ${n}`,c.message)}}}catch(r){console.warn(`Failed to scan directory: ${e}`,r.message)}},o=[`${t}ui/components`,`${t}ui/layouts`,`${t}ui/pages`];for(const e of o)await p(e)&&await s(e)}on_after_start_server(t={}){process.on("message",s=>{if(typeof s=="string"){const o=JSON.parse(s);["RESTART"].includes(o?.type),o?.type==="BUILD_ERROR"&&(process.BUILD_ERROR=JSON.parse(s))}}),console.log(`App running at: http://localhost:${t.port}`)}register_accounts(){this.express.app.get("/api/_accounts/authenticated",k),this.express.app.post("/api/_accounts/user",F),this.express.app.post("/api/_accounts/login",v),this.express.app.post("/api/_accounts/logout",$),this.express.app.post("/api/_accounts/recover-password",O),this.express.app.post("/api/_accounts/reset-password",q),this.express.app.post("/api/_accounts/signup",E),this.express.app.get("/api/_accounts/verify-email",N)}register_api(){const t=this?.options?.api?.getters,s=this?.options?.api?.setters,o=this?.options?.api?.options,e=this?.options?.api?.context;t&&m.is_object(t)&&Object.keys(t||{}).length>0&&M(this.express.app,Object.entries(t||{}),e,o),s&&m.is_object(s)&&Object.keys(s||{}).length>0&&tt(this.express.app,Object.entries(s||{}),e,o)}register_caches(){process.caches={},m.is_function(this.options.caches)&&this.options.caches()}register_cron_jobs(){Q(this.options.cronJobs||this.options.cron_jobs)}register_dynamic_pages(){this.express.app.post("/_joystick/dynamic_page/data",async(t={},s={})=>{const o=u(),e=rt(t?.body?.page),r=`${o}/${e}`;if(!t?.body?.page||!await p(r))return handle_api_error("joystick.dynamic_pages.load",new Error(`Component not found at ${r}.`),s);const i=await d(r);if(i){const a=H(t?.body?.route_pattern||"",t?.body?.path),n=J({params:a?.params||{},query:t?.body?.query_params||{},url:t?.body?.path,headers:t?.headers,context:t?.context}),c=await ot({is_dynamic_page_render:!0,component_to_render:i,api_schema:this?.options?.api,component_options:{props:t?.body?.props},req:n});return s.status(200).send({data:c,req:n,url:{params:a?.params||{},query:t?.body?.query_params||{},path:t?.body?.path,route:t?.body?.route_pattern||t?.body?.path}})}return s.status(200).send({})})}register_fixtures(){m.is_function(this.options.fixtures)&&this.options.fixtures()}register_indexes(){m.is_function(this.options.indexes)&&this.options.indexes()}async register_mod(){if(!await p("private/mod"))return;const s=await p("private/mod/mod_version.txt")&&(await _("private/mod/mod_version.txt","utf-8"))?.trim()||"free";let o,e,r,i={},a={};if(s==="plus"){o=await p("private/mod/mod-light-plus.min.css")&&await _("private/mod/mod-light-plus.min.css","utf-8")||"",e=await p("private/mod/mod-dark-plus.min.css")&&await _("private/mod/mod-dark-plus.min.css","utf-8")||"",r={esm:await p("lib/mod-plus.esm.min.js")&&await _("lib/mod-plus.esm.min.js","utf-8")||"",iife:await p("lib/mod-plus.iife.min.js")&&await _("lib/mod-plus.iife.min.js","utf-8")||""},i=await y();const n=await f("free"),c=await f("plus");a={...n||{},...c||{}}}else o=await p("private/mod/mod-light.min.css")&&await _("private/mod/mod-light.min.css","utf-8")||"",e=await p("private/mod/mod-dark.min.css")&&await _("private/mod/mod-dark.min.css","utf-8")||"",r={esm:await p("lib/mod.esm.min.js")&&await _("lib/mod.esm.min.js","utf-8")||"",iife:await p("lib/mod.iife.min.js")&&await _("lib/mod.iife.min.js","utf-8")||""},i=await y(),a={...await f("free")||{}};this.mod={version:s,css:{light:o,dark:e},js:r,globals:i,components:a}}async register_push(){process.env.NODE_ENV!=="development"&&process.env.IS_PUSH_DEPLOYED&&(this.express.app.get("/api/_push/health",async(t={},s={})=>t?.headers?.["x-push-instance-token"]!==process.env.PUSH_INSTANCE_TOKEN?s.status(403).send("403 - You are not allowed to access this endpoint."):s.status(200).send("ok")),process.push_instances_websocket=nt({url:"wss://push.cheatcode.co/api/_websockets/instances",options:{max_sends_per_second:10,logging:!1,auto_reconnect:!0,reconnect_attempts:1/0,reconnect_delay_in_seconds:10}}),await V(),await Y(),console.log("App running at http://localhost:2600"))}register_queues(){if(m.is_object(this.options.queues)){const t=Object.entries(this.options.queues||{});for(let s=0;sD(t,s,this)),this.express.app.get("/api/_test/process",I),this.express.app.delete("/api/_test/accounts",R),this.express.app.post("/api/_test/accounts/signup",S),this.express.app.post("/api/_test/queues",(t={},s={})=>A(t,s,this))}register_uploaders(){st(this.options.uploaders,this)}register_websockets(){et(this.options.websockets,this)}async start(){await this.load_translations(),await this.load_email_templates(),await this.load_ui(),await this.connect_databases(),await this.register_mod(),this.register_caches(),this.register_cron_jobs(),this.register_queues(),this.start_express(),this.register_websockets(),this.register_tests(),this.register_push(),this.register_accounts(),this.register_api(),this.register_routes(),this.register_dynamic_pages(),this.register_uploaders(),this.register_fixtures(),this.register_indexes()}start_express(){this.express=it(this.on_after_start_server,this)}}const w=async(l={})=>{const t=new ct(l);return await t.start(l),t},_t=(l={})=>new Promise(async t=>{if(l?.cluster)at(async()=>{const s=await w(l);return t(s.express)});else{const s=await w(l);return t(s.express)}});var as=_t;export{as as default}; +import j from"http";import x from"fs";import k from"./api/accounts/authenticated.js";import v from"./api/accounts/login.js";import $ from"./api/accounts/logout.js";import O from"./api/accounts/recover_password.js";import q from"./api/accounts/reset_password.js";import E from"./api/accounts/signup.js";import N from"./api/accounts/user.js";import R from"./api/accounts/verify_email.js";import F from"./api/test/accounts/delete.js";import D from"./api/test/accounts/signup.js";import S from"./api/test/bootstrap.js";import I from"./api/test/process.js";import T from"./api/test/queues.js";import A from"./databases/mongodb/create_indexes.js";import P from"./databases/postgresql/create_indexes.js";import W from"./databases/postgresql/create_tables.js";import d from"../lib/dynamic_import.js";import U from"./generate_machine_id.js";import C from"./generate_process_id.js";import J from"../lib/get_browser_safe_request.js";import u from"../lib/get_joystick_build_path.js";import g from"./databases/get_target_database_connection.js";import L from"./handle_process_errors.js";import V from"./settings/load.js";import B from"../lib/parse_route_pattern.js";import p from"../lib/path_exists.js";import H from"./push/index.js";import Y from"./push/logger.js";import z from"./queues/index.js";import f from"../lib/read_mod_component_css.js";import y from"../lib/read_mod_global_css.js";import K from"./register_app_options.js";import Q from"./cron_jobs/register.js";import G from"./databases/register_database.js";import M from"./api/register_getters.js";import X from"./routes/register_route_from_function.js";import Z from"./routes/register_route_from_object.js";import tt from"./api/register_setters.js";import st from"./uploaders/register.js";import et from"./websockets/register.js";import ot from"./ssr/index.js";import it from"./start_express.js";import at from"./start_node_as_cluster.js";import rt from"../lib/strip_preceeding_slash.js";import m from"../lib/types.js";import nt from"../lib/websocket_client.js";const{readFile:_,readdir:h}=x.promises,pt=V();class ct{constructor(t={}){j.globalAgent.maxSockets=1/0,L(t?.events),K(this,t),this.generate_machine_id(),this.generate_process_id(),process.title=process.env.NODE_ENV==="test"?"joystick_test_app":"joystick_app",process.joystick={app_options:t,external_process_ids:[],track_external_process:(s="")=>{process.send({external_process_id:s}),process.joystick.external_process_ids.push(s)}}}async connect_databases(){const t=pt?.config?.databases;console.log({databases_from_settings:t,env:process.env.NODE_ENV,port:process.env.PORT});for(let s=0;so?.provider===i?.provider)?.length>1;await G(o,e,r)}if(t?.length>0){const s=g("queues"),o=g("users");process.databases._queues=s?.connection,process.databases._users=o?.connection;const e=[s,o],r=e?.filter(a=>a?.provider==="mongodb")?.map(a=>a?.database_type);await A(r);const i=e?.filter(a=>a?.provider==="postgresql")?.map(a=>a?.database_type);await W(i),await P(i)}}async generate_machine_id(){this.joystick_machine_id=await U()}async generate_process_id(){this.joystick_process_id=await C()}async load_translations(){const t=u();if(!await p(t))return;process._joystick_translations={normal:{files:[],path:`${t}i18n`,cache:{}},email:{files:[],path:`${t}i18n/email`,cache:{}}};const s=async o=>{const e=process._joystick_translations[o];if(await p(e.path))try{const r=await h(e.path);e.files=r.filter(i=>i.endsWith(".js"));for(const i of e.files){const a=`${e.path}/${i}`;try{const n=await d(a);e.cache[i]=n}catch(n){console.warn(`Failed to load translation file: ${a}`,n.message)}}}catch(r){console.warn(`Failed to scan translation directory: ${e.path}`,r.message)}};await s("normal"),await s("email")}async load_email_templates(){const s=`${u()}email`;if(await p(s)){process._joystick_email_templates={},process._joystick_email_base_files={};try{const o=await h(s),e=o.filter(i=>i.endsWith(".js"));for(const i of e){const a=`${s}/${i}`,n=i.replace(".js","");try{const c=await d(a);process._joystick_email_templates[n]=c}catch(c){console.warn(`Failed to load email template: ${a}`,c.message)}}const r=o.filter(i=>i.startsWith("base")&&(i.endsWith(".html")||i.endsWith(".css")));for(const i of r){const a=`${s}/${i}`;try{const n=await _(a,"utf-8");process._joystick_email_base_files[i]=n}catch(n){console.warn(`Failed to load email base file: ${a}`,n.message)}}}catch(o){console.warn(`Failed to scan email templates directory: ${s}`,o.message)}}}async load_ui(){const t=u();if(!await p(t))return;process._joystick_html=await _("index.html","utf-8"),process._joystick_components={};const s=async e=>{try{const r=await h(e,{withFileTypes:!0});for(const i of r)if(i.isDirectory()){const n=`${`${e}/${i.name}`}/index.js`;if(await p(n))try{const c=await d(n),b=n.replace(`${t}`,"");process._joystick_components[b]=c}catch(c){console.warn(`Failed to load component: ${n}`,c.message)}}}catch(r){console.warn(`Failed to scan directory: ${e}`,r.message)}},o=[`${t}ui/components`,`${t}ui/layouts`,`${t}ui/pages`];for(const e of o)await p(e)&&await s(e)}on_after_start_server(t={}){process.on("message",s=>{if(typeof s=="string"){const o=JSON.parse(s);["RESTART"].includes(o?.type),o?.type==="BUILD_ERROR"&&(process.BUILD_ERROR=JSON.parse(s))}}),console.log(`App running at: http://localhost:${t.port}`)}register_accounts(){this.express.app.get("/api/_accounts/authenticated",k),this.express.app.post("/api/_accounts/user",N),this.express.app.post("/api/_accounts/login",v),this.express.app.post("/api/_accounts/logout",$),this.express.app.post("/api/_accounts/recover-password",O),this.express.app.post("/api/_accounts/reset-password",q),this.express.app.post("/api/_accounts/signup",E),this.express.app.get("/api/_accounts/verify-email",R)}register_api(){const t=this?.options?.api?.getters,s=this?.options?.api?.setters,o=this?.options?.api?.options,e=this?.options?.api?.context;t&&m.is_object(t)&&Object.keys(t||{}).length>0&&M(this.express.app,Object.entries(t||{}),e,o),s&&m.is_object(s)&&Object.keys(s||{}).length>0&&tt(this.express.app,Object.entries(s||{}),e,o)}register_caches(){process.caches={},m.is_function(this.options.caches)&&this.options.caches()}register_cron_jobs(){Q(this.options.cronJobs||this.options.cron_jobs)}register_dynamic_pages(){this.express.app.post("/_joystick/dynamic_page/data",async(t={},s={})=>{const o=u(),e=rt(t?.body?.page),r=`${o}/${e}`;if(!t?.body?.page||!await p(r))return handle_api_error("joystick.dynamic_pages.load",new Error(`Component not found at ${r}.`),s);const i=await d(r);if(i){const a=B(t?.body?.route_pattern||"",t?.body?.path),n=J({params:a?.params||{},query:t?.body?.query_params||{},url:t?.body?.path,headers:t?.headers,context:t?.context}),c=await ot({is_dynamic_page_render:!0,component_to_render:i,api_schema:this?.options?.api,component_options:{props:t?.body?.props},req:n});return s.status(200).send({data:c,req:n,url:{params:a?.params||{},query:t?.body?.query_params||{},path:t?.body?.path,route:t?.body?.route_pattern||t?.body?.path}})}return s.status(200).send({})})}register_fixtures(){m.is_function(this.options.fixtures)&&this.options.fixtures()}register_indexes(){m.is_function(this.options.indexes)&&this.options.indexes()}async register_mod(){if(!await p("private/mod"))return;const s=await p("private/mod/mod_version.txt")&&(await _("private/mod/mod_version.txt","utf-8"))?.trim()||"free";let o,e,r,i={},a={};if(s==="plus"){o=await p("private/mod/mod-light-plus.min.css")&&await _("private/mod/mod-light-plus.min.css","utf-8")||"",e=await p("private/mod/mod-dark-plus.min.css")&&await _("private/mod/mod-dark-plus.min.css","utf-8")||"",r={esm:await p("lib/mod-plus.esm.min.js")&&await _("lib/mod-plus.esm.min.js","utf-8")||"",iife:await p("lib/mod-plus.iife.min.js")&&await _("lib/mod-plus.iife.min.js","utf-8")||""},i=await y();const n=await f("free"),c=await f("plus");a={...n||{},...c||{}}}else o=await p("private/mod/mod-light.min.css")&&await _("private/mod/mod-light.min.css","utf-8")||"",e=await p("private/mod/mod-dark.min.css")&&await _("private/mod/mod-dark.min.css","utf-8")||"",r={esm:await p("lib/mod.esm.min.js")&&await _("lib/mod.esm.min.js","utf-8")||"",iife:await p("lib/mod.iife.min.js")&&await _("lib/mod.iife.min.js","utf-8")||""},i=await y(),a={...await f("free")||{}};this.mod={version:s,css:{light:o,dark:e},js:r,globals:i,components:a}}async register_push(){process.env.NODE_ENV!=="development"&&process.env.IS_PUSH_DEPLOYED&&(this.express.app.get("/api/_push/health",async(t={},s={})=>t?.headers?.["x-push-instance-token"]!==process.env.PUSH_INSTANCE_TOKEN?s.status(403).send("403 - You are not allowed to access this endpoint."):s.status(200).send("ok")),process.push_instances_websocket=nt({url:"wss://push.cheatcode.co/api/_websockets/instances",options:{max_sends_per_second:10,logging:!1,auto_reconnect:!0,reconnect_attempts:1/0,reconnect_delay_in_seconds:10}}),await H(),await Y(),console.log("App running at http://localhost:2600"))}register_queues(){if(m.is_object(this.options.queues)){const t=Object.entries(this.options.queues||{});for(let s=0;sS(t,s,this)),this.express.app.get("/api/_test/process",I),this.express.app.delete("/api/_test/accounts",F),this.express.app.post("/api/_test/accounts/signup",D),this.express.app.post("/api/_test/queues",(t={},s={})=>T(t,s,this))}register_uploaders(){st(this.options.uploaders,this)}register_websockets(){et(this.options.websockets,this)}async start(){await this.load_translations(),await this.load_email_templates(),await this.load_ui(),await this.connect_databases(),await this.register_mod(),this.register_caches(),this.register_cron_jobs(),this.register_queues(),this.start_express(),this.register_websockets(),this.register_tests(),this.register_push(),this.register_accounts(),this.register_api(),this.register_routes(),this.register_dynamic_pages(),this.register_uploaders(),this.register_fixtures(),this.register_indexes()}start_express(){this.express=it(this.on_after_start_server,this)}}const w=async(l={})=>{const t=new ct(l);return await t.start(l),t},_t=(l={})=>new Promise(async t=>{if(l?.cluster)at(async()=>{const s=await w(l);return t(s.express)});else{const s=await w(l);return t(s.express)}});var as=_t;export{as as default}; diff --git a/node/package-lock.json b/node/package-lock.json index fd1905ebe..3715e8a7d 100644 --- a/node/package-lock.json +++ b/node/package-lock.json @@ -1,12 +1,12 @@ { "name": "@joystick.js/node", - "version": "0.0.0-canary.2160", + "version": "0.0.0-canary.2168", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@joystick.js/node", - "version": "0.0.0-canary.2160", + "version": "0.0.0-canary.2168", "license": "SAUCR", "dependencies": { "@aws-sdk/client-s3": "^3.478.0", diff --git a/node/package.json b/node/package.json index 707951530..9225dd608 100644 --- a/node/package.json +++ b/node/package.json @@ -2,7 +2,7 @@ "name": "@joystick.js/node", "type": "module", "version": "1.0.0-rc.1", - "canary_version": "0.0.0-canary.2160", + "canary_version": "0.0.0-canary.2168", "description": "The Node.js framework for Joystick.", "main": "./dist/index.js", "scripts": { diff --git a/node/src/app/index.js b/node/src/app/index.js index d8d5d5b2e..564886d97 100644 --- a/node/src/app/index.js +++ b/node/src/app/index.js @@ -78,6 +78,12 @@ class App { async connect_databases() { const databases_from_settings = app_settings?.config?.databases; + console.log({ + databases_from_settings, + env: process.env.NODE_ENV, + port: process.env.PORT, + }); + for (let i = 0; i < databases_from_settings?.length; i += 1) { const database_from_settings = databases_from_settings[i]; const database_port = parseInt(process.env.PORT, 10) + 10 + i; diff --git a/test/package-lock.json b/test/package-lock.json index 5f4638758..641882151 100644 --- a/test/package-lock.json +++ b/test/package-lock.json @@ -1,12 +1,12 @@ { "name": "@joystick.js/test", - "version": "0.0.0-canary.2160", + "version": "0.0.0-canary.2168", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@joystick.js/test", - "version": "0.0.0-canary.2160", + "version": "0.0.0-canary.2168", "license": "ISC", "dependencies": { "ava": "^6.2.0", diff --git a/test/package.json b/test/package.json index 44d843db0..b89cc1eef 100644 --- a/test/package.json +++ b/test/package.json @@ -2,7 +2,7 @@ "name": "@joystick.js/test", "type": "module", "version": "1.0.0-rc.1", - "canary_version": "0.0.0-canary.2160", + "canary_version": "0.0.0-canary.2168", "description": "The testing framework for Joystick.", "main": "./dist/index.js", "scripts": { diff --git a/ui/package-lock.json b/ui/package-lock.json index f404d90da..fe15799f1 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "@joystick.js/ui", - "version": "0.0.0-canary.2160", + "version": "0.0.0-canary.2168", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@joystick.js/ui", - "version": "0.0.0-canary.2160", + "version": "0.0.0-canary.2168", "license": "SAUCR", "dependencies": { "js-cookie": "^3.0.5", diff --git a/ui/package.json b/ui/package.json index 271e6cf4f..dd5ca856d 100644 --- a/ui/package.json +++ b/ui/package.json @@ -2,7 +2,7 @@ "name": "@joystick.js/ui", "type": "module", "version": "1.0.0-rc.1", - "canary_version": "0.0.0-canary.2160", + "canary_version": "0.0.0-canary.2168", "description": "The UI framework for Joystick.", "main": "./dist/index.js", "scripts": {