refactor: consolidate all Node.js development into lib package

- Move scripts/ to lib/scripts/ and convert to ESM modules
- Consolidate dependencies: add live-server to lib/package.json
- Remove root package.json and node_modules split
- Preserve CLI integration via existing rebuild-library.sh
- Add development quickstart guide for new unified workflow
- Clean up outdated file references and duplicate assets
This commit is contained in:
2025-09-04 21:40:45 +02:00
parent 6fef293df3
commit c777fc92dd
18 changed files with 2539 additions and 2769 deletions

39
DEVELOPMENT_QUICKSTART.md Normal file
View File

@@ -0,0 +1,39 @@
# Insertr Development Quickstart
## Project Structure
- `lib/` - JavaScript library development (all Node.js tooling)
- `insertr-cli/` - Go CLI application
- `demo-site/` - Static HTML demo site
## Getting Started
### Library Development
```bash
cd lib/
npm install
npm run serve # Start development server
npm run check # Validate setup
npm run demo # Show demo instructions
```
### CLI Development
```bash
cd insertr-cli/
air # Hot reload development server
```
### Build Everything
```bash
cd lib/
npm run build:all # Builds library + CLI with embedded assets
```
## Architecture
The CLI embeds the JavaScript library at build time for distribution. During development:
- `lib/` contains the JavaScript library source and build tools
- Air (Go hot reload) watches `lib/src/` and rebuilds when library changes
- Demo site served from `lib/` package for unified development experience
All Node.js dependencies and scripts are now consolidated in the `lib/` package.

View File

@@ -100,6 +100,9 @@ Bring the current library (`lib/`) up to feature parity with the archived protot
- [ ] Adaptive modal sizing and positioning - [ ] Adaptive modal sizing and positioning
- [ ] Touch-optimized hover states - [ ] Touch-optimized hover states
#### 3.3 Server / CLI
- [ ] A better way to inject insertr.js library into our CLI. Maybe use a cdn when library is stable.
## Key Files to Port/Adapt ## Key Files to Port/Adapt
### From Prototype (`demo-site/archive/insertr-old/`) ### From Prototype (`demo-site/archive/insertr-old/`)

View File

