**chore: remove comprehensive test scripts and related documentation**

- Removed the `scripts/comprehensive-test.js` script and its auxiliary files (`node-test.js`, `TENSORFLOW_NODEJS.md`, and `scripts/test-cli-locally.js`).
- These files encompassed unified testing across environments (Browser, Node.js, and CLI) and TensorFlow.js compatibility.
- Reflects a strategic decision to deprecate integrated testing workflow in favor of modular testing approaches and project simplification.

This cleanup aligns with the ongoing effort to streamline the repository and remove redundant or outdated test infrastructure.
This commit is contained in:
David Snelling 2025-07-15 11:50:37 -07:00
parent 3bc374730b
commit c88e1960da
5 changed files with 0 additions and 959 deletions

View file

@ -1,78 +0,0 @@
# Using TensorFlow.js with Brainy in Node.js Environments
This document provides guidance on resolving TensorFlow.js compatibility issues when using Brainy in Node.js environments, particularly with ES modules.
## Common Issues
When using Brainy with TensorFlow.js in Node.js environments, you might encounter errors like:
```
TypeError: this.util.TextEncoder is not a constructor
```
This occurs due to how TensorFlow.js initializes its platform detection in ES modules environments.
## Solution
Brainy includes a built-in patch to address these issues. The patch is automatically applied when you import Brainy, but in some complex project setups, you might need to take additional steps.
### Option 1: Import the Setup Module First (Recommended)
For the most reliable solution, explicitly import Brainy's setup module before any other imports that might use TensorFlow.js:
```javascript
// Import the setup module first to apply TensorFlow.js patches
import '@soulcraft/brainy/setup';
// Then import and use Brainy or TensorFlow.js
import { BrainyData } from '@soulcraft/brainy';
// ... your code here
```
### Option 2: Apply the Patch Directly
If you need more control, you can directly apply the patch:
```javascript
// Import and apply the patch directly
import { applyTensorFlowPatch } from '@soulcraft/brainy/utils/textEncoding';
applyTensorFlowPatch();
// Then import and use TensorFlow.js
import * as tf from '@tensorflow/tfjs';
// ... your code here
```
### Option 3: For CommonJS Environments
If you're using CommonJS modules:
```javascript
// Apply the patch first
require('@soulcraft/brainy/dist/setup.js');
// Then require TensorFlow.js or Brainy
const brainy = require('@soulcraft/brainy');
// ... your code here
```
## How It Works
The patch works by:
1. Ensuring TextEncoder and TextDecoder are properly available in the global scope
2. Creating a custom PlatformNode implementation that TensorFlow.js will use
3. Applying the patch before any TensorFlow.js code is executed
## Troubleshooting
If you still encounter issues:
1. Make sure the setup module is imported before any other modules that might use TensorFlow.js
2. Check your bundler configuration to ensure it's not removing the patch code (it's marked as having side effects)
3. Try using the CommonJS approach if you're having issues with ES modules
4. If using a bundler like webpack or rollup, ensure it's configured to handle Node.js built-ins properly
## Need More Help?
If you continue to experience issues, please open an issue on our GitHub repository with details about your environment and how you're using Brainy.

View file

