@joystick.js/cli-canary 0.0.0-canary.2139 → 0.0.0-canary.2140
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/development_server/index.js +1 -1
- package/dist/lib/development_server/index.js.map +1 -1
- package/dist/lib/development_server/run_tests.js +2 -2
- package/dist/lib/development_server/run_tests.js.map +3 -3
- package/package.json +2 -2
- package/src/lib/development_server/index.js +1 -1
- package/src/lib/development_server/run_tests.js +43 -9
|
@@ -8,5 +8,5 @@ ${a&&r?.length>0?`
|
|
|
8
8
|
`:""}`)}`}}if(r?.length>0){c+=` ${_.yellow(">")} Required Directories:
|
|
9
9
|
|
|
10
10
|
`;for(let e=0;e<r?.length;e+=1){const o=r[e];c+=` ${_.red(`/${o.path}
|
|
11
|
-
`)}`}}i(c,{level:"danger",docs:"https://cheatcode.co/docs/joystick/structure"}),process.exit(0)}},ts=async()=>{const s=await l(`${process.cwd()}/.joystick`),t=await l(`${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))},x=async(s={})=>{await ts(),await es(),await ss();const t=Z(s?.port),r=await f(t),c=await f(t+1);r&&Y(t),c&&m(t),W(s,t);const e=await g(process.env.NODE_ENV);await Q(e),await R({environment:process.env.NODE_ENV,port:t,settings:e}),s?.tests&&s?.environment!=="test"&&(await f(1977)&&await m(1977),setTimeout(async()=>{try{await x({environment:"test",port:1977,watch:!1,imports:s?.imports||[],_is_test_server:!0})}catch(a){console.error("Error starting test server:",a)}},100)),s?._is_test_server?u(n,!1,s?.imports||[],!1,!0):H({hot_module_reload:(o=[])=>U(o),restart_app_server:()=>O(n,s?.watch,e,s?.imports,s?.tests),start_app_server:()=>u(n,s?.watch,s?.imports,s?.tests,s?._is_test_server),start_hmr_server:s?.environment!=="test"?()=>z(n,p,s?.watch,e,s?.imports,s?.tests):null,run_tests:s?.tests?async()=>{setTimeout(async()=>{try{await v({__dirname:p})}catch(o){console.error("Error running tests after file change:",o)}},
|
|
11
|
+
`)}`}}i(c,{level:"danger",docs:"https://cheatcode.co/docs/joystick/structure"}),process.exit(0)}},ts=async()=>{const s=await l(`${process.cwd()}/.joystick`),t=await l(`${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))},x=async(s={})=>{await ts(),await es(),await ss();const t=Z(s?.port),r=await f(t),c=await f(t+1);r&&Y(t),c&&m(t),W(s,t);const e=await g(process.env.NODE_ENV);await Q(e),await R({environment:process.env.NODE_ENV,port:t,settings:e}),s?.tests&&s?.environment!=="test"&&(await f(1977)&&await m(1977),setTimeout(async()=>{try{await x({environment:"test",port:1977,watch:!1,imports:s?.imports||[],_is_test_server:!0})}catch(a){console.error("Error starting test server:",a)}},100)),s?._is_test_server?u(n,!1,s?.imports||[],!1,!0):H({hot_module_reload:(o=[])=>U(o),restart_app_server:()=>O(n,s?.watch,e,s?.imports,s?.tests),start_app_server:()=>u(n,s?.watch,s?.imports,s?.tests,s?._is_test_server),start_hmr_server:s?.environment!=="test"?()=>z(n,p,s?.watch,e,s?.imports,s?.tests):null,run_tests:s?.tests?async()=>{setTimeout(async()=>{try{await v({__dirname:p})}catch(o){console.error("Error running tests after file change:",o)}},2e3)}:null},{excluded_paths:e?.config?.build?.excluded_paths,custom_copy_paths:e?.config?.build?.copy_paths?.map(o=>({path:o}))||[]}),J(h,n,p)};var Ds=x;export{Ds as default};
|
|
12
12
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/development_server/index.js"],
|
|
4
|
-
"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 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 in parallel using the same development_server function\n // but with different options to avoid recursion and environment conflicts\n setTimeout(async () => {\n try {\n await development_server({\n environment: 'test',\n port: 1977,\n watch: false, // No file watching for test server\n imports: development_server_options?.imports || [],\n _is_test_server: true, // Internal flag to prevent infinite recursion\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 }, 1000);\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"],
|
|
4
|
+
"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 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 in parallel using the same development_server function\n // but with different options to avoid recursion and environment conflicts\n setTimeout(async () => {\n try {\n await development_server({\n environment: 'test',\n port: 1977,\n watch: false, // No file watching for test server\n imports: development_server_options?.imports || [],\n _is_test_server: true, // Internal flag to prevent infinite recursion\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"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"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", "index_default"]
|
|
7
7
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
`)}console.log(e)},_=(e={},
|
|
1
|
+
import i from"child_process";import l from"../cli_log.js";import"chalk";const g=(e="")=>{if(e?.includes("Using configuration"))return null;if(e?.includes("No tests found"))return l("No tests found. Add tests in the /tests folder at the root of your Joystick app.",{level:"danger",docs:"https://cheatcode.co/docs/joystick/test/setup"});console.log(e)},f=(e="")=>{if(e?.includes("Using configuration"))return null;if(e?.includes("No tests found in")){const[o]=e?.split(",");return console.log(`${o}
|
|
2
|
+
`)}console.log(e)},_=(e={},o={})=>{e.stdout.on("data",function(n){const r=n.toString();f(r,o)}),e.stderr.on("data",function(n){const r=n.toString();g(r,o)})},u=(e={})=>{const o=`${process.cwd()}/node_modules/.bin/ava`,n=`${e?.__dirname}/tap_reporter.js`;return new Promise((r,d)=>{const a=i.spawn(o,["--config",`${e?.__dirname}/ava_config.js`,"--tap"],{env:{...process.env,databases:process.databases,FORCE_COLOR:"1"}}),t=i.spawn("node",[n],{env:{...process.env,FORCE_COLOR:"1"}});a.stdout.pipe(t.stdin),t.stdout.on("data",s=>{process.stdout.write(s)}),t.stderr.on("data",s=>{process.stderr.write(s)}),a.stderr.on("data",s=>{s.toString().includes("Using configuration")||process.stderr.write(s)}),a.on("exit",(s,c)=>{t.stdin.end()}),t.on("exit",(s,c)=>{r()}),a.on("error",s=>{console.error("Test runner error:",s.message),r()}),t.on("error",s=>{console.error("TAP reporter error:",s.message),r()})})},m=(e={})=>{const o=`${process.cwd()}/node_modules/.bin/ava`,n=`${e?.__dirname}/tap_reporter.js`;return new Promise(r=>{const d=`DEBUG=ava:watcher && ${o} --config ${e?.__dirname}/ava_config.js`,a=e?.watch?"--watch":"",t=e?.watch?"":`--tap | node ${n}`,s=`${d} ${a} ${t}`,c=i.exec(s,{stdio:"inherit",env:{...process.env,databases:process.databases,FORCE_COLOR:"1"}},p=>{p?(e.cleanup_process.send(JSON.stringify({process_ids:e?.process_ids})),process.exit(0)):(e.cleanup_process.send(JSON.stringify({process_ids:e?.process_ids})),process.exit(0))});_(c,e)})};var O=m;export{O as default,u as run_tests_integrated};
|
|
3
3
|
//# sourceMappingURL=run_tests.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/development_server/run_tests.js"],
|
|
4
|
-
"sourcesContent": ["import child_process from \"child_process\";\nimport cli_log from \"../cli_log.js\";\nimport chalk from 'chalk';\n\nconst handle_ava_stderr = (stderr = '') => {\n // NOTE: Squash output about using a configuration file (we always do in the framework).\n if (stderr?.includes('Using configuration')) {\n return null;\n }\n\n if (stderr?.includes('No tests found')) {\n return cli_log('No tests found. Add tests in the /tests folder at the root of your Joystick app.', {\n level: 'danger',\n docs: 'https://cheatcode.co/docs/joystick/test/setup',\n });\n }\n \n console.log(stderr);\n};\n\nconst handle_ava_stdout = (stdout = '') => {\n // NOTE: Squash output about using a configuration file (we always do in the framework).\n if (stdout?.includes('Using configuration')) {\n return null;\n }\n\n if (stdout?.includes('No tests found in')) {\n const [message] = stdout?.split(',');\n return console.log(`${message}\\n`);\n }\n \n console.log(stdout);\n};\n\nconst handle_ava_stdio = (ava = {}, run_tests_options = {}) => {\n ava.stdout.on('data', function (data) {\n const string = data.toString();\n handle_ava_stdout(string, run_tests_options);\n });\n\n ava.stderr.on('data', function (data) {\n const string = data.toString();\n handle_ava_stderr(string, run_tests_options);\n });\n};\n\nconst run_tests_integrated = (run_tests_options = {}) => {\n const ava_path = `${process.cwd()}/node_modules/.bin/ava`;\n const tap_reporter_path = `${run_tests_options?.__dirname}/tap_reporter.js`;\n \n return new Promise((resolve, reject) => {\n // NOTE: Run
|
|
5
|
-
"mappings": "AAAA,OAAOA,MAAmB,gBAC1B,OAAOC,MAAa,gBACpB,MAAkB,QAElB,MAAMC,EAAoB,CAACC,EAAS,KAAO,CAEzC,GAAIA,GAAQ,SAAS,qBAAqB,EACxC,OAAO,KAGT,GAAIA,GAAQ,SAAS,gBAAgB,EACnC,OAAOF,EAAQ,mFAAoF,CACjG,MAAO,SACP,KAAM,+CACR,CAAC,EAGH,QAAQ,IAAIE,CAAM,CACpB,EAEMC,EAAoB,CAACC,EAAS,KAAO,CAEzC,GAAIA,GAAQ,SAAS,qBAAqB,EACxC,OAAO,KAGT,GAAIA,GAAQ,SAAS,mBAAmB,EAAG,CACzC,KAAM,CAACC,CAAO,EAAID,GAAQ,MAAM,GAAG,EACnC,OAAO,QAAQ,IAAI,GAAGC,CAAO;AAAA,CAAI,CACnC,CAEA,QAAQ,IAAID,CAAM,CACpB,EAEME,EAAmB,CAACC,EAAM,CAAC,EAAGC,EAAoB,CAAC,IAAM,CAC7DD,EAAI,OAAO,GAAG,OAAQ,SAAUE,EAAM,CACpC,MAAMC,EAASD,EAAK,SAAS,EAC7BN,EAAkBO,EAAQF,CAAiB,CAC7C,CAAC,EAEDD,EAAI,OAAO,GAAG,OAAQ,SAAUE,EAAM,CACpC,MAAMC,EAASD,EAAK,SAAS,EAC7BR,EAAkBS,EAAQF,CAAiB,CAC7C,CAAC,CACH,EAEMG,EAAuB,CAACH,EAAoB,CAAC,IAAM,CACvD,MAAMI,EAAW,GAAG,QAAQ,IAAI,CAAC,yBAC3BC,EAAoB,GAAGL,GAAmB,SAAS,mBAEzD,OAAO,IAAI,QAAQ,CAACM,EAASC,IAAW,CAEtC,
|
|
6
|
-
"names": ["child_process", "cli_log", "handle_ava_stderr", "stderr", "handle_ava_stdout", "stdout", "message", "handle_ava_stdio", "ava", "run_tests_options", "data", "string", "run_tests_integrated", "ava_path", "tap_reporter_path", "resolve", "reject", "
|
|
4
|
+
"sourcesContent": ["import child_process from \"child_process\";\nimport cli_log from \"../cli_log.js\";\nimport chalk from 'chalk';\n\nconst handle_ava_stderr = (stderr = '') => {\n // NOTE: Squash output about using a configuration file (we always do in the framework).\n if (stderr?.includes('Using configuration')) {\n return null;\n }\n\n if (stderr?.includes('No tests found')) {\n return cli_log('No tests found. Add tests in the /tests folder at the root of your Joystick app.', {\n level: 'danger',\n docs: 'https://cheatcode.co/docs/joystick/test/setup',\n });\n }\n \n console.log(stderr);\n};\n\nconst handle_ava_stdout = (stdout = '') => {\n // NOTE: Squash output about using a configuration file (we always do in the framework).\n if (stdout?.includes('Using configuration')) {\n return null;\n }\n\n if (stdout?.includes('No tests found in')) {\n const [message] = stdout?.split(',');\n return console.log(`${message}\\n`);\n }\n \n console.log(stdout);\n};\n\nconst handle_ava_stdio = (ava = {}, run_tests_options = {}) => {\n ava.stdout.on('data', function (data) {\n const string = data.toString();\n handle_ava_stdout(string, run_tests_options);\n });\n\n ava.stderr.on('data', function (data) {\n const string = data.toString();\n handle_ava_stderr(string, run_tests_options);\n });\n};\n\nconst run_tests_integrated = (run_tests_options = {}) => {\n const ava_path = `${process.cwd()}/node_modules/.bin/ava`;\n const tap_reporter_path = `${run_tests_options?.__dirname}/tap_reporter.js`;\n \n return new Promise((resolve, reject) => {\n // NOTE: Run ava directly and spawn tap reporter separately to avoid shell exit propagation\n const ava = child_process.spawn(ava_path, [\n '--config', `${run_tests_options?.__dirname}/ava_config.js`,\n '--tap'\n ], {\n env: {\n ...(process.env),\n databases: process.databases,\n FORCE_COLOR: \"1\"\n }\n });\n\n const tap_reporter = child_process.spawn('node', [tap_reporter_path], {\n env: {\n ...(process.env),\n FORCE_COLOR: \"1\"\n }\n });\n\n // NOTE: Pipe ava output to tap reporter\n ava.stdout.pipe(tap_reporter.stdin);\n \n // NOTE: Stream tap reporter output to console\n tap_reporter.stdout.on('data', (data) => {\n process.stdout.write(data);\n });\n\n tap_reporter.stderr.on('data', (data) => {\n process.stderr.write(data);\n });\n\n // NOTE: Handle ava stderr directly (before piping to tap reporter)\n ava.stderr.on('data', (data) => {\n const stderr_string = data.toString();\n if (!stderr_string.includes('Using configuration')) {\n process.stderr.write(data);\n }\n });\n\n // NOTE: Handle process exits without propagating to parent\n ava.on('exit', (code, signal) => {\n tap_reporter.stdin.end();\n });\n\n tap_reporter.on('exit', (code, signal) => {\n // NOTE: Always resolve, never reject - we want to keep servers running\n resolve();\n });\n\n // NOTE: Handle any errors without crashing parent process\n ava.on('error', (error) => {\n console.error('Test runner error:', error.message);\n resolve();\n });\n\n tap_reporter.on('error', (error) => {\n console.error('TAP reporter error:', error.message);\n resolve();\n });\n });\n};\n\nconst run_tests = (run_tests_options = {}) => {\n // NOTE: A little bananas to reason through this. In order for Ava to run w/o errors,\n // the Ava binary being run here has to be identical to the one used in @joystick.js/test.\n // That would equal the copy of Ava that's installed in a Joystick app's node_modules\n // directory, not the node_modules directory of the CLI here. We can guarantee that will\n // exist for the CLI here because a developer has to install @joystick.js/test which will\n // add Ava as a dependency to their app in order to write tests.\n const ava_path = `${process.cwd()}/node_modules/.bin/ava`;\n const tap_reporter_path = `${run_tests_options?.__dirname}/tap_reporter.js`;\n \n return new Promise((resolve) => {\n // NOTE: Despite using the app's node_modules path to reference Ava, we still want to reference\n // the internal path here for the default test config in /lib/dev/tests.config.js.\n // Use TAP output and pipe to custom reporter only when not in watch mode\n const base_command = `DEBUG=ava:watcher && ${ava_path} --config ${run_tests_options?.__dirname}/ava_config.js`;\n const watch_flag = run_tests_options?.watch ? '--watch' : '';\n const tap_pipe = run_tests_options?.watch ? '' : `--tap | node ${tap_reporter_path}`;\n const full_command = `${base_command} ${watch_flag} ${tap_pipe}`;\n \n const ava = child_process.exec(full_command, {\n stdio: 'inherit',\n env: {\n ...(process.env),\n databases: process.databases,\n FORCE_COLOR: \"1\"\n }\n }, (error) => {\n if (!error) {\n // NOTE: Do this here because the standard SIGINT and SIGTERM hooks the dev process\n // listens for don't catch a clean exit (and the process.exit() hook fires after exit).\n run_tests_options.cleanup_process.send(JSON.stringify(({ process_ids: run_tests_options?.process_ids })));\n process.exit(0);\n } else {\n // NOTE: Do not report any Ava errors here because they're picked up by the handle_ava_stdio();\n // hook below. Just do a clean exit here so Node doesn't hang.\n run_tests_options.cleanup_process.send(JSON.stringify(({ process_ids: run_tests_options?.process_ids })));\n process.exit(0);\n }\n });\n\n handle_ava_stdio(ava, run_tests_options);\n });\n};\n\nexport { run_tests_integrated };\nexport default run_tests;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["child_process", "cli_log", "handle_ava_stderr", "stderr", "handle_ava_stdout", "stdout", "message", "handle_ava_stdio", "ava", "run_tests_options", "data", "string", "run_tests_integrated", "ava_path", "tap_reporter_path", "resolve", "reject", "tap_reporter", "code", "signal", "error", "run_tests", "base_command", "watch_flag", "tap_pipe", "full_command", "run_tests_default"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joystick.js/cli-canary",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.0-canary.
|
|
5
|
-
"canary_version": "0.0.0-canary.
|
|
4
|
+
"version": "0.0.0-canary.2140",
|
|
5
|
+
"canary_version": "0.0.0-canary.2139",
|
|
6
6
|
"description": "The CLI for Joystick.",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"bin": {
|
|
@@ -490,7 +490,7 @@ const development_server = async (development_server_options = {}) => {
|
|
|
490
490
|
} catch (error) {
|
|
491
491
|
console.error('Error running tests after file change:', error);
|
|
492
492
|
}
|
|
493
|
-
},
|
|
493
|
+
}, 2000);
|
|
494
494
|
} : null,
|
|
495
495
|
}, {
|
|
496
496
|
excluded_paths: settings?.config?.build?.excluded_paths,
|
|
@@ -49,31 +49,65 @@ const run_tests_integrated = (run_tests_options = {}) => {
|
|
|
49
49
|
const tap_reporter_path = `${run_tests_options?.__dirname}/tap_reporter.js`;
|
|
50
50
|
|
|
51
51
|
return new Promise((resolve, reject) => {
|
|
52
|
-
// NOTE: Run
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
// NOTE: Run ava directly and spawn tap reporter separately to avoid shell exit propagation
|
|
53
|
+
const ava = child_process.spawn(ava_path, [
|
|
54
|
+
'--config', `${run_tests_options?.__dirname}/ava_config.js`,
|
|
55
|
+
'--tap'
|
|
56
|
+
], {
|
|
56
57
|
env: {
|
|
57
58
|
...(process.env),
|
|
58
59
|
databases: process.databases,
|
|
59
60
|
FORCE_COLOR: "1"
|
|
60
61
|
}
|
|
61
|
-
}, (error, stdout, stderr) => {
|
|
62
|
-
// NOTE: Always resolve, never reject - we want to keep servers running
|
|
63
|
-
resolve();
|
|
64
62
|
});
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
const tap_reporter = child_process.spawn('node', [tap_reporter_path], {
|
|
65
|
+
env: {
|
|
66
|
+
...(process.env),
|
|
67
|
+
FORCE_COLOR: "1"
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// NOTE: Pipe ava output to tap reporter
|
|
72
|
+
ava.stdout.pipe(tap_reporter.stdin);
|
|
73
|
+
|
|
74
|
+
// NOTE: Stream tap reporter output to console
|
|
75
|
+
tap_reporter.stdout.on('data', (data) => {
|
|
68
76
|
process.stdout.write(data);
|
|
69
77
|
});
|
|
70
78
|
|
|
79
|
+
tap_reporter.stderr.on('data', (data) => {
|
|
80
|
+
process.stderr.write(data);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// NOTE: Handle ava stderr directly (before piping to tap reporter)
|
|
71
84
|
ava.stderr.on('data', (data) => {
|
|
72
85
|
const stderr_string = data.toString();
|
|
73
86
|
if (!stderr_string.includes('Using configuration')) {
|
|
74
87
|
process.stderr.write(data);
|
|
75
88
|
}
|
|
76
89
|
});
|
|
90
|
+
|
|
91
|
+
// NOTE: Handle process exits without propagating to parent
|
|
92
|
+
ava.on('exit', (code, signal) => {
|
|
93
|
+
tap_reporter.stdin.end();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
tap_reporter.on('exit', (code, signal) => {
|
|
97
|
+
// NOTE: Always resolve, never reject - we want to keep servers running
|
|
98
|
+
resolve();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// NOTE: Handle any errors without crashing parent process
|
|
102
|
+
ava.on('error', (error) => {
|
|
103
|
+
console.error('Test runner error:', error.message);
|
|
104
|
+
resolve();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
tap_reporter.on('error', (error) => {
|
|
108
|
+
console.error('TAP reporter error:', error.message);
|
|
109
|
+
resolve();
|
|
110
|
+
});
|
|
77
111
|
});
|
|
78
112
|
};
|
|
79
113
|
|