diff --git a/spiffworkflow-frontend/bin/boot_server_in_docker b/spiffworkflow-frontend/bin/boot_server_in_docker index 43a4e0f2..5792bd3b 100755 --- a/spiffworkflow-frontend/bin/boot_server_in_docker +++ b/spiffworkflow-frontend/bin/boot_server_in_docker @@ -7,4 +7,29 @@ function error_handler() { trap 'error_handler ${LINENO} $?' ERR set -o errtrace -o errexit -o nounset -o pipefail +# sort of like https://lithic.tech/blog/2020-05/react-dynamic-config, but without golang +react_configs=$(env | grep -E "^SPIFFWORKFLOW_FRONTEND_RUNTIME_CONFIG_") +if [[ -n "$react_configs" ]]; then + index_html_file="./build/index.html" + if [[ ! -f "$index_html_file" ]]; then + >&2 echo "ERROR: Could not find '${index_html_file}'. Cannot use SPIFFWORKFLOW_FRONTEND_RUNTIME_CONFIG values without it." + exit 1 + fi + + if ! command -v sed >/dev/null ; then + >&2 echo "ERROR: sed command not found. Cannot use SPIFFWORKFLOW_FRONTEND_RUNTIME_CONFIG values without it." + exit 1 + fi + + if ! command -v perl >/dev/null ; then + >&2 echo "ERROR: perl command not found. Cannot use SPIFFWORKFLOW_FRONTEND_RUNTIME_CONFIG values without it." + exit 1 + fi + + for react_config in $react_configs; do + react_config_without_prefix=$(sed -E 's/^SPIFFWORKFLOW_FRONTEND_RUNTIME_CONFIG_([^=]*)=(.*)/\1=\\"\2\\"/' <<<"${react_config}") + perl -pi -e "s/(window._jsenv=\{\})/\1;window._jsenv.${react_config_without_prefix}/" "$index_html_file" + done +fi + exec ./node_modules/.bin/serve -s build -l "$PORT0" diff --git a/spiffworkflow-frontend/public/index.html b/spiffworkflow-frontend/public/index.html index 1a7cafa9..111f3c6d 100644 --- a/spiffworkflow-frontend/public/index.html +++ b/spiffworkflow-frontend/public/index.html @@ -25,6 +25,10 @@ Learn how to configure a non-root public URL by running `npm run build`. --> SpiffWorkflow + + diff --git a/spiffworkflow-frontend/src/config.tsx b/spiffworkflow-frontend/src/config.tsx index 9813b943..e38ab19d 100644 --- a/spiffworkflow-frontend/src/config.tsx +++ b/spiffworkflow-frontend/src/config.tsx @@ -1,17 +1,46 @@ const { port, hostname } = window.location; -let hostAndPort = hostname; let protocol = 'https'; +declare global { + interface SpiffworkflowFrontendJsenvObject { + [key: string]: string; + } + interface Window { + spiffworkflowFrontendJsenv: SpiffworkflowFrontendJsenvObject; + } +} + +let appRoutingStrategy = 'subdomain_based'; +if ( + 'spiffworkflowFrontendJsenv' in window && + 'APP_ROUTING_STRATEGY' in window.spiffworkflowFrontendJsenv +) { + appRoutingStrategy = window.spiffworkflowFrontendJsenv.APP_ROUTING_STRATEGY; +} + +let hostAndPortAndPathPrefix; +if (appRoutingStrategy === 'subdomain_based') { + hostAndPortAndPathPrefix = `api.${hostname}`; +} else if (appRoutingStrategy === 'path_based') { + hostAndPortAndPathPrefix = `${hostname}/api`; +} else { + throw new Error(`Invalid app routing strategy: ${appRoutingStrategy}`); +} + if (/^\d+\./.test(hostname) || hostname === 'localhost') { let serverPort = 7000; if (!Number.isNaN(Number(port))) { serverPort = Number(port) - 1; } - hostAndPort = `${hostname}:${serverPort}`; + hostAndPortAndPathPrefix = `${hostname}:${serverPort}`; protocol = 'http'; } -let url = `${protocol}://${hostAndPort}/api/v1.0`; +let url = `${protocol}://${hostAndPortAndPathPrefix}/v1.0`; + +// this can only ever work locally since this is a static site. +// use spiffworkflowFrontendJsenv if you want to inject env vars +// that can be read by the static site. if (process.env.REACT_APP_BACKEND_BASE_URL) { url = process.env.REACT_APP_BACKEND_BASE_URL; }