@ -1,102 +0,0 @@
/**
* CLI Test for TensorFlow.js and TextEncoder
*
* This script tests TensorFlow.js and TextEncoder functionality in the CLI environment.
*/
import {
getTextEncoder,
getTextDecoder
} from './utils/textEncoding.js'
import * as tf from '@tensorflow/tfjs'
import '@tensorflow/tfjs-backend-cpu'
export async function testTensorFlowAndTextEncoder(): Promise<boolean> {
console.log('Testing TensorFlow.js and TextEncoder in CLI environment...')
try {
// TensorFlow patch is automatically applied by the main package
console.log('Using TensorFlow with automatic patching')
// Test TextEncoder
console.log('\n--- Testing TextEncoder ---')
const encoder = getTextEncoder()
const decoder = getTextDecoder()
const testString = 'Hello, world! 👋'
console.log(`Original string: "${testString}"`)
const encoded = encoder.encode(testString)
console.log(`Encoded: [${encoded}]`)
const decoded = decoder.decode(encoded)
console.log(`Decoded: "${decoded}"`)
if (testString === decoded) {
console.log('✅ TextEncoder/TextDecoder test passed!')
} else {
console.error('❌ TextEncoder/TextDecoder test failed!')
return false
}
// Test TensorFlow.js
console.log('\n--- Testing TensorFlow.js ---')
// Create a simple tensor
const tensor = tf.tensor2d([
[1, 2],
[3, 4]
])
console.log('Created tensor:')
tensor.print()
// Perform a simple operation
const result = tensor.add(tf.scalar(1))
console.log('Result of adding 1:')
result.print()
// Check the values
const values = await result.array()
const expected = [
[2, 3],
[4, 5]
]
console.log('Result values:', values)
console.log('Expected values:', expected)
// Compare values
const match = JSON.stringify(values) === JSON.stringify(expected)
if (match) {
console.log('✅ TensorFlow.js test passed!')
} else {
console.error('❌ TensorFlow.js test failed!')
return false
}
console.log('\nAll tests passed successfully!')
return true
} catch (error) {
console.error('Error during test:', error)
return false
}
}
// This function can be called from the CLI
export async function runTest(): Promise<void> {
const success = await testTensorFlowAndTextEncoder()
if (success) {
console.log(
'TensorFlow.js and TextEncoder verification completed successfully!'
)
process.exit(0)
} else {
console.error('TensorFlow.js and TextEncoder verification failed!')
process.exit(1)
}
}
// If this file is run directly
if (typeof require !== 'undefined' && require.main === module) {
runTest()
}

View file

@ -1,75 +0,0 @@
// Node.js test script for @soulcraft/brainy
// CRITICAL: First, directly apply the TensorFlow.js patch
// This is the most reliable way to ensure the patch is applied before TensorFlow.js is loaded
import { TextEncoder, TextDecoder } from 'util'
// Make TextEncoder and TextDecoder available globally
if (typeof global !== 'undefined') {
global.TextEncoder = TextEncoder
global.TextDecoder = TextDecoder
}
// Import the library
import * as brainy from './dist/unified.js'
async function runNodeTest() {
console.log('\n=== Testing @soulcraft/brainy in Node.js environment ===\n')
try {
// Test environment detection
console.log('Environment Detection:')
console.log(`- isBrowser: ${brainy.isBrowser()}`)
console.log(`- isNode: ${brainy.isNode()}`)
console.log(`- isWebWorker: ${brainy.isWebWorker()}`)
console.log(`- areWebWorkersAvailable: ${brainy.areWebWorkersAvailable()}`)
console.log(`- isThreadingAvailable: ${brainy.isThreadingAvailable()}`)
console.log(
`- areWorkerThreadsAvailableSync: ${brainy.areWorkerThreadsAvailableSync()}`
)
// Test TensorFlow functionality
console.log('\nTesting TensorFlow functionality...')
// Create a simple BrainyData instance
const data = new brainy.BrainyData({
dimensions: 2,
metric: 'euclidean'
})
console.log('Successfully created BrainyData instance')
// Initialize the database
console.log('Initializing database...')
await data.init()
// Add a simple vector
await data.add([1, 2], { id: 'test1', text: 'Test item' })
console.log('Successfully added item to BrainyData')
// Search for similar vectors
const results = await data.search([1, 2], 1)
console.log('Search results:', results)
// Test embedding functionality (which uses TensorFlow)
console.log('\nTesting embedding functionality...')
const embeddingFunction = brainy.createEmbeddingFunction()
const embedding = await embeddingFunction('This is a test sentence')
console.log(
`Successfully created embedding with length: ${embedding.length}`
)
console.log('\n✅ All Node.js tests passed successfully!')
return true
} catch (error) {
console.error('❌ Node.js test failed:', error)
return false
}
}
// Run the test
runNodeTest().then((success) => {
if (!success) {
process.exit(1)
}
})

View file

