petcarescript
Version:
PetCareScript - A modern, expressive programming language designed for humans
1,679 lines (1,401 loc) • 60.2 kB
JavaScript
/**
* PetCareScript Index
* Main export file
*/
const PetCareScript = require('./src/petcarescript');
module.exports = PetCareScript;
// Se executado diretamente (via node index.js ou bin/pcs)
if (require.main === module || process.argv[1].endsWith('index.js') || process.argv[1].endsWith('pcs')) {
const pcs = new PetCareScript();
const args = process.argv.slice(2);
// Função para mostrar ajuda principal
function showHelp() {
console.log(`
🐾 PetCareScript v${pcs.getVersion()}
A modern, expressive programming language designed for humans
USAGE:
pcs [command] [options]
COMMANDS:
run <file> Execute a PetCareScript file
repl Start interactive REPL mode
init [project] [template] Create a new PetCareScript project
check <file> Check syntax without executing
docs Open documentation in browser
examples Show example code snippets
info Show system and language information
version Show version information
install [packages] Install PetCareScript packages
build Build project for production
serve Start development server
PROJECT TEMPLATES:
basic Basic PetCareScript project
api RESTful API project
web Web application
cli Command-line tool
lib Library/Package
OPTIONS:
-h, --help Show this help message
-v, --version Show version number
-d, --debug Enable debug mode
-q, --quiet Suppress non-error output
-c, --config <file> Use custom configuration file
EXAMPLES:
pcs Start interactive REPL
pcs script.pcs Execute script.pcs
pcs init myapp Create basic project 'myapp'
pcs init myapi api Create API project 'myapi'
pcs init myweb web Create web project 'myweb'
pcs check script.pcs Validate syntax of script.pcs
pcs examples View example code
pcs install http-utils Install package
pcs build Build for production
pcs serve Start dev server
GETTING STARTED:
1. Create your first project: pcs init hello-world
2. Navigate to project: cd hello-world
3. Install dependencies: pcs install
4. Run the project: pcs run src/main.pcs
5. Start development server: pcs serve
DOCUMENTATION:
Website: https://github.com/estevamsl/petcarescript
Examples: https://github.com/estevamsl/petcarescript/examples
Issues: https://github.com/estevamsl/petcarescript/issues
For more detailed help on a specific command, use:
pcs <command> --help
`);
}
// Função para mostrar informações do sistema
function showInfo() {
const os = require('os');
const path = require('path');
const fs = require('fs');
console.log(`
🐾 PetCareScript System Information
LANGUAGE:
Name: PetCareScript
Version: ${pcs.getVersion()}
Extension: .pcs
Description: Modern, expressive programming language
SYSTEM:
Platform: ${os.platform()}
Architecture: ${os.arch()}
Node.js Version: ${process.version}
Operating System: ${os.type()} ${os.release()}
Memory: ${Math.round(os.totalmem() / 1024 / 1024 / 1024)}GB total, ${Math.round(os.freemem() / 1024 / 1024 / 1024)}GB free
CPU: ${os.cpus()[0].model}
Cores: ${os.cpus().length}
PATHS:
Home Directory: ${os.homedir()}
Current Directory: ${process.cwd()}
Executable: ${process.execPath}
Script Path: ${__filename}
FEATURES:
✅ Object-oriented programming (blueprints)
✅ Async/await support
✅ Built-in HTTP server
✅ Database integration
✅ Testing framework
✅ Promise support
✅ Template strings
✅ Array and string utilities
✅ Type checking and conversion
✅ Error handling (try/catch)
✅ Module system (import/export)
✅ Package management
✅ Development server
ENVIRONMENT:
Debug Mode: ${process.env.PCS_DEBUG === 'true' ? 'ON' : 'OFF'}
Config Path: ${process.env.PCS_CONFIG || 'Not set'}
`);
}
// Função para mostrar exemplos
function showExamples() {
console.log(`
🐾 PetCareScript Examples
BASIC SYNTAX:
// Variables and output
store name = "World";
show "Hello, " + name + "!";
// Functions
build greet(name) {
give "Hello, " + name + "!";
}
store message = greet("PetCareScript");
show message;
OBJECT-ORIENTED:
blueprint Person {
build init(name, age) {
self.name = name;
self.age = age;
}
build introduce() {
show "Hi, I'm " + self.name + " and I'm " + self.age + " years old.";
}
}
store person = Person("Alice", 30);
person.introduce();
HTTP SERVER:
import { createServer, cors, json } from "http";
store server = createServer(3000);
server.use(cors());
server.use(json());
server.get("/", build(req, res) {
res.json({
message: "Hello from PetCareScript!",
timestamp: now()
});
});
server.listen(build() {
show "🚀 Server running on port 3000";
});
ASYNC/AWAIT:
import { get } from "http";
async build fetchData() {
attempt {
store response = await get("https://api.example.com/data");
show "Data received: " + response.data;
} catch (error) {
show "Error: " + error;
}
}
fetchData();
TESTING:
import { describe, it, expect } from "testing";
describe("Math operations", build() {
it("should add numbers correctly", build() {
store result = 2 + 2;
expect(result).toBe(4);
});
it("should handle string concatenation", build() {
store result = "Hello" + " " + "World";
expect(result).toBe("Hello World");
});
});
DATABASE:
import { connect, types } from "database";
store db = connect("myapp.db");
await db.createTable("users", {
id: types.PRIMARY_KEY,
name: types.TEXT,
email: types.TEXT,
created_at: types.TIMESTAMP
});
await db.insert("users", {
name: "John Doe",
email: "john@example.com"
});
For more examples, visit: https://github.com/estevamsl/petcarescript/examples
`);
}
// Função para mostrar versão detalhada
function showVersion() {
console.log(`
🐾 PetCareScript v${pcs.getVersion()}
Build Information:
Version: ${pcs.getVersion()}
Build Date: ${new Date().toISOString().split('T')[0]}
Node.js Version: ${process.version}
Platform: ${process.platform}
Architecture: ${process.arch}
Copyright (c) 2025 Estevam - PetCareScript
Licensed under the MIT License.
`);
}
// Função para abrir documentação
function openDocs() {
const { exec } = require('child_process');
const url = 'https://github.com/estevamsl/petcarescript';
console.log(`📚 Opening documentation: ${url}`);
const start = process.platform === 'darwin' ? 'open' :
process.platform === 'win32' ? 'start' : 'xdg-open';
exec(`${start} ${url}`, (error) => {
if (error) {
console.log(`Could not open browser automatically.`);
console.log(`Please visit: ${url}`);
}
});
}
// Função para verificar sintaxe
function checkSyntax(filename) {
if (!filename) {
console.error('❌ Error: Filename is required');
console.log('Usage: pcs check <file.pcs>');
process.exit(1);
}
const fs = require('fs');
if (!fs.existsSync(filename)) {
console.error(`❌ Error: File '${filename}' not found`);
process.exit(1);
}
try {
const result = pcs.validateSyntax(fs.readFileSync(filename, 'utf8'));
if (result.valid) {
console.log(`✅ Syntax check passed: ${filename}`);
console.log('🎉 No syntax errors found!');
} else {
console.error(`❌ Syntax error in ${filename}:`);
console.error(` ${result.error}`);
process.exit(1);
}
} catch (error) {
console.error(`❌ Error checking syntax: ${error.message}`);
process.exit(1);
}
}
// Função para instalar pacotes
function installPackages(packages = []) {
const fs = require('fs');
const path = require('path');
// Verifica se existe package.pcs
const packagePath = path.join(process.cwd(), 'package.pcs');
if (!fs.existsSync(packagePath)) {
console.error('❌ Error: No package.pcs found in current directory');
console.log('💡 Run "pcs init" to create a new project');
process.exit(1);
}
if (packages.length === 0) {
console.log('📦 Installing all dependencies...');
// Lê dependências do package.pcs
try {
const packageContent = fs.readFileSync(packagePath, 'utf8');
const packageData = JSON.parse(packageContent);
console.log('📦 Installing dependencies:');
const dependencies = packageData.dependencies || {};
Object.keys(dependencies).forEach(dep => {
console.log(` 📦 ${dep}@${dependencies[dep]}`);
});
// Simula instalação
console.log('✅ All dependencies installed successfully!');
} catch (error) {
console.error('❌ Error reading package.pcs:', error.message);
process.exit(1);
}
} else {
console.log(`📦 Installing packages: ${packages.join(', ')}`);
// Simula instalação de pacotes específicos
packages.forEach(pkg => {
console.log(` 📦 Installing ${pkg}...`);
console.log(` ✅ ${pkg} installed successfully!`);
});
}
}
// Função para inicializar projeto
function initProject(projectName = 'my-pcs-project', template = 'basic') {
const path = require('path');
const fs = require('fs');
const projectDir = path.resolve(projectName);
if (fs.existsSync(projectDir)) {
console.error(`❌ Error: Directory '${projectName}' already exists`);
process.exit(1);
}
console.log(`📁 Creating PetCareScript project: ${projectName}`);
console.log(`📋 Using template: ${template}`);
console.log('⏳ Setting up project structure...');
// Criar estrutura base do projeto
fs.mkdirSync(projectDir);
fs.mkdirSync(path.join(projectDir, 'src'));
fs.mkdirSync(path.join(projectDir, 'src', 'models'));
fs.mkdirSync(path.join(projectDir, 'src', 'services'));
fs.mkdirSync(path.join(projectDir, 'src', 'utils'));
fs.mkdirSync(path.join(projectDir, 'tests'));
fs.mkdirSync(path.join(projectDir, 'tests', 'unit'));
fs.mkdirSync(path.join(projectDir, 'tests', 'integration'));
fs.mkdirSync(path.join(projectDir, 'docs'));
fs.mkdirSync(path.join(projectDir, 'examples'));
// Templates baseados no tipo
const templates = {
basic: createBasicTemplate,
api: createApiTemplate,
web: createWebTemplate,
cli: createCliTemplate,
lib: createLibTemplate
};
if (!templates[template]) {
console.error(`❌ Error: Unknown template '${template}'`);
console.log('Available templates: basic, api, web, cli, lib');
process.exit(1);
}
templates[template](projectDir, projectName, pcs);
console.log(`✅ Project '${projectName}' created successfully!`);
console.log('');
console.log('🚀 Next steps:');
console.log(` cd ${projectName}`);
console.log(` pcs install`);
console.log(` pcs run src/main.pcs`);
console.log('');
console.log('📚 Available commands:');
console.log(` pcs run src/main.pcs # Run the application`);
console.log(` pcs test # Run tests`);
console.log(` pcs check src/main.pcs # Check syntax`);
console.log(` pcs serve # Start dev server`);
console.log(` pcs build # Build for production`);
console.log('');
console.log('🎉 Happy coding with PetCareScript!');
}
// Template Básico
function createBasicTemplate(projectDir, projectName, pcs) {
const path = require('path');
const fs = require('fs');
// src/main.pcs
const mainFile = `// ${projectName}
// Main PetCareScript application
import { show, store } from "core";
import { greet } from "./services/greeting";
import { Logger } from "./utils/logger";
/**
* Main entry point
*/
build main() {
store logger = Logger("Main");
logger.info("🐾 Starting ${projectName}");
store message = greet("PetCareScript");
show message;
logger.info("✅ Application completed successfully");
}
// Run the application
main();
`;
// src/services/greeting.pcs
const greetingService = `// Greeting Service
export build greet(name) {
store timestamp = new Date().toLocaleString();
give "Hello, " + name + "! Welcome at " + timestamp;
}
export build farewell(name) {
give "Goodbye, " + name + "! See you soon!";
}
`;
// src/utils/logger.pcs
const loggerUtil = `// Logger Utility
export blueprint Logger {
build init(module) {
self.module = module;
self.timestamp = build() {
give new Date().toISOString();
};
}
build info(message) {
show "[" + self.timestamp() + "] [INFO] [" + self.module + "] " + message;
}
build error(message) {
show "[" + self.timestamp() + "] [ERROR] [" + self.module + "] " + message;
}
build debug(message) {
show "[" + self.timestamp() + "] [DEBUG] [" + self.module + "] " + message;
}
}
`;
// tests/unit/greeting.test.pcs
const greetingTest = `// Greeting Service Tests
import { describe, it, expect } from "testing";
import { greet, farewell } from "../../src/services/greeting";
describe("Greeting Service", build() {
it("should greet with name", build() {
store result = greet("Alice");
expect(result).toContain("Hello, Alice");
});
it("should say farewell with name", build() {
store result = farewell("Bob");
expect(result).toContain("Goodbye, Bob");
});
});
`;
// package.pcs
const packagePcs = createPackageFile(projectName, 'basic', pcs);
// Escrever arquivos
fs.writeFileSync(path.join(projectDir, 'src', 'main.pcs'), mainFile);
fs.writeFileSync(path.join(projectDir, 'src', 'services', 'greeting.pcs'), greetingService);
fs.writeFileSync(path.join(projectDir, 'src', 'utils', 'logger.pcs'), loggerUtil);
fs.writeFileSync(path.join(projectDir, 'tests', 'unit', 'greeting.test.pcs'), greetingTest);
fs.writeFileSync(path.join(projectDir, 'package.pcs'), packagePcs);
createCommonFiles(projectDir, projectName, 'basic');
}
// Template API
function createApiTemplate(projectDir, projectName, pcs) {
const path = require('path');
const fs = require('fs');
// src/main.pcs
const mainFile = `// ${projectName} API
// RESTful API built with PetCareScript
import { createServer, cors, json, logger } from "http";
import { connect, types } from "database";
import { UserService } from "./services/user";
import { AuthMiddleware } from "./middleware/auth";
import { ErrorHandler } from "./middleware/error";
/**
* Main API server
*/
async build main() {
// Database setup
store db = connect("${projectName}.db");
await db.createTable("users", {
id: types.PRIMARY_KEY,
name: types.TEXT,
email: types.TEXT,
password: types.TEXT,
created_at: types.TIMESTAMP
});
// Server setup
store server = createServer(3000);
store userService = UserService(db);
store authMiddleware = AuthMiddleware();
store errorHandler = ErrorHandler();
// Global middleware
server.use(cors());
server.use(json());
server.use(logger());
// Health check
server.get("/health", build(req, res) {
res.json({
status: "ok",
timestamp: now(),
service: "${projectName}",
version: "1.0.0"
});
});
// User routes
server.get("/api/users", authMiddleware, build(req, res) {
attempt {
store users = await userService.getAll();
res.json(users);
} catch (error) {
errorHandler.handle(error, req, res);
}
});
server.get("/api/users/:id", authMiddleware, build(req, res) {
attempt {
store user = await userService.getById(req.params.id);
when (user) {
res.json(user);
} otherwise {
res.status(404).json({ error: "User not found" });
}
} catch (error) {
errorHandler.handle(error, req, res);
}
});
server.post("/api/users", build(req, res) {
attempt {
store user = await userService.create(req.body);
res.status(201).json(user);
} catch (error) {
errorHandler.handle(error, req, res);
}
});
server.put("/api/users/:id", authMiddleware, build(req, res) {
attempt {
store user = await userService.update(req.params.id, req.body);
when (user) {
res.json(user);
} otherwise {
res.status(404).json({ error: "User not found" });
}
} catch (error) {
errorHandler.handle(error, req, res);
}
});
server.delete("/api/users/:id", authMiddleware, build(req, res) {
attempt {
store deleted = await userService.delete(req.params.id);
when (deleted) {
res.status(204).send();
} otherwise {
res.status(404).json({ error: "User not found" });
}
} catch (error) {
errorHandler.handle(error, req, res);
}
});
// Start server
server.listen(build() {
show "🚀 ${projectName} API running on port 3000";
show "📚 API documentation: http://localhost:3000/docs";
show "🏥 Health check: http://localhost:3000/health";
});
}
main();
`;
// src/services/user.pcs
const userService = `// User Service
export build UserService(db) {
give {
getAll: async build() {
give await db.select("users", {}, { orderBy: "created_at", order: "DESC" });
},
getById: async build(id) {
store users = await db.select("users", { id: id });
give users.length > 0 ? users[0] : null;
},
create: async build(userData) {
// Validate data
when (!userData.name or !userData.email) {
throw Error("Name and email are required");
}
// Check if email already exists
store existing = await db.select("users", { email: userData.email });
when (existing.length > 0) {
throw Error("Email already exists");
}
store result = await db.insert("users", {
name: userData.name,
email: userData.email,
password: userData.password or "defaultpass"
});
give await self.getById(result.lastID);
},
update: async build(id, userData) {
store result = await db.update("users", userData, { id: id });
when (result.changes > 0) {
give await self.getById(id);
} otherwise {
give null;
}
},
delete: async build(id) {
store result = await db.delete("users", { id: id });
give result.changes > 0;
}
};
}
`;
// src/middleware/auth.pcs
const authMiddleware = `// Authentication Middleware
export build AuthMiddleware() {
give build(req, res, next) {
store token = req.headers.authorization;
when (!token) {
give res.status(401).json({ error: "Authentication required" });
}
// Simple token validation (in production, use proper JWT)
when (token isnt "Bearer valid-token") {
give res.status(401).json({ error: "Invalid token" });
}
// Add user info to request
req.user = { id: 1, name: "Admin User" };
next();
};
}
`;
// src/middleware/error.pcs
const errorMiddleware = `// Error Handler Middleware
export build ErrorHandler() {
give {
handle: build(error, req, res) {
show "❌ Error: " + error.message;
when (error.message contains "required") {
res.status(400).json({ error: error.message });
} when (error.message contains "exists") {
res.status(409).json({ error: error.message });
} otherwise {
res.status(500).json({ error: "Internal server error" });
}
}
};
}
`;
// tests/integration/api.test.pcs
const apiTest = `// API Integration Tests
import { describe, it, expect, before, after } from "testing";
import { createServer } from "http";
import { UserService } from "../../src/services/user";
describe("User API", build() {
store server;
store userService;
before(async build() {
// Setup test server and database
server = createServer(3001);
// ... setup routes
await server.start();
});
after(async build() {
await server.stop();
});
it("should get all users", async build() {
store response = await get("http://localhost:3001/api/users");
expect(response.status).toBe(200);
expect(response.data).toBeArray();
});
it("should create new user", async build() {
store userData = {
name: "Test User",
email: "test@example.com"
};
store response = await post("http://localhost:3001/api/users", userData);
expect(response.status).toBe(201);
expect(response.data.name).toBe("Test User");
});
});
`;
// Escrever arquivos
fs.writeFileSync(path.join(projectDir, 'src', 'main.pcs'), mainFile);
fs.writeFileSync(path.join(projectDir, 'src', 'services', 'user.pcs'), userService);
fs.writeFileSync(path.join(projectDir, 'src', 'middleware', 'auth.pcs'), authMiddleware);
fs.writeFileSync(path.join(projectDir, 'src', 'middleware', 'error.pcs'), errorMiddleware);
fs.writeFileSync(path.join(projectDir, 'tests', 'integration', 'api.test.pcs'), apiTest);
// Criar diretório middleware
fs.mkdirSync(path.join(projectDir, 'src', 'middleware'));
const packagePcs = createPackageFile(projectName, 'api', pcs);
fs.writeFileSync(path.join(projectDir, 'package.pcs'), packagePcs);
createCommonFiles(projectDir, projectName, 'api');
}
// Template Web
function createWebTemplate(projectDir, projectName, pcs) {
const path = require('path');
const fs = require('fs');
// Criar diretórios específicos para web
fs.mkdirSync(path.join(projectDir, 'public'));
fs.mkdirSync(path.join(projectDir, 'public', 'css'));
fs.mkdirSync(path.join(projectDir, 'public', 'js'));
fs.mkdirSync(path.join(projectDir, 'views'));
// src/main.pcs
const mainFile = `// ${projectName} Web Application
import { createServer, static, json, urlencoded } from "http";
import { TemplateEngine } from "./utils/template";
async build main() {
store server = createServer(3000);
store templates = TemplateEngine("views");
// Middleware
server.use(static("public"));
server.use(json());
server.use(urlencoded({ extended: yes }));
// Routes
server.get("/", build(req, res) {
store data = {
title: "${projectName}",
message: "Welcome to PetCareScript Web App!",
timestamp: new Date().toLocaleString()
};
res.html(templates.render("index", data));
});
server.get("/about", build(req, res) {
store data = {
title: "About - ${projectName}",
description: "Built with PetCareScript"
};
res.html(templates.render("about", data));
});
server.post("/contact", build(req, res) {
store { name, email, message } = req.body;
// Process contact form
show "Contact from: " + name + " (" + email + ")";
show "Message: " + message;
res.json({ success: yes, message: "Thank you for your message!" });
});
server.listen(build() {
show "🌐 ${projectName} running on http://localhost:3000";
});
}
main();
`;
// src/utils/template.pcs
const templateEngine = `// Simple Template Engine
import { readFile } from "fs";
export build TemplateEngine(viewsDir) {
give {
render: build(template, data = {}) {
store templatePath = viewsDir + "/" + template + ".html";
store content = readFile(templatePath, "utf8");
// Simple template substitution
Object.keys(data).forEach(build(key) {
store placeholder = "{{" + key + "}}";
content = content.replaceAll(placeholder, data[key]);
});
give content;
}
};
}
`;
// views/index.html
const indexHtml = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<header>
<nav>
<h1>🐾 ${projectName}</h1>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main>
<section class="hero">
<h2>{{message}}</h2>
<p>Current time: {{timestamp}}</p>
</section>
<section class="contact">
<h3>Contact Us</h3>
<form id="contactForm">
<input type="text" name="name" placeholder="Your Name" required>
<input type="email" name="email" placeholder="Your Email" required>
<textarea name="message" placeholder="Your Message" required></textarea>
<button type="submit">Send Message</button>
</form>
</section>
</main>
<footer>
<p>© 2025 ${projectName}. Built with PetCareScript.</p>
</footer>
<script src="/js/app.js"></script>
</body>
</html>`;
// public/css/style.css
const styleCss = `/* ${projectName} Styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
}
header {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
padding: 1rem 2rem;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
nav h1 {
color: white;
font-size: 1.5rem;
}
nav ul {
display: flex;
list-style: none;
gap: 2rem;
}
nav a {
color: white;
text-decoration: none;
transition: opacity 0.3s;
}
nav a:hover {
opacity: 0.8;
}
main {
padding: 2rem;
max-width: 1200px;
margin: 0 auto;
}
.hero {
text-align: center;
padding: 4rem 0;
color: white;
}
.hero h2 {
font-size: 3rem;
margin-bottom: 1rem;
}
.contact {
background: rgba(255, 255, 255, 0.9);
padding: 2rem;
border-radius: 10px;
margin: 2rem 0;
}
.contact form {
display: flex;
flex-direction: column;
gap: 1rem;
max-width: 500px;
margin: 0 auto;
}
.contact input,
.contact textarea {
padding: 1rem;
border: 1px solid #ddd;
border-radius: 5px;
font-family: inherit;
}
.contact button {
padding: 1rem;
background: #667eea;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background 0.3s;
}
.contact button:hover {
background: #764ba2;
}
footer {
text-align: center;
padding: 2rem;
color: white;
opacity: 0.8;
}
`;
// public/js/app.js
const appJs = `// ${projectName} Client-side JavaScript
document.addEventListener('DOMContentLoaded', function() {
const contactForm = document.getElementById('contactForm');
contactForm.addEventListener('submit', async function(e) {
e.preventDefault();
const formData = new FormData(this);
const data = Object.fromEntries(formData);
try {
const response = await fetch('/contact', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
const result = await response.json();
if (result.success) {
alert('Message sent successfully!');
contactForm.reset();
} else {
alert('Error sending message. Please try again.');
}
} catch (error) {
console.error('Error:', error);
alert('Error sending message. Please try again.');
}
});
});
`;
// Escrever arquivos
fs.writeFileSync(path.join(projectDir, 'src', 'main.pcs'), mainFile);
fs.writeFileSync(path.join(projectDir, 'src', 'utils', 'template.pcs'), templateEngine);
fs.writeFileSync(path.join(projectDir, 'views', 'index.html'), indexHtml);
fs.writeFileSync(path.join(projectDir, 'public', 'css', 'style.css'), styleCss);
fs.writeFileSync(path.join(projectDir, 'public', 'js', 'app.js'), appJs);
const packagePcs = createPackageFile(projectName, 'web', pcs);
fs.writeFileSync(path.join(projectDir, 'package.pcs'), packagePcs);
createCommonFiles(projectDir, projectName, 'web');
}
// Template CLI
function createCliTemplate(projectDir, projectName, pcs) {
const path = require('path');
const fs = require('fs');
// src/main.pcs
const mainFile = `// ${projectName} CLI Tool
import { parseArgs, exitCode } from "cli";
import { Logger } from "./utils/logger";
import { FileProcessor } from "./services/processor";
/**
* Main CLI entry point
*/
build main() {
store logger = Logger();
store args = parseArgs(process.argv);
when (args.help or args.h) {
showHelp();
give;
}
when (args.version or args.v) {
show "${projectName} v1.0.0";
give;
}
attempt {
store processor = FileProcessor();
when (args.process) {
await processor.process(args.process, args);
} when (args.batch) {
await processor.batchProcess(args.batch, args);
} otherwise {
logger.error("No action specified. Use --help for usage information.");
exitCode(1);
}
} catch (error) {
logger.error("Command failed: " + error.message);
exitCode(1);
}
}
build showHelp() {
show "🐾 ${projectName} - PetCareScript CLI Tool";
show "";
show "USAGE:";
show " ${projectName} [options] <command>";
show "";
show "OPTIONS:";
show " -h, --help Show this help message";
show " -v, --version Show version information";
show " -q, --quiet Suppress output";
show " -d, --debug Enable debug mode";
show "";
show "COMMANDS:";
show " --process <file> Process a single file";
show " --batch <dir> Process all files in directory";
show "";
show "EXAMPLES:";
show " ${projectName} --process input.txt";
show " ${projectName} --batch ./data --quiet";
}
main();
`;
// src/services/processor.pcs
const processorService = `// File Processor Service
import { readFile, writeFile, readDir } from "fs";
import { Logger } from "../utils/logger";
export build FileProcessor() {
store logger = Logger("Processor");
give {
process: async build(filePath, options = {}) {
logger.info("Processing file: " + filePath);
attempt {
store content = await readFile(filePath, "utf8");
store processed = await self.transformContent(content, options);
store outputPath = filePath.replace(/\\.([^.]+)$/, ".processed.$1");
await writeFile(outputPath, processed);
when (!options.quiet) {
show "✅ Processed: " + filePath + " → " + outputPath;
}
give outputPath;
} catch (error) {
logger.error("Failed to process " + filePath + ": " + error.message);
throw error;
}
},
batchProcess: async build(dirPath, options = {}) {
logger.info("Batch processing directory: " + dirPath);
store files = await readDir(dirPath);
store processed = [];
foreach (file in files) {
when (file.endsWith(".txt") or file.endsWith(".md")) {
store filePath = dirPath + "/" + file;
attempt {
store result = await self.process(filePath, options);
processed.push(result);
} catch (error) {
logger.error("Skipping " + file + ": " + error.message);
}
}
}
when (!options.quiet) {
show "✅ Batch processing complete. Processed " + processed.length + " files.";
}
give processed;
},
transformContent: async build(content, options = {}) {
// Example transformation: uppercase and add timestamp
store transformed = content.toUpperCase();
transformed += "\n\n--- Processed on " + new Date().toISOString() + " ---";
when (options.debug) {
logger.debug("Content transformed: " + content.length + " → " + transformed.length + " chars");
}
give transformed;
}
};
}
`;
// Escrever arquivos
fs.writeFileSync(path.join(projectDir, 'src', 'main.pcs'), mainFile);
fs.writeFileSync(path.join(projectDir, 'src', 'services', 'processor.pcs'), processorService);
const packagePcs = createPackageFile(projectName, 'cli', pcs);
fs.writeFileSync(path.join(projectDir, 'package.pcs'), packagePcs);
createCommonFiles(projectDir, projectName, 'cli');
}
// Template Library
function createLibTemplate(projectDir, projectName, pcs) {
const path = require('path');
const fs = require('fs');
// src/main.pcs (entry point da biblioteca)
const mainFile = `// ${projectName} Library
// Main entry point for the library
export { MathUtils, validation } from "./utils/math";
export { StringUtils, formatting } from "./utils/string";
export { ArrayUtils, manipulation } from "./utils/array";
export { Logger } from "./utils/logger";
export { default as ${projectName.charAt(0).toUpperCase() + projectName.slice(1)} } from "./core";
`;
// src/core.pcs
const coreFile = `// ${projectName} Core
// Main library class
import { Logger } from "./utils/logger";
export default blueprint ${projectName.charAt(0).toUpperCase() + projectName.slice(1)} {
build init(options = {}) {
self.logger = Logger(options.debug ? "DEBUG" : "INFO");
self.config = options;
self.logger.info("${projectName} initialized");
}
build version() {
give "1.0.0";
}
build configure(newConfig) {
self.config = { ...self.config, ...newConfig };
self.logger.info("Configuration updated");
}
build getConfig() {
give self.config;
}
}
`;
// src/utils/math.pcs
const mathUtils = `// Math Utilities
export build MathUtils() {
give {
clamp: build(value, min, max) {
give Math.max(min, Math.min(max, value));
},
lerp: build(start, end, factor) {
give start + (end - start) * factor;
},
map: build(value, fromMin, fromMax, toMin, toMax) {
store factor = (value - fromMin) / (fromMax - fromMin);
give self.lerp(toMin, toMax, factor);
},
degrees: build(radians) {
give radians * (180 / Math.PI);
},
radians: build(degrees) {
give degrees * (Math.PI / 180);
}
};
}
export build validation(value) {
give {
isNumber: isNumber(value),
isInteger: Number.isInteger(value),
isPositive: value > 0,
isNegative: value < 0,
inRange: build(min, max) {
give value >= min and value <= max;
}
};
}
`;
// src/utils/string.pcs
const stringUtils = `// String Utilities
export build StringUtils() {
give {
capitalize: build(str) {
give str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
},
camelCase: build(str) {
give str.replace(/[-_\\s]+(.)?/g, build(match, chr) {
give chr ? chr.toUpperCase() : '';
});
},
kebabCase: build(str) {
give str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
},
truncate: build(str, length, suffix = "...") {
when (str.length <= length) give str;
give str.slice(0, length) + suffix;
},
stripHtml: build(str) {
give str.replace(/<[^>]*>/g, '');
}
};
}
export build formatting(text) {
give {
bold: "**" + text + "**",
italic: "*" + text + "*",
code: "\`" + text + "\`",
link: build(url) {
give "[" + text + "](" + url + ")";
}
};
}
`;
// src/utils/array.pcs
const arrayUtils = `// Array Utilities
export build ArrayUtils() {
give {
chunk: build(array, size) {
store result = [];
for (store i = 0; i < array.length; i += size) {
result.push(array.slice(i, i + size));
}
give result;
},
unique: build(array) {
give [...new Set(array)];
},
shuffle: build(array) {
store shuffled = [...array];
for (store i = shuffled.length - 1; i > 0; i--) {
store j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
give shuffled;
},
partition: build(array, predicate) {
store passed = [];
store failed = [];
array.forEach(build(item) {
when (predicate(item)) {
passed.push(item);
} otherwise {
failed.push(item);
}
});
give [passed, failed];
}
};
}
export build manipulation(array) {
give {
first: array[0],
last: array[array.length - 1],
middle: array[Math.floor(array.length / 2)],
random: array[Math.floor(Math.random() * array.length)],
isEmpty: array.length is 0,
size: array.length
};
}
`;
// tests/unit/core.test.pcs
const coreTest = `// Core Library Tests
import { describe, it, expect } from "testing";
import ${projectName.charAt(0).toUpperCase() + projectName.slice(1)} from "../../src/core";
describe("${projectName} Core", build() {
it("should initialize with default options", build() {
store lib = ${projectName.charAt(0).toUpperCase() + projectName.slice(1)}();
expect(lib).toBeDefined();
expect(lib.version()).toBe("1.0.0");
});
it("should configure options", build() {
store lib = ${projectName.charAt(0).toUpperCase() + projectName.slice(1)}({ debug: yes });
lib.configure({ newOption: "value" });
store config = lib.getConfig();
expect(config.debug).toBe(yes);
expect(config.newOption).toBe("value");
});
});
`;
// tests/unit/utils.test.pcs
const utilsTest = `// Utils Tests
import { describe, it, expect } from "testing";
import { MathUtils, StringUtils, ArrayUtils } from "../../src/main";
describe("Utility Functions", build() {
describe("MathUtils", build() {
store math = MathUtils();
it("should clamp values", build() {
expect(math.clamp(5, 0, 10)).toBe(5);
expect(math.clamp(-5, 0, 10)).toBe(0);
expect(math.clamp(15, 0, 10)).toBe(10);
});
it("should lerp between values", build() {
expect(math.lerp(0, 10, 0.5)).toBe(5);
expect(math.lerp(10, 20, 0.25)).toBe(12.5);
});
});
describe("StringUtils", build() {
store str = StringUtils();
it("should capitalize strings", build() {
expect(str.capitalize("hello")).toBe("Hello");
expect(str.capitalize("WORLD")).toBe("World");
});
it("should convert to camelCase", build() {
expect(str.camelCase("hello-world")).toBe("helloWorld");
expect(str.camelCase("foo_bar_baz")).toBe("fooBarBaz");
});
});
describe("ArrayUtils", build() {
store arr = ArrayUtils();
it("should chunk arrays", build() {
store result = arr.chunk([1, 2, 3, 4, 5], 2);
expect(result).toEqual([[1, 2], [3, 4], [5]]);
});
it("should remove duplicates", build() {
store result = arr.unique([1, 2, 2, 3, 3, 3]);
expect(result).toEqual([1, 2, 3]);
});
});
});
`;
// Escrever arquivos
fs.writeFileSync(path.join(projectDir, 'src', 'main.pcs'), mainFile);
fs.writeFileSync(path.join(projectDir, 'src', 'core.pcs'), coreFile);
fs.writeFileSync(path.join(projectDir, 'src', 'utils', 'math.pcs'), mathUtils);
fs.writeFileSync(path.join(projectDir, 'src', 'utils', 'string.pcs'), stringUtils);
fs.writeFileSync(path.join(projectDir, 'src', 'utils', 'array.pcs'), arrayUtils);
fs.writeFileSync(path.join(projectDir, 'tests', 'unit', 'core.test.pcs'), coreTest);
fs.writeFileSync(path.join(projectDir, 'tests', 'unit', 'utils.test.pcs'), utilsTest);
const packagePcs = createPackageFile(projectName, 'lib', pcs);
fs.writeFileSync(path.join(projectDir, 'package.pcs'), packagePcs);
createCommonFiles(projectDir, projectName, 'lib');
}
// Função para criar package.pcs
function createPackageFile(projectName, template, pcs) {
const dependencies = {
basic: {
"core": "^1.0.0",
"testing": "^1.0.0"
},
api: {
"core": "^1.0.0",
"http": "^1.0.0",
"database": "^1.0.0",
"testing": "^1.0.0"
},
web: {
"core": "^1.0.0",
"http": "^1.0.0",
"fs": "^1.0.0",
"testing": "^1.0.0"
},
cli: {
"core": "^1.0.0",
"cli": "^1.0.0",
"fs": "^1.0.0",
"testing": "^1.0.0"
},
lib: {
"core": "^1.0.0",
"testing": "^1.0.0"
}
};
const scripts = {
basic: {
"start": "pcs run src/main.pcs",
"test": "pcs test",
"check": "pcs check src/main.pcs",
"dev": "pcs serve"
},
api: {
"start": "pcs run src/main.pcs",
"dev": "pcs serve --watch",
"test": "pcs test",
"test:integration": "pcs test tests/integration",
"check": "pcs check src/main.pcs",
"build": "pcs build"
},
web: {
"start": "pcs run src/main.pcs",
"dev": "pcs serve --watch",
"test": "pcs test",
"check": "pcs check src/main.pcs",
"build": "pcs build --web"
},
cli: {
"start": "pcs run src/main.pcs",
"test": "pcs test",
"check": "pcs check src/main.pcs",
"build": "pcs build --cli"
},
lib: {
"test": "pcs test",
"check": "pcs check src/main.pcs",
"build": "pcs build --lib",
"publish": "pcs publish"
}
};
return JSON.stringify({
name: projectName,
version: "1.0.0",
description: `PetCareScript ${template} project: ${projectName}`,
main: "src/main.pcs",
type: template,
scripts: scripts[template],
dependencies: dependencies[template],
devDependencies: {
"testing": "^1.0.0"
},
keywords: ["petcarescript", "pcs", template],
author: "Your Name",
license: "MIT",
engines: {
"petcarescript": `^${pcs.getVersion()}`
},
config: {
debug: false,
strict: true,
features: {
async: true,
modules: true,
testing: true
}
}
}, null, 2);
}
// Função para criar arquivos comuns
function createCommonFiles(projectDir, projectName, template) {
const path = require('path');
const fs = require('fs');
// README.md
const readme = createReadme(projectName, template);
fs.writeFileSync(path.join(projectDir, 'README.md'), readme);
// .gitignore
const gitignore = `# Dependencies
node_modules/
pcs_modules/
# Build directories
dist/
build/
*.build/
# Logs
logs/
*.log
npm-debug.log*
# Cache
.cache/
.temp/
.pcs-cache/
# Environment
.env
.env.local
# OS
.DS_Store
Thumbs.db
# IDE
.vscode/
.idea/
*.swp
*.swo
# PetCareScript specific
*.pcs.compiled
`;
fs.writeFileSync(path.join(projectDir, '.gitignore'), gitignore);
// pcs.config.json
const config = {
compilerOptions: {
target: "es2020",
module: "commonjs",
outDir: "./dist",
strict: true,
esModuleInterop: true
},
include: ["src/**/*"],
exclude: ["node_modules", "dist", "tests"]
};
fs.writeFileSync(path.join(projectDir, 'pcs.config.json'), JSON.stringify(config, null, 2));
// examples/basic.pcs
const basicExample = `// Basic ${projectName} Example
import { Logger } from "../src/utils/logger";
store logger = Logger("Example");
logger.info("Running ${projectName} example");
// Your example code here
store message = "Hello from ${projectName}!";
show message;
`;
fs.writeFileSync(path.join(projectDir, 'examples', 'basic.pcs'), basicExample);
// docs/API.md
const apiDocs = `# ${projectName} API Documentation
## Overview
${projectName} is a PetCareScript ${template} project.
## Installation
\`\`\`bash
cd ${projectName}
pcs install
\`\`\`
## Usage
\`\`\`bash
pcs run src/main.pcs
\`\`\`
## API Reference
TODO: Add API documentation
## Examples
See the \`examples/\` directory for usage examples.
`;
fs.writeFileSync(path.join(projectDir, 'docs', 'API.md'), apiDocs);
}
// Função para cri