4 Commits

Author SHA1 Message Date
abc1cef7c2 Implement missing sample data loading and one-time use security
- Fix UI to load server-hosted sample data at startup as per specification
- Add one-time use security: server clears sample data after retrieval
- Ensure React app periodically checks for new sample data availability
- Remove complex same-origin protection in favor of simpler one-time use model
- Improve data security by preventing data persistence after consumption
2026-01-23 06:15:21 +01:00
766ff96137 Add upload-jmespath script for JSON file uploads to API 2026-01-23 06:05:01 +01:00
e22b3c82a2 Fix Docker build version detection
- Skip prebuild step in Docker when VERSION build arg is provided
- Prevent version-check.js from overwriting pre-generated version.js in Docker
- Fix Docker containers showing incorrect '-dev' suffix for release builds
- Use direct react-scripts build when version is pre-generated
2026-01-21 22:06:37 +01:00
c9ce0d14b9 Separate Docker build into dedicated script
- Create build-image.sh for dedicated Docker image building
- Remove Docker build logic from build.sh to focus on Node.js app only
- Add comprehensive instructions for running and pushing Docker images
- Improve build script modularity and separation of concerns
2026-01-21 21:55:58 +01:00
7 changed files with 139 additions and 54 deletions

View File

@@ -31,8 +31,14 @@ RUN if [ -n "$VERSION" ]; then \
echo "📝 Generated version.js with VERSION=$VERSION, IS_RELEASE=$IS_RELEASE"; \ echo "📝 Generated version.js with VERSION=$VERSION, IS_RELEASE=$IS_RELEASE"; \
fi fi
# Build the application # Build the application (skip prebuild if we already generated version.js)
RUN npm run build RUN if [ -n "$VERSION" ]; then \
echo "🚀 Building with pre-generated version.js" && \
npx react-scripts build; \
else \
echo "🚀 Building with version-check.js" && \
npm run build; \
fi
# Production stage # Production stage
FROM node:24-alpine AS production FROM node:24-alpine AS production

41
bin/upload-jmespath Executable file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -euo pipefail
API_URL="https://jmespath-playground.koszewscy.waw.pl"
JSON_FILE="-"
function usage() {
echo "Usage: $0 [--api-url <url>] [--json-file <file>]"
exit 1
}
while [[ $# -gt 0 ]]; do
case $1 in
--api-url)
API_URL="$2"
shift 2
;;
--json-file)
JSON_FILE="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "ERROR: Unknown argument: $1"
usage
exit 1
;;
esac
done
# Send the POST request
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data @${JSON_FILE} \
"$API_URL/api/v1/upload"

View File

