This commit is contained in:
Waleed Latif
2025-03-13 15:06:25 -07:00
parent 145bd0cca6
commit 8bd26159a7
412 changed files with 200 additions and 4146 deletions

View File

@@ -1,281 +0,0 @@
#!/usr/bin/env node
/**
* Build Standalone App Script
*
* This script builds a standalone version of Sim Studio that can be run without a database.
* It creates a tarball that includes:
* 1. A pre-built Next.js application
* 2. A simple Express server to serve the application
* 3. Configuration to use browser localStorage for data persistence
*/
const fs = require('fs')
const path = require('path')
const { execSync } = require('child_process')
const tar = require('tar')
const crypto = require('crypto')
// Configuration
const ROOT_DIR = path.resolve(__dirname, '..')
const STANDALONE_DIR = path.join(ROOT_DIR, 'packages/simstudio/standalone')
const STANDALONE_PACKAGE_JSON = path.join(STANDALONE_DIR, 'package.json')
const STANDALONE_SERVER_JS = path.join(STANDALONE_DIR, 'server.js')
const OUTPUT_TARBALL = path.join(ROOT_DIR, 'sim-standalone.tar.gz')
// Ensure the standalone directory exists
if (!fs.existsSync(STANDALONE_DIR)) {
fs.mkdirSync(STANDALONE_DIR, { recursive: true })
}
// Clean the standalone directory first
if (fs.existsSync(STANDALONE_DIR)) {
fs.rmSync(STANDALONE_DIR, { recursive: true, force: true })
}
fs.mkdirSync(STANDALONE_DIR, { recursive: true })
// Build the Next.js app with local storage mode
console.log('Building Next.js app in standalone mode...')
try {
// Instead of using static export, we'll build a regular Next.js app
// and then copy the necessary files to run it with a simple Express server
execSync('npm run build', {
cwd: ROOT_DIR,
stdio: 'inherit',
env: {
...process.env,
USE_LOCAL_STORAGE: 'true',
NEXT_PUBLIC_USE_LOCAL_STORAGE: 'true',
DISABLE_DB_SYNC: 'true',
NODE_ENV: 'production',
},
})
} catch (error) {
console.error('Failed to build Next.js app:', error)
console.log('Continuing with the standalone build process...')
}
// Copy the built app to the standalone directory
console.log('Copying built app to standalone directory...')
try {
// Copy the .next directory
if (fs.existsSync(path.join(ROOT_DIR, '.next'))) {
execSync(`cp -r ${path.join(ROOT_DIR, '.next')} ${path.join(STANDALONE_DIR, '.next')}`)
}
// Copy the public directory
if (fs.existsSync(path.join(ROOT_DIR, 'public'))) {
execSync(`cp -r ${path.join(ROOT_DIR, 'public')} ${path.join(STANDALONE_DIR, 'public')}`)
}
// Copy necessary files for standalone operation
if (fs.existsSync(path.join(ROOT_DIR, 'next.config.ts'))) {
execSync(
`cp ${path.join(ROOT_DIR, 'next.config.ts')} ${path.join(STANDALONE_DIR, 'next.config.ts')}`
)
}
} catch (error) {
console.error('Failed to copy built app:', error)
process.exit(1)
}
// Create a package.json for the standalone app
console.log('Creating package.json for standalone app...')
const packageJson = {
name: 'sim-studio-standalone',
version: '0.1.0',
private: true,
scripts: {
start: 'node server.js',
},
dependencies: {
express: '^4.18.2',
next: '^15.2.0',
react: '^18.2.0',
'react-dom': '^18.2.0',
compression: '^1.7.4',
'serve-favicon': '^2.5.0',
typescript: '^5.7.3',
},
}
fs.writeFileSync(STANDALONE_PACKAGE_JSON, JSON.stringify(packageJson, null, 2))
// Create a simple Express server to serve the static files
console.log('Creating server.js for standalone app...')
const serverJs = `
const express = require('express');
const next = require('next');
const path = require('path');
const fs = require('fs');
const compression = require('compression');
const favicon = require('serve-favicon');
const crypto = require('crypto');
// Register TypeScript compiler
require('typescript');
// Set environment variables for standalone mode
process.env.USE_LOCAL_STORAGE = 'true';
process.env.NEXT_PUBLIC_USE_LOCAL_STORAGE = 'true';
process.env.DISABLE_DB_SYNC = 'true';
process.env.DISABLE_AUTH = 'true';
process.env.NEXT_PUBLIC_DISABLE_AUTH = 'true';
const port = process.env.SIM_STUDIO_PORT || 3000;
const dev = false; // Always run in production mode
// Initialize Next.js
const app = next({ dev, dir: __dirname });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = express();
// Enable compression
server.use(compression());
// Serve favicon
if (fs.existsSync(path.join(__dirname, 'public', 'favicon.ico'))) {
server.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
}
// Middleware to set environment variables for each request
server.use((req, res, next) => {
// These will be available to the API routes
process.env.USE_LOCAL_STORAGE = 'true';
process.env.NEXT_PUBLIC_USE_LOCAL_STORAGE = 'true';
process.env.DISABLE_DB_SYNC = 'true';
process.env.DISABLE_AUTH = 'true';
process.env.NEXT_PUBLIC_DISABLE_AUTH = 'true';
next();
});
// Redirect root path to a new workflow
server.get('/', (req, res) => {
// Generate a UUID for the new workflow
const uuid = crypto.randomUUID();
console.log(\`Redirecting to new workflow: \${uuid}\`);
// Use 302 redirect to ensure it's not cached and is followed
return res.redirect(302, \`/w/\${uuid}\`);
});
// Handle all other requests with Next.js
server.all('*', (req, res) => {
return handle(req, res);
});
// Start the server
server.listen(port, (err) => {
if (err) throw err;
console.log(\`> Sim Studio standalone server ready on http://localhost:\${port}\`);
console.log('> Running in local storage mode - all data will be stored in the browser');
console.log('> Authentication is disabled - anyone can access the app');
console.log('> Root path (/) will redirect to a new workflow automatically');
});
});
`
fs.writeFileSync(STANDALONE_SERVER_JS, serverJs)
// Skip creating .env file for the standalone app
console.log('Skipping .env file creation for standalone app...')
// Create a tsconfig.json for the standalone app
console.log('Creating tsconfig.json for standalone app...')
const tsconfigJson = {
compilerOptions: {
target: 'es5',
lib: ['dom', 'dom.iterable', 'esnext'],
allowJs: true,
skipLibCheck: true,
strict: true,
forceConsistentCasingInFileNames: true,
noEmit: true,
esModuleInterop: true,
module: 'esnext',
moduleResolution: 'node',
resolveJsonModule: true,
isolatedModules: true,
jsx: 'preserve',
incremental: true,
plugins: [
{
name: 'next',
},
],
paths: {
'@/*': ['./*'],
},
},
include: ['next-env.d.ts', '**/*.ts', '**/*.tsx', '.next/types/**/*.ts'],
exclude: ['node_modules'],
}
fs.writeFileSync(path.join(STANDALONE_DIR, 'tsconfig.json'), JSON.stringify(tsconfigJson, null, 2))
// Create a README.md for the standalone app
console.log('Creating README.md for standalone app...')
const readmeFile = `# Sim Studio Standalone
This is a standalone version of Sim Studio that runs without a database. All data is stored in your browser's localStorage.
## Getting Started
1. Install dependencies:
\`\`\`
npm install
\`\`\`
2. Start the server:
\`\`\`
npm start
\`\`\`
3. Open your browser to http://localhost:3000
## Features
- **Full Functionality**: All features of Sim Studio are available, including API routes
- **No Authentication Required**: Just start building workflows right away
- **Local Storage**: All your workflows and settings are stored in your browser's localStorage
- **Drag and Drop Interface**: Easily create and connect workflow blocks
- **Real-time Execution**: Test your workflows as you build them
## Environment Variables
You can customize the app by setting these environment variables:
- \`SIM_STUDIO_PORT\`: Change the port (default: 3000)
## How It Works
When you start the app, it will:
1. Automatically redirect you to a new workflow with a unique ID
2. Allow you to drag and drop blocks to build your workflow
3. Save all your work to localStorage in your browser
4. Let you execute workflows directly in the browser
No database or authentication is required!
`
fs.writeFileSync(path.join(STANDALONE_DIR, 'README.md'), readmeFile)
// Create the tarball
console.log('Creating tarball...')
try {
// Remove any .env files before creating the tarball
console.log('Removing any .env files from the standalone directory...')
execSync('find ' + STANDALONE_DIR + ' -name ".env*" -type f -delete')
// Create the tarball
execSync(
`tar -czf ${OUTPUT_TARBALL} -C ${path.dirname(STANDALONE_DIR)} ${path.basename(STANDALONE_DIR)}`
)
console.log(`Standalone app built and packaged to ${OUTPUT_TARBALL}`)
console.log('You can now upload this file to GitHub releases')
} catch (error) {
console.error('Failed to create tarball:', error)
process.exit(1)
}

