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:
39
DEVELOPMENT_QUICKSTART.md
Normal file
39
DEVELOPMENT_QUICKSTART.md
Normal 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.
|
||||
5
TODO.md
5
TODO.md
@@ -100,6 +100,9 @@ Bring the current library (`lib/`) up to feature parity with the archived protot
|
||||
- [ ] Adaptive modal sizing and positioning
|
||||
- [ ] 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
|
||||
|
||||
### From Prototype (`demo-site/archive/insertr-old/`)
|
||||
@@ -143,4 +146,4 @@ Keep the current library + CLI architecture while porting prototype features:
|
||||
|
||||
---
|
||||
|
||||
*This TODO represents bringing a basic proof-of-concept up to production-ready feature parity with the original prototype.*
|
||||
*This TODO represents bringing a basic proof-of-concept up to production-ready feature parity with the original prototype.*
|
||||
|
||||
@@ -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;
|
||||
|
||||
})();
|
||||
1
insertr-cli/assets/lib/insertr.min.js
vendored
1
insertr-cli/assets/lib/insertr.min.js
vendored
@@ -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}();
|
||||
@@ -15,7 +15,7 @@ var Insertr = (function () {
|
||||
|
||||
// Find all enhanced elements on the page
|
||||
findEnhancedElements() {
|
||||
return document.querySelectorAll('[data-insertr-enhanced="true"]');
|
||||
return document.querySelectorAll('.insertr');
|
||||
}
|
||||
|
||||
// Get element metadata
|
||||
@@ -608,7 +608,7 @@ var Insertr = (function () {
|
||||
background-color: rgba(0, 124, 186, 0.05) !important;
|
||||
}
|
||||
|
||||
[data-insertr-enhanced="true"]:hover::after {
|
||||
.insertr:hover::after {
|
||||
content: "✏️ " attr(data-content-type);
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
@@ -1142,16 +1142,16 @@ var Insertr = (function () {
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Only show editing features when in edit mode */
|
||||
.insertr-authenticated.insertr-edit-mode [data-insertr-enhanced] {
|
||||
.insertr-authenticated.insertr-edit-mode .insertr {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.insertr-authenticated.insertr-edit-mode [data-insertr-enhanced]:hover {
|
||||
.insertr-authenticated.insertr-edit-mode .insertr:hover {
|
||||
outline: 2px dashed #007cba !important;
|
||||
outline-offset: 2px !important;
|
||||
background-color: rgba(0, 124, 186, 0.05) !important;
|
||||
@@ -1203,25 +1203,25 @@ var Insertr = (function () {
|
||||
core: null,
|
||||
editor: null,
|
||||
auth: null,
|
||||
|
||||
|
||||
// Initialize the library
|
||||
init(options = {}) {
|
||||
console.log('🔧 Insertr v1.0.0 initializing... (Hot Reload Ready)');
|
||||
|
||||
|
||||
this.core = new InsertrCore(options);
|
||||
this.auth = new InsertrAuth(options);
|
||||
this.editor = new InsertrEditor(this.core, this.auth, options);
|
||||
|
||||
|
||||
// Auto-initialize if DOM is ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => this.start());
|
||||
} else {
|
||||
this.start();
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
// Start the system - only creates the minimal trigger
|
||||
start() {
|
||||
if (this.auth) {
|
||||
@@ -1236,37 +1236,36 @@ var Insertr = (function () {
|
||||
this.editor.start();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Public API methods
|
||||
login() {
|
||||
return this.auth ? this.auth.toggleAuthentication() : null;
|
||||
},
|
||||
|
||||
|
||||
logout() {
|
||||
if (this.auth && this.auth.isAuthenticated()) {
|
||||
this.auth.toggleAuthentication();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
toggleEditMode() {
|
||||
return this.auth ? this.auth.toggleEditMode() : null;
|
||||
},
|
||||
|
||||
|
||||
isAuthenticated() {
|
||||
return this.auth ? this.auth.isAuthenticated() : false;
|
||||
},
|
||||
|
||||
|
||||
isEditMode() {
|
||||
return this.auth ? this.auth.isEditMode() : false;
|
||||
},
|
||||
|
||||
// Version info
|
||||
version: '1.0.0'
|
||||
|
||||
// TODO: Version info based on package.json?
|
||||
};
|
||||
|
||||
// Auto-initialize in development mode with proper DOM ready handling
|
||||
function autoInitialize() {
|
||||
if (document.querySelector('[data-insertr-enhanced="true"]')) {
|
||||
if (document.querySelector('.insertr')) {
|
||||
window.Insertr.init();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -126,11 +126,11 @@ func (i *Injector) injectLinkContent(node *html.Node, content string) {
|
||||
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) {
|
||||
i.setAttribute(node, "data-content-id", contentID)
|
||||
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
|
||||
@@ -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
|
||||
type Element struct {
|
||||
Node *html.Node
|
||||
|
||||
2375
lib/package-lock.json
generated
2375
lib/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,12 @@
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"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": [
|
||||
"cms",
|
||||
@@ -25,6 +30,7 @@
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "^15.0.0",
|
||||
"@rollup/plugin-terser": "^0.4.0",
|
||||
"rollup": "^3.0.0"
|
||||
"rollup": "^3.0.0",
|
||||
"live-server": "^1.2.2"
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,16 @@
|
||||
* This ensures the CLI always has the latest library version embedded
|
||||
*/
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import { execSync } from 'child_process';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
console.log('🔨 Building Insertr library and CLI...\n');
|
||||
|
||||
// 1. Build the library
|
||||
console.log('📦 Building JavaScript library...');
|
||||
try {
|
||||
execSync('npm run build', { cwd: './lib', stdio: 'inherit' });
|
||||
execSync('npm run build', { stdio: 'inherit' });
|
||||
console.log('✅ Library built successfully\n');
|
||||
} catch (error) {
|
||||
console.error('❌ Library build failed:', error.message);
|
||||
@@ -23,8 +23,8 @@ try {
|
||||
|
||||
// 2. Copy built library to CLI assets
|
||||
console.log('📁 Copying library to CLI assets...');
|
||||
const srcDir = './lib/dist';
|
||||
const destDir = './insertr-cli/pkg/content/assets';
|
||||
const srcDir = './dist';
|
||||
const destDir = '../insertr-cli/pkg/content/assets';
|
||||
|
||||
// Ensure destination directory exists
|
||||
fs.mkdirSync(destDir, { recursive: true });
|
||||
@@ -43,7 +43,7 @@ console.log('📁 Assets copied successfully\n');
|
||||
// 3. Build the CLI
|
||||
console.log('🔧 Building Go CLI...');
|
||||
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');
|
||||
} catch (error) {
|
||||
console.error('❌ CLI build failed:', error.message);
|
||||
@@ -55,4 +55,4 @@ console.log('📋 What was built:');
|
||||
console.log(' • JavaScript library (lib/dist/)');
|
||||
console.log(' • Go CLI with embedded library (insertr-cli/insertr)');
|
||||
console.log('\n🚀 Ready to use:');
|
||||
console.log(' cd insertr-cli && ./insertr --help');
|
||||
console.log(' cd ../insertr-cli && ./insertr --help');
|
||||
@@ -5,9 +5,9 @@
|
||||
* Provides common development tasks and utilities
|
||||
*/
|
||||
|
||||
const { execSync, spawn } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import { execSync, spawn } from 'child_process';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const commands = {
|
||||
serve: {
|
||||
@@ -21,7 +21,7 @@ const commands = {
|
||||
console.log(' ✏️ Client: Click "Login as Client" → "Edit Mode: On"');
|
||||
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'
|
||||
});
|
||||
}
|
||||
@@ -33,13 +33,13 @@ const commands = {
|
||||
console.log('🔍 Checking Insertr project status...\n');
|
||||
|
||||
// Check files exist
|
||||
const requiredFiles = [
|
||||
'demo-site/index.html',
|
||||
'demo-site/about.html',
|
||||
'demo-site/insertr/insertr.js',
|
||||
'demo-site/insertr/insertr.css',
|
||||
'package.json'
|
||||
];
|
||||
const requiredFiles = [
|
||||
'../demo-site/index.html',
|
||||
'../demo-site/about.html',
|
||||
'dist/insertr.js',
|
||||
'dist/insertr.min.js',
|
||||
'package.json'
|
||||
];
|
||||
|
||||
let allGood = true;
|
||||
|
||||
@@ -56,17 +56,17 @@ const commands = {
|
||||
console.log('\n🎉 All core files present!');
|
||||
console.log('\n📊 Project stats:');
|
||||
|
||||
// Count editable elements
|
||||
const indexContent = fs.readFileSync('demo-site/index.html', 'utf8');
|
||||
const aboutContent = fs.readFileSync('demo-site/about.html', 'utf8');
|
||||
const insertrMatches = (indexContent + aboutContent).match(/class="insertr"/g) || [];
|
||||
console.log(` 📝 Editable elements: ${insertrMatches.length}`);
|
||||
// Count editable elements
|
||||
const indexContent = fs.readFileSync('../demo-site/index.html', 'utf8');
|
||||
const aboutContent = fs.readFileSync('../demo-site/about.html', 'utf8');
|
||||
const insertrMatches = (indexContent + aboutContent).match(/class="insertr"/g) || [];
|
||||
console.log(` 📝 Editable elements: ${insertrMatches.length}`);
|
||||
|
||||
// Check library size
|
||||
const libSize = fs.statSync('dist/insertr.js').size;
|
||||
console.log(` 📦 Library size: ${(libSize / 1024).toFixed(1)}KB`);
|
||||
|
||||
// Check library size
|
||||
const libSize = fs.statSync('demo-site/insertr/insertr.js').size;
|
||||
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 {
|
||||
console.log('\n❌ Some files are missing. Please check your setup.');
|
||||
process.exit(1);
|
||||
@@ -78,7 +78,7 @@ const commands = {
|
||||
description: 'Show demo instructions',
|
||||
action: () => {
|
||||
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('3. 🔑 Client login: Click "Login as Client"');
|
||||
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('\nUsage: node scripts/dev.js <command>');
|
||||
console.log(' or: npm run dev:help\n');
|
||||
console.log(' or: npm run check\n');
|
||||
} else {
|
||||
console.log(`❌ Unknown command: ${command}`);
|
||||
console.log('Run: node scripts/dev.js help');
|
||||
@@ -509,16 +509,16 @@ export class InsertrAuth {
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Only show editing features when in edit mode */
|
||||
.insertr-authenticated.insertr-edit-mode [data-insertr-enhanced] {
|
||||
.insertr-authenticated.insertr-edit-mode .insertr {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.insertr-authenticated.insertr-edit-mode [data-insertr-enhanced]:hover {
|
||||
.insertr-authenticated.insertr-edit-mode .insertr:hover {
|
||||
outline: 2px dashed #007cba !important;
|
||||
outline-offset: 2px !important;
|
||||
background-color: rgba(0, 124, 186, 0.05) !important;
|
||||
|
||||
@@ -130,7 +130,7 @@ export class InsertrEditor {
|
||||
background-color: rgba(0, 124, 186, 0.05) !important;
|
||||
}
|
||||
|
||||
[data-insertr-enhanced="true"]:hover::after {
|
||||
.insertr:hover::after {
|
||||
content: "✏️ " attr(data-content-type);
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
|
||||
@@ -12,7 +12,7 @@ export class InsertrCore {
|
||||
|
||||
// Find all enhanced elements on the page
|
||||
findEnhancedElements() {
|
||||
return document.querySelectorAll('[data-insertr-enhanced="true"]');
|
||||
return document.querySelectorAll('.insertr');
|
||||
}
|
||||
|
||||
// Get element metadata
|
||||
|
||||
@@ -14,25 +14,25 @@ window.Insertr = {
|
||||
core: null,
|
||||
editor: null,
|
||||
auth: null,
|
||||
|
||||
|
||||
// Initialize the library
|
||||
init(options = {}) {
|
||||
console.log('🔧 Insertr v1.0.0 initializing... (Hot Reload Ready)');
|
||||
|
||||
|
||||
this.core = new InsertrCore(options);
|
||||
this.auth = new InsertrAuth(options);
|
||||
this.editor = new InsertrEditor(this.core, this.auth, options);
|
||||
|
||||
|
||||
// Auto-initialize if DOM is ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => this.start());
|
||||
} else {
|
||||
this.start();
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
// Start the system - only creates the minimal trigger
|
||||
start() {
|
||||
if (this.auth) {
|
||||
@@ -47,37 +47,36 @@ window.Insertr = {
|
||||
this.editor.start();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Public API methods
|
||||
login() {
|
||||
return this.auth ? this.auth.toggleAuthentication() : null;
|
||||
},
|
||||
|
||||
|
||||
logout() {
|
||||
if (this.auth && this.auth.isAuthenticated()) {
|
||||
this.auth.toggleAuthentication();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
toggleEditMode() {
|
||||
return this.auth ? this.auth.toggleEditMode() : null;
|
||||
},
|
||||
|
||||
|
||||
isAuthenticated() {
|
||||
return this.auth ? this.auth.isAuthenticated() : false;
|
||||
},
|
||||
|
||||
|
||||
isEditMode() {
|
||||
return this.auth ? this.auth.isEditMode() : false;
|
||||
},
|
||||
|
||||
// Version info
|
||||
version: '1.0.0'
|
||||
|
||||
// TODO: Version info based on package.json?
|
||||
};
|
||||
|
||||
// Auto-initialize in development mode with proper DOM ready handling
|
||||
function autoInitialize() {
|
||||
if (document.querySelector('[data-insertr-enhanced="true"]')) {
|
||||
if (document.querySelector('.insertr')) {
|
||||
window.Insertr.init();
|
||||
}
|
||||
}
|
||||
@@ -90,4 +89,4 @@ if (document.readyState === 'loading') {
|
||||
autoInitialize();
|
||||
}
|
||||
|
||||
export default window.Insertr;
|
||||
export default window.Insertr;
|
||||
|
||||
2403
package-lock.json
generated
2403
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
46
package.json
46
package.json
@@ -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": {}
|
||||
}
|
||||
@@ -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"
|
||||
Reference in New Issue
Block a user