@@ -1,6 +1,6 @@
{ {
"name": "jmespath-playground", "name": "jmespath-playground",
"version": "1.1.4", "version": "1.1.7",
"description": "A React-based web application for testing JMESPath expressions against JSON data", "description": "A React-based web application for testing JMESPath expressions against JSON data",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

63
scripts/build-image.sh Executable file
View File

@@ -0,0 +1,63 @@
#!/bin/bash
# JMESPath Testing Tool - Docker Image Build Script
set -e
echo "🐳 JMESPath Testing Tool - Docker Image Build"
echo "=============================================="
echo ""
# Check if Docker is available
if ! command -v docker &> /dev/null; then
echo "❌ Docker not found. Please install Docker to build container images."
exit 1
fi
# Determine version information for Docker build
VERSION=$(git tag --points-at HEAD 2>/dev/null | sed 's/^v//' | head -n 1)
if [ -n "$VERSION" ]; then
# We're at a tagged commit - release build
echo "📦 Building release version: $VERSION"
docker build \
--build-arg VERSION="$VERSION" \
--build-arg IS_RELEASE="true" \
-t skoszewski/jmespath-playground:$VERSION \
-t skoszewski/jmespath-playground:latest .
echo "✅ Built Docker images: skoszewski/jmespath-playground:$VERSION, skoszewski/jmespath-playground:latest"
echo ""
echo "To run the release container:"
echo " docker run -p 3000:3000 skoszewski/jmespath-playground:$VERSION"
echo " docker run -p 3000:3000 skoszewski/jmespath-playground:latest"
echo ""
echo "To push to Docker Hub:"
echo " docker push skoszewski/jmespath-playground:$VERSION"
echo " docker push skoszewski/jmespath-playground:latest"
else
# Development build
PACKAGE_VERSION=$(grep '"version"' package.json | cut -d'"' -f4)
DEV_VERSION="${PACKAGE_VERSION}-dev"
echo "📦 Building development version: $DEV_VERSION"
docker build \
--build-arg VERSION="$DEV_VERSION" \
--build-arg IS_RELEASE="false" \
-t skoszewski/jmespath-playground:dev \
-t skoszewski/jmespath-playground:latest .
echo "✅ Built Docker images: skoszewski/jmespath-playground:dev, skoszewski/jmespath-playground:latest"
echo ""
echo "To run the development container:"
echo " docker run -p 3000:3000 skoszewski/jmespath-playground:dev"
echo " docker run -p 3000:3000 skoszewski/jmespath-playground:latest"
echo ""
echo "To push to Docker Hub:"
echo " docker push skoszewski/jmespath-playground:dev"
echo " docker push skoszewski/jmespath-playground:latest"
fi
echo ""
echo "🎉 Docker image build completed successfully!"

View File

@@ -30,49 +30,10 @@ npm install
echo "🔨 Building production bundle..." echo "🔨 Building production bundle..."
npm run build npm run build
# Optional container build with Docker
if command -v docker &> /dev/null; then
echo "🐳 Building Docker container (optional)..."
# Determine version information for Docker build
VERSION=$(git tag --points-at HEAD 2>/dev/null | sed 's/^v//' | head -n 1)
if [ -n "$VERSION" ]; then
# We're at a tagged commit - release build
echo "📦 Building release version: $VERSION"
docker build \
--build-arg VERSION="$VERSION" \
--build-arg IS_RELEASE="true" \
-t skoszewski/jmespath-playground:$VERSION \
-t skoszewski/jmespath-playground:latest .
echo "✅ Built Docker images: skoszewski/jmespath-playground:$VERSION, skoszewski/jmespath-playground:latest"
else
# Development build
PACKAGE_VERSION=$(grep '"version"' package.json | cut -d'"' -f4)
DEV_VERSION="${PACKAGE_VERSION}-dev"
echo "📦 Building development version: $DEV_VERSION"
docker build \
--build-arg VERSION="$DEV_VERSION" \
--build-arg IS_RELEASE="false" \
-t skoszewski/jmespath-playground:dev \
-t skoszewski/jmespath-playground:latest .
echo "✅ Built Docker images: skoszewski/jmespath-playground:dev, skoszewski/jmespath-playground:latest"
fi
else
echo "💡 Docker not found. Container build is optional."
echo " Install Docker if you want to build containers."
fi
echo "✅ Build completed successfully!" echo "✅ Build completed successfully!"
echo "" echo ""
echo "To run the application:" echo "To run the application:"
echo " npm run server # Run integrated server locally" echo " npm run server # Run integrated server locally"
if command -v docker &> /dev/null; then echo ""
VERSION=$(git tag --points-at HEAD 2>/dev/null | sed 's/^v//' | head -n 1) echo "To build Docker image:"
if [ -n "$VERSION" ]; then echo " scripts/build-image.sh # Build Docker container image"
echo " docker run -p 3000:3000 skoszewski/jmespath-playground:$VERSION # Run release container"
else
echo " docker run -p 3000:3000 skoszewski/jmespath-playground:dev # Run dev container"
fi
echo " docker run -p 3000:3000 skoszewski/jmespath-playground:latest # Run latest container"
fi

View File

@@ -51,7 +51,13 @@ function createApp() {
app.get('/api/v1/sample', (req, res) => { app.get('/api/v1/sample', (req, res) => {
try { try {
res.json(sampleData); const dataToReturn = sampleData;
// Security: Clear the sample data after it's retrieved (one-time use)
sampleData = null;
console.log('📤 Sample data retrieved and cleared from server memory');
res.json(dataToReturn);
} catch (error) { } catch (error) {
res.status(500).json({ error: 'Failed to retrieve sample data' }); res.status(500).json({ error: 'Failed to retrieve sample data' });
} }

View File

@@ -54,22 +54,30 @@ function App() {
localStorage.setItem('theme', theme); localStorage.setItem('theme', theme);
}, [theme]); }, [theme]);
// API polling for state changes // API polling for state changes and initial sample data load
useEffect(() => { useEffect(() => {
// Initial state load // Initial load: get both state and sample data
const loadInitialState = async () => { const loadInitialData = async () => {
try { try {
const response = await fetch('/api/v1/state'); // Load sample data first
if (response.ok) { const sampleResponse = await fetch('/api/v1/sample');
const data = await response.json(); if (sampleResponse.ok) {
setCurrentStateGuid(data.state); const sampleData = await sampleResponse.json();
setJsonData(JSON.stringify(sampleData, null, 2));
}
// Then load state GUID
const stateResponse = await fetch('/api/v1/state');
if (stateResponse.ok) {
const stateData = await stateResponse.json();
setCurrentStateGuid(stateData.state);
} }
} catch (error) { } catch (error) {
console.debug('API not available:', error); console.debug('API not available:', error);
} }
}; };
loadInitialState(); loadInitialData();
// Poll for state changes every 3 seconds // Poll for state changes every 3 seconds
const interval = setInterval(async () => { const interval = setInterval(async () => {