View File

@@ -1,7 +0,0 @@
#!/bin/bash
# Generate migrations using Drizzle
echo "Generating database migrations..."
docker compose exec simstudio npm run db:push
echo "Migrations generated successfully."

View File

@@ -1,102 +0,0 @@
#!/usr/bin/env node
/**
* Release NPM Package Script
*
* This script helps with the process of releasing the Sim Studio CLI to npm.
* It builds the standalone app, prepares the CLI package, and publishes it to npm.
*/
const fs = require('fs')
const path = require('path')
const { execSync } = require('child_process')
// Configuration
const ROOT_DIR = path.resolve(__dirname, '..')
const CLI_DIR = path.join(ROOT_DIR, 'packages/@simstudio/cli')
const STANDALONE_DIR = path.join(CLI_DIR, 'standalone')
const OUTPUT_TARBALL = path.join(ROOT_DIR, 'sim-standalone.tar.gz')
// Ensure we're in the right directory
process.chdir(ROOT_DIR)
// Helper function to run commands and log output
function runCommand(command, options = {}) {
console.log(`> ${command}`)
try {
execSync(command, {
stdio: 'inherit',
...options,
})
return true
} catch (error) {
console.error(`Error running command: ${command}`)
console.error(error)
return false
}
}
// Main release process
async function release() {
console.log('=== Sim Studio CLI Release Process ===')
// 1. Clean up any existing standalone files
console.log('\n1. Cleaning up existing standalone files...')
if (fs.existsSync(STANDALONE_DIR)) {
fs.rmSync(STANDALONE_DIR, { recursive: true, force: true })
}
if (fs.existsSync(OUTPUT_TARBALL)) {
fs.unlinkSync(OUTPUT_TARBALL)
}
// 2. Build the standalone app
console.log('\n2. Building standalone app...')
if (!runCommand('node scripts/build-standalone.js')) {
console.error('Failed to build standalone app')
process.exit(1)
}
// 3. Prepare the CLI package
console.log('\n3. Preparing CLI package...')
process.chdir(CLI_DIR)
// Clean and build
if (!runCommand('npm run clean && npm run build')) {
console.error('Failed to build CLI package')
process.exit(1)
}
// 4. Create the standalone directory
console.log('\n4. Creating standalone directory...')
if (!fs.existsSync(STANDALONE_DIR)) {
fs.mkdirSync(STANDALONE_DIR, { recursive: true })
}
// 5. Publish to npm
console.log('\n5. Publishing to npm...')
console.log('Ready to publish to npm. Run the following commands:')
console.log(`
cd ${path.relative(process.cwd(), CLI_DIR)}
npm publish
`)
// 6. Create GitHub release
console.log('\n6. Creating GitHub release...')
console.log('After publishing to npm, create a GitHub release with the standalone tarball:')
console.log(`
1. Go to https://github.com/simstudioai/sim/releases/new
2. Set the tag to v0.1.0 (or your current version)
3. Set the title to "Sim Studio v0.1.0"
4. Upload the tarball: ${path.relative(ROOT_DIR, OUTPUT_TARBALL)}
5. Publish the release
`)
console.log('\n=== Release Process Complete ===')
console.log('Follow the instructions above to publish to npm and create a GitHub release.')
}
// Run the release process
release().catch((error) => {
console.error('Release process failed:', error)
process.exit(1)
})