@ -1,574 +0,0 @@
#!/usr/bin/env node
/**
* Comprehensive Test Script for @soulcraft/brainy
*
* This script tests the library in all environments:
* - Browser (using Puppeteer for headless browser testing)
* - Node.js/server
* - CLI
*
* It verifies:
* - Library loading in each environment
* - TensorFlow functionality in each environment
* - Environment detection functionality
*/
import { execSync } from 'child_process'
import { fileURLToPath } from 'url'
import path from 'path'
import fs from 'fs'
import http from 'http'
import puppeteer from 'puppeteer'
// Get the directory of the current module
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const rootDir = path.join(__dirname, '..')
// Define colors for console output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
green: '\x1b[32m',
yellow: '\x1b[33m',
red: '\x1b[31m',
cyan: '\x1b[36m',
magenta: '\x1b[35m',
blue: '\x1b[34m'
}
// Helper function to log with colors
function log(message, color = colors.reset) {
console.log(`${color}${message}${colors.reset}`)
}
// Helper function to log section headers
function logSection(title) {
console.log('\n' + '='.repeat(80))
console.log(`${colors.bright}${colors.cyan}${title}${colors.reset}`)
console.log('='.repeat(80) + '\n')
}
// Helper function to log subsection headers
function logSubSection(title) {
console.log('\n' + '-'.repeat(60))
console.log(`${colors.bright}${colors.magenta}${title}${colors.reset}`)
console.log('-'.repeat(60) + '\n')
}
// Helper function to run a command and return its output
function runCommand(command, cwd = rootDir) {
try {
return execSync(command, { stdio: 'pipe', cwd, encoding: 'utf8' })
} catch (error) {
log(`Error running command: ${command}`, colors.red)
log(error.message, colors.red)
if (error.stdout) log(`stdout: ${error.stdout}`)
if (error.stderr) log(`stderr: ${error.stderr}`, colors.red)
throw error
}
}
// Create a simple HTML file for browser testing
function createBrowserTestFile() {
const testHtmlPath = path.join(rootDir, 'browser-test.html')
const htmlContent = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@soulcraft/brainy Browser Test</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
line-height: 1.6;
}
h1 {
color: #333;
border-bottom: 2px solid #eee;
padding-bottom: 10px;
}
button {
background-color: #4CAF50;
border: none;
color: white;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 10px 2px;
cursor: pointer;
border-radius: 4px;
}
#result {
background-color: #f5f5f5;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin-top: 20px;
white-space: pre-wrap;
overflow-x: auto;
}
.success {
color: green;
font-weight: bold;
}
.error {
color: red;
font-weight: bold;
}
</style>
</head>
<body>
<h1>@soulcraft/brainy Browser Test</h1>
<p>This page tests the @soulcraft/brainy library in a browser environment.</p>
<button id="runTest">Run Test</button>
<div id="result">Test results will appear here...</div>
<script type="module">
// Import the library
import * as brainy from './dist/unified.js';
document.getElementById('runTest').addEventListener('click', async () => {
const resultElement = document.getElementById('result');
resultElement.innerHTML = 'Running tests...';
try {
// Test environment detection
const results = [];
results.push(\`Environment Detection:\`);
results.push(\`- isBrowser: \${brainy.isBrowser()}\`);
results.push(\`- isNode: \${brainy.isNode()}\`);
results.push(\`- isWebWorker: \${brainy.isWebWorker()}\`);
results.push(\`- areWebWorkersAvailable: \${brainy.areWebWorkersAvailable()}\`);
results.push(\`- isThreadingAvailable: \${brainy.isThreadingAvailable()}\`);
// Test TensorFlow functionality
results.push(\`\nTesting TensorFlow functionality...\`);
// Create a simple BrainyData instance
const data = new brainy.BrainyData({
dimensions: 2,
metric: 'euclidean'
});
results.push(\`Successfully created BrainyData instance\`);
// Initialize the database
results.push(\`Initializing database...\`);
await data.init();
// Add a simple vector
await data.add([1, 2], { id: 'test1', text: 'Test item' });
results.push(\`Successfully added item to BrainyData\`);
// Search for similar vectors
const searchResults = await data.search([1, 2], 1);
results.push(\`Search results: \${JSON.stringify(searchResults)}\`);
// Test embedding functionality (which uses TensorFlow)
results.push(\`\nTesting embedding functionality...\`);
try {
const embeddingFunction = brainy.createEmbeddingFunction();
const embedding = await embeddingFunction('This is a test sentence');
results.push(\`Successfully created embedding with length: \${embedding.length}\`);
} catch (embeddingError) {
results.push(\`Error testing embedding: \${embeddingError.message}\`);
throw embeddingError;
}
results.push(\`\n<span class="success">✅ All tests passed successfully!</span>\`);
resultElement.innerHTML = results.join('<br>');
} catch (error) {
resultElement.innerHTML = \`<span class="error">❌ Test failed:</span><br>\${error.message}\`;
console.error('Test error:', error);
}
});
</script>
</body>
</html>
`;
fs.writeFileSync(testHtmlPath, htmlContent);
return testHtmlPath;
}
// Create a Node.js test script
function createNodeTestScript() {
const testScriptPath = path.join(rootDir, 'node-test.js');
const scriptContent = `
// Node.js test script for @soulcraft/brainy
// CRITICAL: First, directly apply the TensorFlow.js patch
// This is the most reliable way to ensure the patch is applied before TensorFlow.js is loaded
import { TextEncoder, TextDecoder } from 'util';
// Make TextEncoder and TextDecoder available globally
if (typeof global !== 'undefined') {
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
}
// Import the library
import * as brainy from './dist/unified.js';
async function runNodeTest() {
console.log('\\n=== Testing @soulcraft/brainy in Node.js environment ===\\n');
try {
// Test environment detection
console.log('Environment Detection:');
console.log(\`- isBrowser: \${brainy.isBrowser()}\`);
console.log(\`- isNode: \${brainy.isNode()}\`);
console.log(\`- isWebWorker: \${brainy.isWebWorker()}\`);
console.log(\`- areWebWorkersAvailable: \${brainy.areWebWorkersAvailable()}\`);
console.log(\`- isThreadingAvailable: \${brainy.isThreadingAvailable()}\`);
console.log(\`- areWorkerThreadsAvailableSync: \${brainy.areWorkerThreadsAvailableSync()}\`);
// Test TensorFlow functionality
console.log('\\nTesting TensorFlow functionality...');
// Create a simple BrainyData instance
const data = new brainy.BrainyData({
dimensions: 2,
metric: 'euclidean'
});
console.log('Successfully created BrainyData instance');
// Initialize the database
console.log('Initializing database...');
await data.init();
// Add a simple vector
await data.add([1, 2], { id: 'test1', text: 'Test item' });
console.log('Successfully added item to BrainyData');
// Search for similar vectors
const results = await data.search([1, 2], 1);
console.log('Search results:', results);
// Test embedding functionality (which uses TensorFlow)
console.log('\\nTesting embedding functionality...');
const embeddingFunction = brainy.createEmbeddingFunction();
const embedding = await embeddingFunction('This is a test sentence');
console.log(\`Successfully created embedding with length: \${embedding.length}\`);
console.log('\\n✅ All Node.js tests passed successfully!');
return true;
} catch (error) {
console.error('❌ Node.js test failed:', error);
return false;
}
}
// Run the test
runNodeTest().then(success => {
if (!success) {
process.exit(1);
}
});
`;
fs.writeFileSync(testScriptPath, scriptContent);
return testScriptPath;
}
// Create a CLI test script
function createCliTestScript() {
const cliTestScriptPath = path.join(rootDir, 'cli-test.js');
const scriptContent = `
// CLI test script for @soulcraft/brainy-cli
import { execSync } from 'child_process';
function runCommand(command) {
try {
return execSync(command, { stdio: 'pipe', encoding: 'utf8' });
} catch (error) {
console.error(\`Error running command: \${command}\`);
console.error(error.message);
if (error.stdout) console.log(\`stdout: \${error.stdout}\`);
if (error.stderr) console.error(\`stderr: \${error.stderr}\`);
throw error;
}
}
async function testCli() {
console.log('\\n=== Testing @soulcraft/brainy-cli ===\\n');
try {
// Test CLI version
console.log('Testing CLI version...');
const versionOutput = runCommand('brainy --version');
console.log(\`CLI version: \${versionOutput.trim()}\`);
// Test CLI help
console.log('\\nTesting CLI help...');
runCommand('brainy --help');
console.log('Help command executed successfully');
// Test pipeline command
console.log('\\nTesting pipeline command...');
const pipelineOutput = runCommand('brainy test-pipeline "This is a test"');
console.log('Pipeline test completed successfully');
// Test TensorFlow functionality in CLI
console.log('\\nTesting TensorFlow functionality in CLI...');
const tensorflowOutput = runCommand('brainy test-tensorflow');
console.log('TensorFlow test completed successfully');
console.log('\\n✅ All CLI tests passed successfully!');
return true;
} catch (error) {
console.error('❌ CLI test failed. This might be expected if you don\\'t have the CLI installed globally.');
console.error('You can install the CLI globally with: npm run test:cli');
return false;
}
}
// Run the test
testCli().catch(error => {
console.error('Unhandled error:', error);
});
`;
fs.writeFileSync(cliTestScriptPath, scriptContent);
return cliTestScriptPath;
}
// Main function to run all tests
async function runComprehensiveTests() {
try {
logSection('COMPREHENSIVE TEST SUITE FOR @soulcraft/brainy');
log('This test suite verifies the library in all environments: Browser, Node.js, and CLI', colors.yellow);
logSection('BUILDING PACKAGES');
// Build the main package
logSubSection('Building Main Package');
log('Building main package...', colors.yellow);
runCommand('npm run build');
log('Main package built successfully!', colors.green);
// Build the browser package
logSubSection('Building Browser Package');
log('Building browser package...', colors.yellow);
runCommand('npm run build:browser');
log('Browser package built successfully!', colors.green);
// Build the CLI package
logSubSection('Building CLI Package');
log('Building CLI package...', colors.yellow);
runCommand('npm run build:cli');
log('CLI package built successfully!', colors.green);
logSection('NODE.JS ENVIRONMENT TESTS');
// Create and run Node.js test script
logSubSection('Creating Node.js Test Script');
const nodeTestScript = createNodeTestScript();
log(`Node.js test script created at: ${nodeTestScript}`, colors.green);
logSubSection('Running Node.js Tests');
try {
const nodeTestResult = runCommand(`node ${nodeTestScript}`);
log(nodeTestResult);
log('Node.js tests completed successfully!', colors.green);
} catch (error) {
log('Node.js tests failed!', colors.red);
throw error;
}
logSection('BROWSER ENVIRONMENT TESTS');
// Create browser test file
logSubSection('Creating Browser Test File');
const browserTestFile = createBrowserTestFile();
log(`Browser test file created at: ${browserTestFile}`, colors.green);
// Start a simple HTTP server to serve the test files
logSubSection('Starting HTTP Server');
const server = http.createServer((req, res) => {
// Normalize the URL to handle relative paths
const normalizedUrl = req.url.replace(/^\/+/, '/');
let filePath = path.join(
rootDir,
normalizedUrl === '/' ? 'browser-test.html' : normalizedUrl
);
// Handle relative paths (e.g., ../dist/unified.js)
if (normalizedUrl.includes('../')) {
// Convert the URL to an absolute path relative to the root directory
const parts = normalizedUrl.split('/');
const resolvedParts = [];
for (const part of parts) {
if (part === '..') {
resolvedParts.pop();
} else if (part && part !== '.') {
resolvedParts.push(part);
}
}
filePath = path.join(rootDir, resolvedParts.join('/'));
}
log(`Request for: ${req.url}, resolved to: ${filePath}`, colors.blue);
// Check if the file exists
if (fs.existsSync(filePath)) {
const extname = path.extname(filePath);
let contentType = 'text/html';
switch (extname) {
case '.js':
contentType = 'text/javascript';
break;
case '.css':
contentType = 'text/css';
break;
case '.json':
contentType = 'application/json';
break;
case '.png':
contentType = 'image/png';
break;
case '.jpg':
contentType = 'image/jpg';
break;
}
res.writeHead(200, { 'Content-Type': contentType });
const fileStream = fs.createReadStream(filePath);
fileStream.pipe(res);
} else {
log(`File not found: ${filePath}`, colors.red);
res.writeHead(404);
res.end('File not found');
}
});
// Start the server on a random port
const PORT = 3000 + Math.floor(Math.random() * 1000);
server.listen(PORT);
log(`HTTP server started on port ${PORT}`, colors.green);
// Run browser tests using Puppeteer
logSubSection('Running Browser Tests with Puppeteer');
log('Launching headless browser...', colors.yellow);
const browser = await puppeteer.launch({ args: ['--no-sandbox'] });
const page = await browser.newPage();
// Capture console logs from the page
page.on('console', (message) => {
const type = message.type();
const text = message.text();
if (type === 'error') {
log(`Browser console error: ${text}`, colors.red);
} else {
log(`Browser console: ${text}`, colors.blue);
}
});
// Navigate to the test page
log('Navigating to browser test page...', colors.yellow);
await page.goto(`http://localhost:${PORT}/browser-test.html`);
// Run the test
log('Running browser tests...', colors.yellow);
await page.waitForSelector('#runTest');
await page.click('#runTest');
// Wait for test completion
await page.waitForFunction(
() => {
const resultText = document.getElementById('result').textContent;
return resultText.includes('All tests passed') || resultText.includes('Test failed');
},
{ timeout: 60000 }
);
// Get test results
const browserTestResult = await page.evaluate(() => {
return document.getElementById('result').innerHTML;
});
log('Browser test results:', colors.green);
log(browserTestResult.replace(/<[^>]*>/g, '').trim());
// Check if the test passed
const browserTestPassed = browserTestResult.includes('All tests passed');
if (!browserTestPassed) {
throw new Error('Browser tests failed!');
}
// Close the browser and server
await browser.close();
server.close();
log('HTTP server stopped', colors.green);
logSection('CLI ENVIRONMENT TESTS');
// Create and run CLI test script
logSubSection('Creating CLI Test Script');
const cliTestScript = createCliTestScript();
log(`CLI test script created at: ${cliTestScript}`, colors.green);
logSubSection('Installing CLI Package Locally');
log('Installing CLI package locally for testing...', colors.yellow);
try {
runCommand('npm run test:cli');
log('CLI package installed successfully!', colors.green);
logSubSection('Running CLI Tests');
try {
const cliTestResult = runCommand(`node ${cliTestScript}`);
log(cliTestResult);
log('CLI tests completed!', colors.green);
} catch (error) {
log('CLI tests failed. This might be expected if you don\'t have the CLI installed globally.', colors.yellow);
log('You can install the CLI globally with: npm run test:cli', colors.yellow);
}
} catch (error) {
log('Failed to install CLI package locally. Skipping CLI tests.', colors.yellow);
log('You can run the CLI tests separately with: npm run test:cli', colors.yellow);
}
logSection('CLEANING UP');
// Clean up test files
log('Cleaning up test files...', colors.yellow);
fs.unlinkSync(nodeTestScript);
fs.unlinkSync(browserTestFile);
fs.unlinkSync(cliTestScript);
log('Test files removed', colors.green);
logSection('TEST SUMMARY');
log('✅ All environment tests completed successfully!', colors.green);
log('The library has been tested in the following environments:', colors.green);
log('- Browser environment', colors.green);
log('- Node.js/server environment', colors.green);
log('- CLI environment', colors.green);
log('\nTensorFlow functionality has been verified in all environments.', colors.green);
log('Environment detection has been tested and is working correctly.', colors.green);
} catch (error) {
logSection('TEST FAILURE');
log(`Tests failed: ${error.message}`, colors.red);
process.exit(1);
}
}
// Run the tests
runComprehensiveTests().catch((error) => {
log(`Unhandled error: ${error.message}`, colors.red);
process.exit(1);
});

View file

@ -1,130 +0,0 @@
#!/usr/bin/env node
/**
* Test CLI Package Locally
*
* This script allows testing the CLI package locally before publishing to npm.
* It builds both packages, creates local tarballs, and installs the CLI package
* globally for testing.
*/
import { execSync } from 'child_process'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
// Get the directory of the current module
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const rootDir = path.join(__dirname, '..')
const cliPackageDir = path.join(rootDir, 'cli-package')
// Ensure the CLI package directory exists
if (!fs.existsSync(cliPackageDir)) {
console.error(`Error: CLI package directory not found at ${cliPackageDir}`)
process.exit(1)
}
try {
// Step 1: Ensure versions are in sync
console.log('Ensuring versions are in sync...')
execSync('node scripts/generate-version.js', {
stdio: 'inherit',
cwd: rootDir
})
// Step 2: Build the main package
console.log('Building main package...')
execSync('npm run build', { stdio: 'inherit', cwd: rootDir })
// Step 3: Create a local tarball of the main package
console.log('Creating local tarball of main package...')
execSync('npm pack', { stdio: 'inherit', cwd: rootDir })
// Read the main package.json to get the name and version
const mainPackageJsonPath = path.join(rootDir, 'package.json')
const mainPackageJson = JSON.parse(
fs.readFileSync(mainPackageJsonPath, 'utf8')
)
// The tarball name follows a standard format: <package-name>-<version>.tgz
const mainPackageName = mainPackageJson.name
.replace('@', '')
.replace('/', '-')
const mainPackageVersion = mainPackageJson.version
const mainTarballName = `${mainPackageName}-${mainPackageVersion}.tgz`
const mainPackageTarball = path.join(rootDir, mainTarballName)
// Verify the tarball exists
if (!fs.existsSync(mainPackageTarball)) {
console.error(
`Error: Main package tarball not found at ${mainPackageTarball}`
)
process.exit(1)
}
console.log(`Main package tarball created: ${mainPackageTarball}`)
// Step 4: Build the CLI package
console.log('Building CLI package...')
execSync('npm run build', { stdio: 'inherit', cwd: cliPackageDir })
// Step 5: Verify the CLI was built successfully
const cliPath = path.join(cliPackageDir, 'dist', 'cli.js')
if (!fs.existsSync(cliPath)) {
console.error(`Error: CLI build failed. File not found at ${cliPath}`)
process.exit(1)
}
// Step 6: Temporarily update the CLI package.json to use the local main package
console.log('Updating CLI package.json to use local main package...')
const cliPackageJsonPath = path.join(cliPackageDir, 'package.json')
const cliPackageJson = JSON.parse(fs.readFileSync(cliPackageJsonPath, 'utf8'))
// Save the original dependency for restoration later
const originalDependency = cliPackageJson.dependencies['@soulcraft/brainy']
// Update to use the local tarball
cliPackageJson.dependencies['@soulcraft/brainy'] =
`file:${mainPackageTarball}`
// Write the updated package.json
fs.writeFileSync(cliPackageJsonPath, JSON.stringify(cliPackageJson, null, 2))
// Step 7: Create a local tarball of the CLI package
console.log('Creating local tarball of CLI package...')
execSync('npm pack', { stdio: 'inherit', cwd: cliPackageDir })
// The tarball name follows a standard format: <package-name>-<version>.tgz
const cliPackageName = cliPackageJson.name.replace('@', '').replace('/', '-')
const cliPackageVersion = cliPackageJson.version
const cliTarballName = `${cliPackageName}-${cliPackageVersion}.tgz`
const cliPackageTarball = path.join(cliPackageDir, cliTarballName)
// Verify the tarball exists
if (!fs.existsSync(cliPackageTarball)) {
console.error(
`Error: CLI package tarball not found at ${cliPackageTarball}`
)
process.exit(1)
}
console.log(`CLI package tarball created: ${cliPackageTarball}`)
// Step 8: Install the CLI package globally for testing
console.log('Installing CLI package globally for testing...')
execSync(`npm install -g "${cliPackageTarball}"`, { stdio: 'inherit' })
// Step 9: Restore the original dependency in CLI package.json
console.log('Restoring original dependency in CLI package.json...')
cliPackageJson.dependencies['@soulcraft/brainy'] = originalDependency
fs.writeFileSync(cliPackageJsonPath, JSON.stringify(cliPackageJson, null, 2))
console.log('\nCLI package installed globally for testing!')
console.log('You can now run the CLI using the "brainy" command.')
console.log('\nTo uninstall after testing:')
console.log('npm uninstall -g @soulcraft/brainy-cli')
} catch (error) {
console.error('Error:', error.message)
process.exit(1)
}