@@ -1,197 +0,0 @@
var Insertr = (function () {
'use strict';
/**
* InsertrCore - Core functionality for content management
*/
class InsertrCore {
constructor(options = {}) {
this.options = {
apiEndpoint: options.apiEndpoint || '/api/content',
siteId: options.siteId || 'default',
...options
};
}
// Find all enhanced elements on the page
findEnhancedElements() {
return document.querySelectorAll('[data-insertr-enhanced="true"]');
}
// Get element metadata
getElementMetadata(element) {
return {
contentId: element.getAttribute('data-content-id'),
contentType: element.getAttribute('data-content-type'),
element: element
};
}
// Get all elements with their metadata
getAllElements() {
const elements = this.findEnhancedElements();
return Array.from(elements).map(el => this.getElementMetadata(el));
}
}
/**
* InsertrEditor - Visual editing functionality
*/
class InsertrEditor {
constructor(core, options = {}) {
this.core = core;
this.options = options;
this.isActive = false;
}
start() {
if (this.isActive) return;
console.log('🚀 Starting Insertr Editor');
this.isActive = true;
// Add editor styles
this.addEditorStyles();
// Initialize all enhanced elements
const elements = this.core.getAllElements();
console.log(`📝 Found ${elements.length} editable elements`);
elements.forEach(meta => this.initializeElement(meta));
}
initializeElement(meta) {
const { element, contentId, contentType } = meta;
// Add visual indicators
element.style.cursor = 'pointer';
element.style.position = 'relative';
// Add interaction handlers
this.addHoverEffects(element);
this.addClickHandler(element, meta);
}
addHoverEffects(element) {
element.addEventListener('mouseenter', () => {
element.classList.add('insertr-editing-hover');
});
element.addEventListener('mouseleave', () => {
element.classList.remove('insertr-editing-hover');
});
}
addClickHandler(element, meta) {
element.addEventListener('click', (e) => {
e.preventDefault();
this.openEditor(meta);
});
}
openEditor(meta) {
const { contentId, contentType, element } = meta;
const currentContent = element.textContent.trim();
// For now, use a simple prompt (will be replaced with proper modal)
const newContent = prompt(
`Edit ${contentType} content (ID: ${contentId}):`,
currentContent
);
if (newContent !== null && newContent !== currentContent) {
this.updateContent(meta, newContent);
}
}
updateContent(meta, newContent) {
const { element } = meta;
// Update the element content
element.textContent = newContent;
// TODO: Save to backend API
console.log(`💾 Content updated:`, meta.contentId, newContent);
}
addEditorStyles() {
const styles = `
.insertr-editing-hover {
outline: 2px dashed #007cba !important;
outline-offset: 2px !important;
background-color: rgba(0, 124, 186, 0.05) !important;
}
[data-insertr-enhanced="true"]:hover::after {
content: "✏️ " attr(data-content-type);
position: absolute;
top: -25px;
left: 0;
background: #007cba;
color: white;
padding: 2px 6px;
font-size: 11px;
border-radius: 3px;
white-space: nowrap;
z-index: 1000;
font-family: monospace;
}
`;
const styleSheet = document.createElement('style');
styleSheet.type = 'text/css';
styleSheet.innerHTML = styles;
document.head.appendChild(styleSheet);
}
}
/**
* Insertr - The Tailwind of CMS
* Main library entry point
*/
// Create global Insertr instance
window.Insertr = {
// Core functionality
core: null,
editor: null,
// Initialize the library
init(options = {}) {
console.log('🔧 Insertr v1.0.0 initializing...');
this.core = new InsertrCore(options);
this.editor = new InsertrEditor(this.core, options);
// Auto-initialize if DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => this.start());
} else {
this.start();
}
return this;
},
// Start the editor
start() {
if (this.editor) {
this.editor.start();
}
},
// Version info
version: '1.0.0'
};
// Auto-initialize in development mode
if (document.querySelector('[data-insertr-enhanced]')) {
window.Insertr.init();
}
var index = window.Insertr;
return index;
})();

View File

@@ -1 +0,0 @@
var Insertr=function(){"use strict";class t{constructor(t={}){this.options={apiEndpoint:t.apiEndpoint||"/api/content",siteId:t.siteId||"default",...t}}findEnhancedElements(){return document.querySelectorAll('[data-insertr-enhanced="true"]')}getElementMetadata(t){return{contentId:t.getAttribute("data-content-id"),contentType:t.getAttribute("data-content-type"),element:t}}getAllElements(){const t=this.findEnhancedElements();return Array.from(t).map(t=>this.getElementMetadata(t))}}class e{constructor(t,e={}){this.core=t,this.options=e,this.isActive=!1}start(){if(this.isActive)return;console.log("🚀 Starting Insertr Editor"),this.isActive=!0,this.addEditorStyles();const t=this.core.getAllElements();console.log(`📝 Found ${t.length} editable elements`),t.forEach(t=>this.initializeElement(t))}initializeElement(t){const{element:e,contentId:n,contentType:i}=t;e.style.cursor="pointer",e.style.position="relative",this.addHoverEffects(e),this.addClickHandler(e,t)}addHoverEffects(t){t.addEventListener("mouseenter",()=>{t.classList.add("insertr-editing-hover")}),t.addEventListener("mouseleave",()=>{t.classList.remove("insertr-editing-hover")})}addClickHandler(t,e){t.addEventListener("click",t=>{t.preventDefault(),this.openEditor(e)})}openEditor(t){const{contentId:e,contentType:n,element:i}=t,o=i.textContent.trim(),r=prompt(`Edit ${n} content (ID: ${e}):`,o);null!==r&&r!==o&&this.updateContent(t,r)}updateContent(t,e){const{element:n}=t;n.textContent=e,console.log("💾 Content updated:",t.contentId,e)}addEditorStyles(){const t=document.createElement("style");t.type="text/css",t.innerHTML='\n .insertr-editing-hover {\n outline: 2px dashed #007cba !important;\n outline-offset: 2px !important;\n background-color: rgba(0, 124, 186, 0.05) !important;\n }\n \n [data-insertr-enhanced="true"]:hover::after {\n content: "✏️ " attr(data-content-type);\n position: absolute;\n top: -25px;\n left: 0;\n background: #007cba;\n color: white;\n padding: 2px 6px;\n font-size: 11px;\n border-radius: 3px;\n white-space: nowrap;\n z-index: 1000;\n font-family: monospace;\n }\n ',document.head.appendChild(t)}}return window.Insertr={core:null,editor:null,init(n={}){return console.log("🔧 Insertr v1.0.0 initializing..."),this.core=new t(n),this.editor=new e(this.core,n),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>this.start()):this.start(),this},start(){this.editor&&this.editor.start()},version:"1.0.0"},document.querySelector("[data-insertr-enhanced]")&&window.Insertr.init(),window.Insertr}();