View File

@@ -1,33 +0,0 @@
#!/bin/bash
set -e
echo "Setting up Sim Studio CLI Package..."
# Create directory structure if it doesn't exist
mkdir -p packages/@simstudio/cli/bin
mkdir -p packages/@simstudio/cli/src/commands
mkdir -p packages/@simstudio/cli/src/utils
# Navigate to CLI directory
cd packages/@simstudio/cli
# Install dependencies
echo "Installing CLI dependencies..."
npm install
# Build the CLI package
echo "Building CLI package..."
npm run build
# Make the CLI executable
chmod +x bin/sim.js
echo "✅ CLI setup complete!"
echo ""
echo "You can now run:"
echo " npm run cli:start - to test the CLI"
echo " npm run cli:dev - to develop the CLI with live reload"
echo " npm run cli:publish - to publish to npm"
echo ""
echo "Try it out with: ./packages/@simstudio/cli/bin/sim.js"

View File

@@ -1,25 +0,0 @@
#!/bin/bash
# Check if .env file exists, if not, create from example
if [ ! -f .env ]; then
echo "Creating .env file from .env.example..."
cp .env.example .env
echo "Please update .env file with your configuration."
fi
# Stop any running containers
docker compose down
# Build and start containers in detached mode
docker compose up --build -d
# Wait for database to be ready
echo "Waiting for database to be ready..."
sleep 5
# Apply migrations automatically
echo "Applying database migrations..."
docker compose exec simstudio npm run db:push
echo "Sim Studio is now running at http://localhost:3000"
echo "To view logs, run: docker compose logs -f simstudio"