View File

@@ -15,7 +15,7 @@ var Insertr = (function () {
// Find all enhanced elements on the page // Find all enhanced elements on the page
findEnhancedElements() { findEnhancedElements() {
return document.querySelectorAll('[data-insertr-enhanced="true"]'); return document.querySelectorAll('.insertr');
} }
// Get element metadata // Get element metadata
@@ -608,7 +608,7 @@ var Insertr = (function () {
background-color: rgba(0, 124, 186, 0.05) !important; background-color: rgba(0, 124, 186, 0.05) !important;
} }
[data-insertr-enhanced="true"]:hover::after { .insertr:hover::after {
content: "✏️ " attr(data-content-type); content: "✏️ " attr(data-content-type);
position: absolute; position: absolute;
top: -25px; top: -25px;
@@ -1142,16 +1142,16 @@ var Insertr = (function () {
} }
/* Hide editing interface when not in edit mode */ /* Hide editing interface when not in edit mode */
body:not(.insertr-edit-mode) [data-insertr-enhanced]:hover::after { body:not(.insertr-edit-mode) .insertr:hover::after {
display: none !important; display: none !important;
} }
/* Only show editing features when in edit mode */ /* Only show editing features when in edit mode */
.insertr-authenticated.insertr-edit-mode [data-insertr-enhanced] { .insertr-authenticated.insertr-edit-mode .insertr {
cursor: pointer; cursor: pointer;
} }
.insertr-authenticated.insertr-edit-mode [data-insertr-enhanced]:hover { .insertr-authenticated.insertr-edit-mode .insertr:hover {
outline: 2px dashed #007cba !important; outline: 2px dashed #007cba !important;
outline-offset: 2px !important; outline-offset: 2px !important;
background-color: rgba(0, 124, 186, 0.05) !important; background-color: rgba(0, 124, 186, 0.05) !important;
@@ -1260,13 +1260,12 @@ var Insertr = (function () {
return this.auth ? this.auth.isEditMode() : false; return this.auth ? this.auth.isEditMode() : false;
}, },
// Version info // TODO: Version info based on package.json?
version: '1.0.0'
}; };
// Auto-initialize in development mode with proper DOM ready handling // Auto-initialize in development mode with proper DOM ready handling
function autoInitialize() { function autoInitialize() {
if (document.querySelector('[data-insertr-enhanced="true"]')) { if (document.querySelector('.insertr')) {
window.Insertr.init(); window.Insertr.init();
} }
} }

File diff suppressed because one or more lines are too long

View File

@@ -126,11 +126,11 @@ func (i *Injector) injectLinkContent(node *html.Node, content string) {
i.injectTextContent(node, content) i.injectTextContent(node, content)
} }
// addContentAttributes adds necessary data attributes for editor functionality // addContentAttributes adds necessary data attributes and insertr class for editor functionality
func (i *Injector) addContentAttributes(node *html.Node, contentID string, contentType string) { func (i *Injector) addContentAttributes(node *html.Node, contentID string, contentType string) {
i.setAttribute(node, "data-content-id", contentID) i.setAttribute(node, "data-content-id", contentID)
i.setAttribute(node, "data-content-type", contentType) i.setAttribute(node, "data-content-type", contentType)
i.setAttribute(node, "data-insertr-enhanced", "true") i.addClass(node, "insertr")
} }
// InjectEditorAssets adds editor JavaScript and CSS to HTML document // InjectEditorAssets adds editor JavaScript and CSS to HTML document
@@ -193,6 +193,48 @@ func (i *Injector) setAttribute(node *html.Node, key, value string) {
}) })
} }
// addClass safely adds a class to an HTML node
func (i *Injector) addClass(node *html.Node, className string) {
var classAttr *html.Attribute
var classIndex int = -1
// Find existing class attribute
for idx, attr := range node.Attr {
if attr.Key == "class" {
classAttr = &attr
classIndex = idx
break
}
}
var classes []string
if classAttr != nil {
classes = strings.Fields(classAttr.Val)
}
// Check if class already exists
for _, class := range classes {
if class == className {
return // Class already exists
}
}
// Add new class
classes = append(classes, className)
newClassValue := strings.Join(classes, " ")
if classIndex >= 0 {
// Update existing class attribute
node.Attr[classIndex].Val = newClassValue
} else {
// Add new class attribute
node.Attr = append(node.Attr, html.Attribute{
Key: "class",
Val: newClassValue,
})
}
}
// Element represents a parsed HTML element with metadata // Element represents a parsed HTML element with metadata
type Element struct { type Element struct {
Node *html.Node Node *html.Node

2375
lib/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,12 @@
"scripts": { "scripts": {
"build": "rollup -c", "build": "rollup -c",
"watch": "rollup -c -w", "watch": "rollup -c -w",
"dev": "rollup -c -w" "dev": "rollup -c -w",
"serve": "node scripts/dev.js serve",
"serve:about": "live-server ../demo-site --port=3000 --open=/about.html",
"check": "node scripts/dev.js check",
"demo": "node scripts/dev.js demo",
"build:all": "node scripts/build.js"
}, },
"keywords": [ "keywords": [
"cms", "cms",
@@ -25,6 +30,7 @@
"devDependencies": { "devDependencies": {
"@rollup/plugin-node-resolve": "^15.0.0", "@rollup/plugin-node-resolve": "^15.0.0",
"@rollup/plugin-terser": "^0.4.0", "@rollup/plugin-terser": "^0.4.0",
"rollup": "^3.0.0" "rollup": "^3.0.0",
"live-server": "^1.2.2"
} }
} }

View File

@@ -5,16 +5,16 @@
* This ensures the CLI always has the latest library version embedded * This ensures the CLI always has the latest library version embedded
*/ */
const { execSync } = require('child_process'); import { execSync } from 'child_process';
const fs = require('fs'); import fs from 'fs';
const path = require('path'); import path from 'path';
console.log('🔨 Building Insertr library and CLI...\n'); console.log('🔨 Building Insertr library and CLI...\n');
// 1. Build the library // 1. Build the library
console.log('📦 Building JavaScript library...'); console.log('📦 Building JavaScript library...');
try { try {
execSync('npm run build', { cwd: './lib', stdio: 'inherit' }); execSync('npm run build', { stdio: 'inherit' });
console.log('✅ Library built successfully\n'); console.log('✅ Library built successfully\n');
} catch (error) { } catch (error) {
console.error('❌ Library build failed:', error.message); console.error('❌ Library build failed:', error.message);
@@ -23,8 +23,8 @@ try {
// 2. Copy built library to CLI assets // 2. Copy built library to CLI assets
console.log('📁 Copying library to CLI assets...'); console.log('📁 Copying library to CLI assets...');
const srcDir = './lib/dist'; const srcDir = './dist';
const destDir = './insertr-cli/pkg/content/assets'; const destDir = '../insertr-cli/pkg/content/assets';
// Ensure destination directory exists // Ensure destination directory exists
fs.mkdirSync(destDir, { recursive: true }); fs.mkdirSync(destDir, { recursive: true });
@@ -43,7 +43,7 @@ console.log('📁 Assets copied successfully\n');
// 3. Build the CLI // 3. Build the CLI
console.log('🔧 Building Go CLI...'); console.log('🔧 Building Go CLI...');
try { try {
execSync('go build -o insertr', { cwd: './insertr-cli', stdio: 'inherit' }); execSync('go build -o insertr', { cwd: '../insertr-cli', stdio: 'inherit' });
console.log('✅ CLI built successfully\n'); console.log('✅ CLI built successfully\n');
} catch (error) { } catch (error) {
console.error('❌ CLI build failed:', error.message); console.error('❌ CLI build failed:', error.message);
@@ -55,4 +55,4 @@ console.log('📋 What was built:');
console.log(' • JavaScript library (lib/dist/)'); console.log(' • JavaScript library (lib/dist/)');
console.log(' • Go CLI with embedded library (insertr-cli/insertr)'); console.log(' • Go CLI with embedded library (insertr-cli/insertr)');
console.log('\n🚀 Ready to use:'); console.log('\n🚀 Ready to use:');
console.log(' cd insertr-cli && ./insertr --help'); console.log(' cd ../insertr-cli && ./insertr --help');

View File

@@ -5,9 +5,9 @@
* Provides common development tasks and utilities * Provides common development tasks and utilities
*/ */
const { execSync, spawn } = require('child_process'); import { execSync, spawn } from 'child_process';
const fs = require('fs'); import fs from 'fs';
const path = require('path'); import path from 'path';
const commands = { const commands = {
serve: { serve: {
@@ -21,7 +21,7 @@ const commands = {
console.log(' ✏️ Client: Click "Login as Client" → "Edit Mode: On"'); console.log(' ✏️ Client: Click "Login as Client" → "Edit Mode: On"');
console.log(' 🔧 Developer: View source to see integration\n'); console.log(' 🔧 Developer: View source to see integration\n');
spawn('npx', ['live-server', 'demo-site', '--port=3000', '--open=/index.html'], { spawn('npx', ['live-server', '../demo-site', '--port=3000', '--open=/index.html'], {
stdio: 'inherit' stdio: 'inherit'
}); });
} }
@@ -33,13 +33,13 @@ const commands = {
console.log('🔍 Checking Insertr project status...\n'); console.log('🔍 Checking Insertr project status...\n');
// Check files exist // Check files exist
const requiredFiles = [ const requiredFiles = [
'demo-site/index.html', '../demo-site/index.html',
'demo-site/about.html', '../demo-site/about.html',
'demo-site/insertr/insertr.js', 'dist/insertr.js',
'demo-site/insertr/insertr.css', 'dist/insertr.min.js',
'package.json' 'package.json'
]; ];
let allGood = true; let allGood = true;
@@ -56,17 +56,17 @@ const commands = {
console.log('\n🎉 All core files present!'); console.log('\n🎉 All core files present!');
console.log('\n📊 Project stats:'); console.log('\n📊 Project stats:');
// Count editable elements // Count editable elements
const indexContent = fs.readFileSync('demo-site/index.html', 'utf8'); const indexContent = fs.readFileSync('../demo-site/index.html', 'utf8');
const aboutContent = fs.readFileSync('demo-site/about.html', 'utf8'); const aboutContent = fs.readFileSync('../demo-site/about.html', 'utf8');
const insertrMatches = (indexContent + aboutContent).match(/class="insertr"/g) || []; const insertrMatches = (indexContent + aboutContent).match(/class="insertr"/g) || [];
console.log(` 📝 Editable elements: ${insertrMatches.length}`); console.log(` 📝 Editable elements: ${insertrMatches.length}`);
// Check library size // Check library size
const libSize = fs.statSync('demo-site/insertr/insertr.js').size; const libSize = fs.statSync('dist/insertr.js').size;
console.log(` 📦 Library size: ${(libSize / 1024).toFixed(1)}KB`); console.log(` 📦 Library size: ${(libSize / 1024).toFixed(1)}KB`);
console.log('\n🚀 Ready to develop! Run: npm run dev'); console.log('\n🚀 Ready to develop! Run: npm run serve');
} else { } else {
console.log('\n❌ Some files are missing. Please check your setup.'); console.log('\n❌ Some files are missing. Please check your setup.');
process.exit(1); process.exit(1);
@@ -78,7 +78,7 @@ const commands = {
description: 'Show demo instructions', description: 'Show demo instructions',
action: () => { action: () => {
console.log('🎬 Insertr Demo Instructions\n'); console.log('🎬 Insertr Demo Instructions\n');
console.log('1. 🌐 Start server: npm run dev'); console.log('1. 🌐 Start server: npm run serve');
console.log('2. 👀 Customer view: Browse the site normally'); console.log('2. 👀 Customer view: Browse the site normally');
console.log('3. 🔑 Client login: Click "Login as Client"'); console.log('3. 🔑 Client login: Click "Login as Client"');
console.log('4. ✏️ Edit mode: Click "Edit Mode: Off" to enable editing'); console.log('4. ✏️ Edit mode: Click "Edit Mode: Off" to enable editing');
@@ -107,7 +107,7 @@ if (commands[command]) {
console.log(` ${name.padEnd(12)} ${cmd.description}`); console.log(` ${name.padEnd(12)} ${cmd.description}`);
}); });
console.log('\nUsage: node scripts/dev.js <command>'); console.log('\nUsage: node scripts/dev.js <command>');
console.log(' or: npm run dev:help\n'); console.log(' or: npm run check\n');
} else { } else {
console.log(`❌ Unknown command: ${command}`); console.log(`❌ Unknown command: ${command}`);
console.log('Run: node scripts/dev.js help'); console.log('Run: node scripts/dev.js help');

View File

@@ -509,16 +509,16 @@ export class InsertrAuth {
} }
/* Hide editing interface when not in edit mode */ /* Hide editing interface when not in edit mode */
body:not(.insertr-edit-mode) [data-insertr-enhanced]:hover::after { body:not(.insertr-edit-mode) .insertr:hover::after {
display: none !important; display: none !important;
} }
/* Only show editing features when in edit mode */ /* Only show editing features when in edit mode */
.insertr-authenticated.insertr-edit-mode [data-insertr-enhanced] { .insertr-authenticated.insertr-edit-mode .insertr {
cursor: pointer; cursor: pointer;
} }
.insertr-authenticated.insertr-edit-mode [data-insertr-enhanced]:hover { .insertr-authenticated.insertr-edit-mode .insertr:hover {
outline: 2px dashed #007cba !important; outline: 2px dashed #007cba !important;
outline-offset: 2px !important; outline-offset: 2px !important;
background-color: rgba(0, 124, 186, 0.05) !important; background-color: rgba(0, 124, 186, 0.05) !important;

View File

@@ -130,7 +130,7 @@ export class InsertrEditor {
background-color: rgba(0, 124, 186, 0.05) !important; background-color: rgba(0, 124, 186, 0.05) !important;
} }
[data-insertr-enhanced="true"]:hover::after { .insertr:hover::after {
content: "✏️ " attr(data-content-type); content: "✏️ " attr(data-content-type);
position: absolute; position: absolute;
top: -25px; top: -25px;

View File

@@ -12,7 +12,7 @@ export class InsertrCore {
// Find all enhanced elements on the page // Find all enhanced elements on the page
findEnhancedElements() { findEnhancedElements() {
return document.querySelectorAll('[data-insertr-enhanced="true"]'); return document.querySelectorAll('.insertr');
} }
// Get element metadata // Get element metadata

View File

@@ -71,13 +71,12 @@ window.Insertr = {
return this.auth ? this.auth.isEditMode() : false; return this.auth ? this.auth.isEditMode() : false;
}, },
// Version info // TODO: Version info based on package.json?
version: '1.0.0'
}; };
// Auto-initialize in development mode with proper DOM ready handling // Auto-initialize in development mode with proper DOM ready handling
function autoInitialize() { function autoInitialize() {
if (document.querySelector('[data-insertr-enhanced="true"]')) { if (document.querySelector('.insertr')) {
window.Insertr.init(); window.Insertr.init();
} }
} }

2403
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,46 +0,0 @@
{
"name": "insertr",
"version": "0.1.0",
"description": "The Tailwind of CMS - Zero-configuration content editing for any static site",
"main": "lib/dist/insertr.js",
"scripts": {
"dev": "node scripts/dev.js serve",
"dev:about": "live-server demo-site --port=3000 --open=/about.html",
"dev:check": "node scripts/dev.js check",
"dev:demo": "node scripts/dev.js demo",
"dev:help": "node scripts/dev.js help",
"build": "node scripts/build.js",
"test": "echo 'Test script placeholder - will add tests for insertr.js'",
"lint": "echo 'Linting placeholder - will add ESLint'",
"serve": "npm run dev",
"start": "npm run dev"
},
"keywords": [
"cms",
"headless-cms",
"static-site-generator",
"content-management",
"build-time-enhancement",
"zero-config",
"go",
"javascript"
],
"author": "Your Name",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/yourusername/insertr.git"
},
"devDependencies": {
"live-server": "^1.2.2"
},
"engines": {
"node": ">=16.0.0",
"npm": ">=8.0.0"
},
"browserslist": [
"defaults",
"not IE 11"
],
"dependencies": {}
}

View File

@@ -1,46 +0,0 @@
#!/bin/bash
# Test script to demonstrate Air hot reload functionality
# Shows how library changes automatically trigger CLI rebuild
echo "🧪 Testing Insertr Hot Reload Functionality"
echo "============================================"
cd insertr-cli
echo "1. Starting Air in background..."
air &
AIR_PID=$!
sleep 5
echo "2. Making a test change to the library..."
cd ../lib/src
# Make a test change
sed -i 's/Hot Reload Ready/Hot Reload TESTED/g' index.js
echo "3. Waiting for Air to detect change and rebuild..."
sleep 8
echo "4. Testing if the change was embedded in CLI..."
cd ../insertr-cli
if ./insertr enhance ../demo-site/ -o /tmp/test-output 2>/dev/null && grep -q "Hot Reload TESTED" /tmp/test-output/index.html; then
echo "✅ SUCCESS: Library change was automatically embedded in CLI!"
else
echo "❌ FAILED: Library change was not embedded"
fi
echo "5. Reverting test change..."
cd ../lib/src
sed -i 's/Hot Reload TESTED/Hot Reload Ready/g' index.js
echo "6. Stopping Air..."
kill $AIR_PID 2>/dev/null
wait $AIR_PID 2>/dev/null
echo ""
echo "🎉 Hot reload test completed!"
echo " Library changes automatically trigger:"
echo " • Library rebuild (npm run build)"
echo " • Asset copy to CLI"
echo " • CLI rebuild with embedded library"
echo " • Development server restart"