petcarescript
v1.4.1
Published
PetCareScript - A modern, expressive programming language designed for humans
Maintainers
Readme
🐾 PetCareScript - Documentação Completa
Uma linguagem de programação moderna, expressiva e amigável para humanos com suporte completo a async, HTTP, banco de dados e testes
🌐 Site Oficial • 📖 Documentação • 🧩 Extensão VS Code • 💬 Comunidade • 🎓 Tutoriais
🌟 Por que PetCareScript?
PetCareScript é uma linguagem de programação revolucionária que combina simplicidade, poder e elegância. Desenvolvida pela PetCareAI, ela oferece uma sintaxe naturalmente legível que torna a programação mais humana e acessível.
✨ Características Principais
🎯 Sintaxe Natural - Escreva código que qualquer pessoa pode entender
⚡ Performance - Interpretador otimizado com execução rápida
🔧 Ferramentas Integradas - HTTP, banco de dados, testes e muito mais
🌐 Async/Await - Programação assíncrona moderna e intuitiva
🏗️ OOP Avançado - Sistema de blueprints poderoso e flexível
🧪 TDD/BDD - Framework de testes completo integrado
📦 Módulos - Sistema de importação/exportação robusto
🎨 Extensibilidade - Fácil integração com bibliotecas externas
📖 Índice
- 🚀 Instalação
- ⚡ Início Rápido
- 🎯 Primeiros Passos
- 📝 Sintaxe Básica
- 🔤 Palavras Reservadas
- 🏗️ Programação Orientada a Objetos
- ⚡ Programação Assíncrona
- 🌐 Servidor HTTP e APIs
- 🗄️ Banco de Dados
- 🧪 Framework de Testes
- 📦 Sistema de Módulos
- 🔧 Operadores Avançados
- 📚 Biblioteca Padrão
- 🛠️ Ferramentas e Extensões
- 📁 Extensão de Arquivo
- 🎓 Tutoriais Avançados
- 📋 Changelog
- 🤝 Contribuição
- 📄 Licença
🚀 Instalação
📦 Instalação Global (Recomendada)
# Via NPM
npm install -g petcarescript
# Via Yarn
yarn global add petcarescript
# Verificar instalação
pcs --version🏠 Instalação Local
# Para projeto específico
npm install petcarescript
npx pcs meuarquivo.pcs💾 Instalação via Executáveis
# Linux/macOS - Instalação automática
curl -sSL https://raw.githubusercontent.com/PetCareAi/petcarescript/main/install.sh | bash
# Windows - PowerShell como Administrador
irm https://raw.githubusercontent.com/PetCareAi/petcarescript/main/install.ps1 | iex🧩 Extensão VS Code
Instale a extensão oficial para VS Code:
Recursos da Extensão:
- 🎨 Syntax highlighting
- 🔍 IntelliSense e autocompletar
- 🐛 Debugging integrado
- 📋 Snippets de código
- 🔧 Linting e formatação
- 🏃 Execução direta no editor
⚡ Início Rápido
🌟 Seu Primeiro Programa
// hello.pcs
show "🐾 Bem-vindo ao PetCareScript!";
store name = "Desenvolvedor";
show "Olá, " + name + "! Vamos programar?";
build greet(person) {
give "🎉 Oi, " + person + "! Que bom ter você aqui!";
}
store message = greet(name);
show message;Execute:
pcs hello.pcs🔥 REPL Interativo
# Iniciar REPL
pcs
# Teste comandos interativamente
pcs> store x = 42;
pcs> show x * 2;
pcs> build square(n) { give n * n; }
pcs> show square(8);
pcs> exit🎯 Primeiros Passos
1️⃣ Variáveis e Tipos
// Tipos básicos
store name = "Ana Silva"; // String
store age = 28; // Number
store isActive = yes; // Boolean (true)
store isInactive = no; // Boolean (false)
store nothing = empty; // Null
store items = [1, 2, 3, 4]; // Array
store person = {
name: "João",
age: 35,
skills: ["JavaScript", "PetCareScript"]
}; // Object2️⃣ Funções Básicas
// Função simples
build sayHello(name) {
show "Olá, " + name + "!";
}
// Função com retorno
build multiply(a, b) {
give a * b; // 'give' é como 'return'
}
// Função com múltiplos parâmetros
build createUser(name, age, email, role = "user") {
give {
name: name,
age: age,
email: email,
role: role,
createdAt: now(),
active: yes
};
}
// Usando funções
sayHello("Maria");
store result = multiply(7, 8);
store newUser = createUser("Pedro", 25, "[email protected]", "admin");
show newUser;3️⃣ Condicionais Inteligentes
store score = 87;
// Condicional básica
when (score >= 90) {
show "Excelente! Nota A";
} otherwise when (score >= 80) {
show "Muito bom! Nota B";
} otherwise when (score >= 70) {
show "Bom! Nota C";
} otherwise {
show "Precisa melhorar";
}
// Unless (oposto de if)
unless (score < 60) {
show "Aprovado!";
}
// Operadores amigáveis
when (score between 80 and 90) {
show "Nota na faixa B+";
}
store grades = [85, 92, 78];
when (grades contains 92) {
show "Tem nota excelente!";
}📝 Sintaxe Básica
🔢 Operadores
// Aritméticos
store sum = 15 + 10; // 25
store diff = 20 - 8; // 12
store product = 6 * 7; // 42
store quotient = 84 / 7; // 12
store remainder = 17 % 5; // 2
// Comparação amigável
store isEqual = (10 is 10); // yes (true)
store isDifferent = (10 isnt 5); // yes (true)
store isGreater = (15 > 10); // yes (true)
store isInRange = (50 between 30 and 70); // yes (true)
// Lógicos naturais
store both = (yes also yes); // yes (true)
store either = (yes either no); // yes (true)
store neither = (not yes); // no (false)
store combined = (age >= 18 and hasLicense);🔄 Loops Avançados
// For loop tradicional
loop (store i = 0; i < 5; i = i + 1) {
show "Contador: " + i;
}
// While loop
store count = 0;
repeat (count < 3) {
show "Repetição: " + count;
count = count + 1;
}
// Until loop (oposto de while)
store countdown = 5;
until (countdown is 0) {
show "Contagem regressiva: " + countdown;
countdown = countdown - 1;
}
// ForEach para arrays
store languages = ["JavaScript", "Python", "PetCareScript"];
foreach (lang in languages) {
show "Linguagem: " + lang;
}
// ForEach para objetos
store user = { name: "Ana", age: 30, city: "SP" };
foreach (key in Object.keys(user)) {
show key + ": " + user[key];
}
// Controle de loop
loop (store j = 0; j < 10; j = j + 1) {
when (j is 3) {
continue; // Pula para próxima iteração
}
when (j is 7) {
break; // Sai do loop
}
show j;
}🎛️ Switch Statement
store dayOfWeek = "monday";
switch (dayOfWeek) {
case "monday":
show "Segunda-feira: Novo começo!";
break;
case "tuesday":
show "Terça-feira: Produtividade!";
break;
case "wednesday":
show "Quarta-feira: Meio da semana!";
break;
case "friday":
show "Sexta-feira: Quase fim de semana!";
break;
default:
show "Dia desconhecido";
}🔤 Palavras Reservadas
Core Language (Essenciais)
| Palavra | Equivalente | Descrição |
|---------|-------------|-----------|
| store | let/var | Declarar variável |
| when | if | Condicional |
| otherwise | else | Alternativa |
| repeat | while | Loop while |
| loop | for | Loop for |
| again | while | Outro while |
| build | function | Declarar função |
| give | return | Retornar valor |
| yes | true | Booleano verdadeiro |
| no | false | Booleano falso |
| empty | null | Valor nulo |
| show | console.log | Exibir saída |
| blueprint | class | Declarar classe |
| self | this | Referência ao objeto |
| parent | super | Referência à classe pai |
Operadores Lógicos
| Palavra | Equivalente | Descrição |
|---------|-------------|-----------|
| also | && | AND lógico |
| either | \|\| | OR lógico |
| not | ! | NOT lógico |
| and | && | Alias para AND |
| or | \|\| | Alias para OR |
Operadores de Comparação
| Palavra | Equivalente | Descrição |
|---------|-------------|-----------|
| is | == | Igualdade |
| isnt | != | Diferença |
| contains | .includes() | Contém elemento |
| in | in | Elemento em coleção |
| of | of | Para iteração |
| like | Pattern match | Similaridade |
| between | Range check | Entre valores |
| matches | Regex match | Pattern matching |
Controle de Fluxo
| Palavra | Descrição |
|---------|-----------|
| break | Sair do loop |
| continue | Próxima iteração |
| unless | If negativo |
| until | While negativo |
| foreach | Loop por elementos |
| switch | Switch statement |
| case | Caso do switch |
| default | Caso padrão |
Tratamento de Erros
| Palavra | Equivalente | Descrição |
|---------|-------------|-----------|
| attempt | try | Tentar execução |
| catch | catch | Capturar erro |
| finally | finally | Sempre executar |
| throw | throw | Lançar erro |
Programação Assíncrona
| Palavra | Descrição |
|---------|-----------|
| async | Função assíncrona |
| await | Esperar promessa |
| promise | Promessa |
| then | Callback de sucesso |
| resolve | Resolver promessa |
| reject | Rejeitar promessa |
| timeout | Função de timeout |
| interval | Função de intervalo |
HTTP e APIs
| Palavra | Descrição |
|---------|-----------|
| http | Módulo HTTP |
| get | HTTP GET |
| post | HTTP POST |
| put | HTTP PUT |
| delete | HTTP DELETE |
| patch | HTTP PATCH |
| server | Servidor HTTP |
| route | Rota da API |
| middleware | Middleware |
| cors | CORS middleware |
| json | Tipo/parser JSON |
Testing
| Palavra | Descrição |
|---------|-----------|
| test | Teste individual |
| describe | Suíte de testes |
| it | Caso de teste |
| expect | Asserção |
| assert | Asserção simples |
| mock | Mock de função |
| spy | Spy de função |
| before | Hook antes |
| after | Hook depois |
| beforeEach | Hook antes de cada |
| afterEach | Hook depois de cada |
Módulos
| Palavra | Descrição |
|---------|-----------|
| import | Importar módulo |
| export | Exportar módulo |
| use | Usar módulo |
| from | De módulo |
| module | Declarar módulo |
| namespace | Namespace |
| as | Alias |
| require | Requerer módulo |
Database
| Palavra | Descrição |
|---------|-----------|
| database | Banco de dados |
| connect | Conectar |
| query | Consulta |
| select | SELECT SQL |
| insert | INSERT SQL |
| update | UPDATE SQL |
| delete | DELETE SQL |
| where | WHERE SQL |
| join | JOIN SQL |
| table | Tabela |
| transaction | Transação |
| commit | Confirmar |
| rollback | Reverter |
Tipos de Dados
| Palavra | Descrição |
|---------|-----------|
| array | Array/lista |
| object | Objeto |
| map | Mapa/dicionário |
| set | Conjunto |
| enum | Enumeração |
| interface | Interface |
| type | Tipo personalizado |
Features Avançadas
| Palavra | Descrição |
|---------|-----------|
| yield | Yield para generators |
| generator | Função generator |
| decorator | Decorator |
| lazy | Avaliação lazy |
| memoize | Memoização |
🏗️ Programação Orientada a Objetos
🏛️ Blueprints (Classes)
// Blueprint básico
blueprint Animal {
build init(name, species) {
self.name = name;
self.species = species;
self.energy = 100;
self.happiness = 50;
}
build eat(food) {
self.energy = self.energy + 15;
show self.name + " comeu " + food + " e ganhou energia!";
give self.energy;
}
build play() {
when (self.energy > 20) {
self.energy = self.energy - 10;
self.happiness = self.happiness + 20;
show self.name + " está brincando! 🎾";
} otherwise {
show self.name + " está muito cansado para brincar...";
}
}
build status() {
give {
name: self.name,
species: self.species,
energy: self.energy,
happiness: self.happiness,
mood: self.happiness > 70 ? "feliz" : "normal"
};
}
}
// Herança
blueprint Dog extends Animal {
build init(name, breed) {
parent.init(name, "Cachorro");
self.breed = breed;
self.tricks = [];
}
build bark() {
show self.name + " faz: AU AU! 🐕";
give "woof";
}
build learnTrick(trick) {
push(self.tricks, trick);
self.happiness = self.happiness + 10;
show self.name + " aprendeu: " + trick + "! 🎉";
}
build performTrick() {
when (size(self.tricks) > 0) {
store trick = randomChoice(self.tricks);
show self.name + " fez: " + trick + "! 👏";
self.happiness = self.happiness + 5;
} otherwise {
show self.name + " ainda não sabe truques...";
}
}
}
// Uso prático
store myDog = Dog("Rex", "Golden Retriever");
myDog.eat("ração premium");
myDog.learnTrick("sentar");
myDog.learnTrick("dar a patinha");
myDog.bark();
myDog.performTrick();
myDog.play();
store dogStatus = myDog.status();
show "Status do " + dogStatus.name + ": " + stringifyJSON(dogStatus);🎭 Interfaces e Enums
// Interface
interface Flyable {
fly(): void;
altitude: number;
maxSpeed: number;
}
// Enumeração
enum OrderStatus {
PENDING,
PROCESSING,
SHIPPED,
DELIVERED,
CANCELLED
}
// Blueprint implementando interface
blueprint Bird extends Animal implements Flyable {
build init(name, wingSpan) {
parent.init(name, "Pássaro");
self.wingSpan = wingSpan;
self.altitude = 0;
self.maxSpeed = 50;
}
build fly() {
self.altitude = 100;
show self.name + " está voando! ✈️";
}
}
// Uso de enum
store orderStatus = OrderStatus.PROCESSING;
when (orderStatus is OrderStatus.DELIVERED) {
show "Pedido entregue!";
}⚡ Programação Assíncrona
🔄 Async/Await
// Função assíncrona básica
async build fetchUserData(userId) {
show "🔍 Buscando dados do usuário " + userId + "...";
attempt {
store response = await get("https://api.example.com/users/" + userId);
store userData = parseJSON(response.data);
show "✅ Usuário encontrado: " + userData.name;
give userData;
} catch (error) {
show "❌ Erro ao buscar usuário: " + error;
give empty;
}
}
// Múltiplas operações assíncronas
async build processUserOrder(userId, orderId) {
show "📦 Processando pedido " + orderId + "...";
// Buscar dados em paralelo
store [user, order, inventory] = await all([
fetchUserData(userId),
fetchOrderData(orderId),
checkInventory(orderId)
]);
when (user and order and inventory.available) {
store result = await processPayment(user, order);
when (result.success) {
await sendConfirmationEmail(user.email, order);
show "🎉 Pedido processado com sucesso!";
give { success: yes, orderId: orderId };
}
} otherwise {
show "❌ Não foi possível processar o pedido";
give { success: no, error: "Dados incompletos" };
}
}
// Usando a função
async build main() {
store result = await processUserOrder(123, "ORD-456");
show "Resultado: " + stringifyJSON(result);
}
main();🎯 Promises Avançadas
// Criando promises personalizadas
build createDownloadPromise(url, filename) {
give Promise(build(resolve, reject) {
show "📥 Iniciando download de " + filename + "...";
timeout(build() {
store success = randomInt(1, 10) > 3; // 70% chance de sucesso
when (success) {
show "✅ Download concluído: " + filename;
resolve({
filename: filename,
size: randomInt(100, 1000) + "KB",
url: url
});
} otherwise {
show "❌ Falha no download: " + filename;
reject("Network error: " + filename);
}
}, randomInt(1000, 3000)); // 1-3 segundos
});
}
// Operações paralelas com controle
async build batchDownload() {
store urls = [
"https://api.example.com/file1.pdf",
"https://api.example.com/file2.jpg",
"https://api.example.com/file3.zip"
];
store downloadPromises = [];
foreach (url in urls) {
store filename = split(url, "/").pop();
push(downloadPromises, createDownloadPromise(url, filename));
}
show "🚀 Iniciando downloads em paralelo...";
attempt {
store results = await all(downloadPromises);
show "🎉 Todos os downloads concluídos!";
foreach (result in results) {
show "📁 " + result.filename + " (" + result.size + ")";
}
give results;
} catch (error) {
show "⚠️ Alguns downloads falharam: " + error;
// Tentar downloads individuais para ver quais falharam
foreach (promise in downloadPromises) {
promise
.then(build(result) {
show "✅ Recuperado: " + result.filename;
})
.catch(build(error) {
show "❌ Falhou definitivamente: " + error;
});
}
}
}
batchDownload();🌐 Servidor HTTP e APIs
🚀 API REST Completa
// server.pcs - Servidor HTTP profissional
import { createServer, cors, json, logger } from "http";
import { connect, types } from "database";
async build startServer() {
// Configuração do banco de dados
store db = connect("petcare_api.db");
await db.connect();
// Criar tabelas
await db.createTable("users", {
id: types.PRIMARY_KEY,
name: types.TEXT + " NOT NULL",
email: types.TEXT + " UNIQUE NOT NULL",
password: types.TEXT + " NOT NULL",
role: types.TEXT + " DEFAULT 'user'",
avatar: types.TEXT,
created_at: types.TIMESTAMP,
updated_at: types.TIMESTAMP
});
await db.createTable("posts", {
id: types.PRIMARY_KEY,
user_id: types.INTEGER + " NOT NULL",
title: types.TEXT + " NOT NULL",
content: types.TEXT,
published: types.BOOLEAN + " DEFAULT 0",
tags: types.JSON,
created_at: types.TIMESTAMP,
updated_at: types.TIMESTAMP
});
// Configuração do servidor
store server = createServer(3000);
// Middleware globais
server.use(cors({
origin: ["http://localhost:3000", "https://petcareai.com.br"],
credentials: yes
}));
server.use(json({ limit: "10mb" }));
server.use(logger("combined"));
// Middleware de autenticação
build authMiddleware(req, res, next) {
store token = req.headers.authorization;
when (token and startsWith(token, "Bearer ")) {
store actualToken = slice(token, 7); // Remove "Bearer "
// Validação simples do token (em produção, use JWT)
when (actualToken is "valid-api-key-123") {
req.user = { id: 1, name: "Admin", role: "admin" };
next();
} otherwise {
res.status(401).json({
error: "Token inválido",
code: "INVALID_TOKEN"
});
}
} otherwise {
res.status(401).json({
error: "Token necessário",
code: "MISSING_TOKEN"
});
}
}
// Rotas públicas
server.get("/health", build(req, res) {
res.json({
status: "healthy",
timestamp: now(),
version: "1.2.3",
uptime: process.uptime()
});
});
// API de usuários
server.get("/api/users", authMiddleware, build(req, res) {
attempt {
store page = toNumber(req.query.page) or 1;
store limit = toNumber(req.query.limit) or 10;
store offset = (page - 1) * limit;
store users = await db.select("users", {}, {
limit: limit,
offset: offset,
orderBy: "created_at",
order: "DESC"
});
// Remover senhas do resultado
store safeUsers = map(users, build(user) {
store { password, ...safeUser } = user;
give safeUser;
});
res.json({
data: safeUsers,
pagination: {
page: page,
limit: limit,
total: size(users)
}
});
} catch (error) {
res.status(500).json({
error: "Erro interno do servidor",
details: error.message
});
}
});
server.post("/api/users", build(req, res) {
attempt {
store { name, email, password, role } = req.body;
// Validação
when (not name or not email or not password) {
res.status(400).json({
error: "Campos obrigatórios: name, email, password"
});
give;
}
when (not isEmail(email)) {
res.status(400).json({
error: "Email inválido"
});
give;
}
// Verificar se email já existe
store existingUser = await db.select("users", { email: email });
when (size(existingUser) > 0) {
res.status(409).json({
error: "Email já cadastrado"
});
give;
}
// Criar usuário
store hashedPassword = hashPassword(password); // Implementar hash
store newUser = await db.insert("users", {
name: name,
email: email,
password: hashedPassword,
role: role or "user"
});
// Buscar usuário criado (sem senha)
store createdUser = await db.select("users", { id: newUser.lastID });
store { password: _, ...safeUser } = createdUser[0];
res.status(201).json({
message: "Usuário criado com sucesso",
data: safeUser
});
} catch (error) {
res.status(500).json({
error: "Erro ao criar usuário",
details: error.message
});
}
});
// API de posts
server.get("/api/posts", build(req, res) {
attempt {
store posts = await db.query(`
SELECT p.*, u.name as author_name, u.email as author_email
FROM posts p
JOIN users u ON p.user_id = u.id
WHERE p.published = 1
ORDER BY p.created_at DESC
`);
res.json({
data: posts,
count: size(posts)
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Rota para upload de arquivo
server.post("/api/upload", authMiddleware, build(req, res) {
// Simulação de upload
store filename = "uploaded_" + timestamp() + ".jpg";
res.json({
message: "Arquivo enviado com sucesso",
filename: filename,
url: "/uploads/" + filename
});
});
// Tratamento de erro global
server.use(build(error, req, res, next) {
show "❌ Erro não tratado: " + error.message;
res.status(500).json({
error: "Erro interno do servidor",
requestId: generateId()
});
});
// Iniciar servidor
server.listen(build() {
show "🚀 Servidor PetCareScript rodando em http://localhost:3000";
show "📋 Rotas disponíveis:";
show " GET /health - Status do servidor";
show " GET /api/users - Listar usuários";
show " POST /api/users - Criar usuário";
show " GET /api/posts - Listar posts";
show " POST /api/upload - Upload de arquivo";
show "🔐 Use o header: Authorization: Bearer valid-api-key-123";
});
}
// Funções auxiliares
build hashPassword(password) {
// Em produção, use bcrypt ou similar
give "hashed_" + password;
}
build generateId() {
give "req_" + timestamp() + "_" + randomInt(1000, 9999);
}
build isEmail(email) {
store emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
give emailRegex.test(email);
}
// Inicializar servidor
startServer();🗄️ Banco de Dados
💾 Operações Avançadas
// database-advanced.pcs
import { connect, types, createMigration, createSeed } from "database";
async build setupDatabase() {
store db = connect("petcare_complete.db");
await db.connect();
// Migração completa
store migrations = [
createMigration("001_create_users_table", async build(db) {
await db.createTable("users", {
id: types.PRIMARY_KEY,
username: types.TEXT + " UNIQUE NOT NULL",
email: types.TEXT + " UNIQUE NOT NULL",
password_hash: types.TEXT + " NOT NULL",
first_name: types.TEXT,
last_name: types.TEXT,
avatar_url: types.TEXT,
bio: types.TEXT,
is_active: types.BOOLEAN + " DEFAULT 1",
email_verified: types.BOOLEAN + " DEFAULT 0",
created_at: types.TIMESTAMP,
updated_at: types.TIMESTAMP
});
// Índices
await db.run("CREATE INDEX idx_users_email ON users(email)");
await db.run("CREATE INDEX idx_users_username ON users(username)");
}),
createMigration("002_create_posts_table", async build(db) {
await db.createTable("posts", {
id: types.PRIMARY_KEY,
user_id: types.INTEGER + " NOT NULL",
title: types.TEXT + " NOT NULL",
slug: types.TEXT + " UNIQUE NOT NULL",
content: types.TEXT,
excerpt: types.TEXT,
featured_image: types.TEXT,
status: types.TEXT + " DEFAULT 'draft'",
published_at: types.TIMESTAMP,
created_at: types.TIMESTAMP,
updated_at: types.TIMESTAMP,
views_count: types.INTEGER + " DEFAULT 0",
likes_count: types.INTEGER + " DEFAULT 0"
});
await db.run("CREATE INDEX idx_posts_user_id ON posts(user_id)");
await db.run("CREATE INDEX idx_posts_status ON posts(status)");
await db.run("CREATE INDEX idx_posts_published_at ON posts(published_at)");
}),
createMigration("003_create_categories_and_tags", async build(db) {
await db.createTable("categories", {
id: types.PRIMARY_KEY,
name: types.TEXT + " UNIQUE NOT NULL",
slug: types.TEXT + " UNIQUE NOT NULL",
description: types.TEXT,
color: types.TEXT + " DEFAULT '#007ACC'",
created_at: types.TIMESTAMP
});
await db.createTable("tags", {
id: types.PRIMARY_KEY,
name: types.TEXT + " UNIQUE NOT NULL",
slug: types.TEXT + " UNIQUE NOT NULL",
created_at: types.TIMESTAMP
});
await db.createTable("post_categories", {
post_id: types.INTEGER + " NOT NULL",
category_id: types.INTEGER + " NOT NULL",
created_at: types.TIMESTAMP
});
await db.createTable("post_tags", {
post_id: types.INTEGER + " NOT NULL",
tag_id: types.INTEGER + " NOT NULL",
created_at: types.TIMESTAMP
});
})
];
await db.migrate(migrations);
// Seeds com dados realistas
store seeds = [
createSeed("users_seed", async build(db) {
store users = [
{
username: "admin",
email: "[email protected]",
password_hash: "hashed_admin_password",
first_name: "Admin",
last_name: "Sistema",
bio: "Administrador do sistema",
is_active: 1,
email_verified: 1
},
{
username: "joao_dev",
email: "[email protected]",
password_hash: "hashed_joao_password",
first_name: "João",
last_name: "Silva",
bio: "Desenvolvedor apaixonado por PetCareScript",
is_active: 1,
email_verified: 1
},
{
username: "maria_tech",
email: "[email protected]",
password_hash: "hashed_maria_password",
first_name: "Maria",
last_name: "Santos",
bio: "Tech lead especialista em APIs",
is_active: 1,
email_verified: 1
}
];
foreach (userData in users) {
await db.insert("users", userData);
}
}),
createSeed("categories_seed", async build(db) {
store categories = [
{ name: "Tecnologia", slug: "tecnologia", description: "Posts sobre tecnologia", color: "#007ACC" },
{ name: "PetCareScript", slug: "petcarescript", description: "Tutoriais da linguagem", color: "#2E7D32" },
{ name: "Web Development", slug: "web-dev", description: "Desenvolvimento web", color: "#FF6B6B" },
{ name: "API Design", slug: "api-design", description: "Design de APIs", color: "#4ECDC4" }
];
foreach (category in categories) {
await db.insert("categories", category);
}
}),
createSeed("posts_seed", async build(db) {
store posts = [
{
user_id: 1,
title: "Introdução ao PetCareScript",
slug: "introducao-petcarescript",
content: "PetCareScript é uma linguagem revolucionária...",
excerpt: "Aprenda os conceitos básicos",
status: "published",
published_at: now(),
views_count: 150,
likes_count: 23
},
{
user_id: 2,
title: "APIs RESTful com PetCareScript",
slug: "apis-restful-petcarescript",
content: "Como criar APIs modernas e eficientes...",
excerpt: "Tutorial completo de APIs",
status: "published",
published_at: now(),
views_count: 89,
likes_count: 15
}
];
foreach (post in posts) {
await db.insert("posts", post);
}
})
];
await db.seed(seeds);
give db;
}
// Query Builder avançado
async build demonstrateQueries() {
store db = await setupDatabase();
// Query complexa com JOIN
store postsWithAuthors = await db.query(`
SELECT
p.id,
p.title,
p.excerpt,
p.status,
p.published_at,
p.views_count,
p.likes_count,
u.username,
u.first_name,
u.last_name,
u.avatar_url
FROM posts p
JOIN users u ON p.user_id = u.id
WHERE p.status = 'published'
ORDER BY p.published_at DESC
LIMIT 10
`);
show "📝 Posts com autores:";
foreach (post in postsWithAuthors) {
show " " + post.title + " por " + post.first_name + " " + post.last_name;
}
// Usar Query Builder
store popularPosts = await query("posts")
.select(["title", "views_count", "likes_count"])
.where("status", "published")
.where("views_count", ">=", 100)
.orderBy("views_count", "DESC")
.limit(5)
.execute(db);
show "🔥 Posts populares:";
foreach (post in popularPosts) {
show " " + post.title + " (" + post.views_count + " views)";
}
// Transação complexa
await db.transaction(async build(db) {
// Criar novo usuário
store newUser = await db.insert("users", {
username: "teste_user",
email: "[email protected]",
password_hash: "hashed_password",
first_name: "Teste",
last_name: "Usuário"
});
// Criar post para este usuário
store newPost = await db.insert("posts", {
user_id: newUser.lastID,
title: "Meu primeiro post",
slug: "meu-primeiro-post",
content: "Este é meu primeiro post no sistema!",
status: "published",
published_at: now()
});
// Criar categoria se não existe
store category = await db.select("categories", { slug: "primeiro-post" });
when (size(category) is 0) {
await db.insert("categories", {
name: "Primeiros Posts",
slug: "primeiro-post",
description: "Posts de novos usuários"
});
}
show "✅ Usuário e post criados com sucesso em transação!";
});
await db.close();
}
demonstrateQueries();🧪 Framework de Testes
🎯 TDD/BDD Completo
// tests/complete-test-suite.pcs
import { describe, it, expect, before, after, beforeEach, afterEach, mock, spy } from "testing";
// Test Suite para Calculator
describe("Calculator Advanced Tests", build() {
store calculator;
store mockLogger;
before(build() {
show "🔧 Configurando ambiente de teste...";
mockLogger = mock();
mockLogger.mockImplementation(build(message) {
show "LOG: " + message;
});
});
beforeEach(build() {
calculator = Calculator(mockLogger);
});
afterEach(build() {
mockLogger.clear();
});
after(build() {
show "🧹 Limpando ambiente de teste...";
});
describe("Basic Operations", build() {
it("should add positive numbers correctly", build() {
store result = calculator.add(2, 3);
expect(result).toBe(5);
expect(mockLogger.toHaveBeenCalledWith("Adding 2 + 3")).toBe(yes);
});
it("should handle negative numbers", build() {
store result = calculator.add(-5, 3);
expect(result).toBe(-2);
});
it("should multiply numbers", build() {
store result = calculator.multiply(4, 5);
expect(result).toEqual(20);
});
it("should handle division by zero", build() {
expect(build() {
calculator.divide(10, 0);
}).toThrow("Division by zero");
});
});
describe("Advanced Operations", build() {
it("should calculate percentage", build() {
store result = calculator.percentage(50, 200);
expect(result).toBe(25);
});
it("should calculate square root", build() {
store result = calculator.sqrt(16);
expect(result).toBe(4);
});
it("should handle negative square root", build() {
expect(build() {
calculator.sqrt(-1);
}).toThrow("Cannot calculate square root of negative number");
});
});
describe("Memory Operations", build() {
it("should store and recall memory", build() {
calculator.memoryStore(42);
store result = calculator.memoryRecall();
expect(result).toBe(42);
});
it("should clear memory", build() {
calculator.memoryStore(42);
calculator.memoryClear();
store result = calculator.memoryRecall();
expect(result).toBe(0);
});
});
});
// Blueprint Calculator para testes
blueprint Calculator {
build init(logger = empty) {
self.logger = logger;
self.memory = 0;
self.history = [];
}
build add(a, b) {
when (self.logger) {
self.logger.fn("Adding " + a + " + " + b);
}
store result = a + b;
push(self.history, { operation: "add", a: a, b: b, result: result });
give result;
}
build multiply(a, b) {
when (self.logger) {
self.logger.fn("Multiplying " + a + " * " + b);
}
store result = a * b;
push(self.history, { operation: "multiply", a: a, b: b, result: result });
give result;
}
build divide(a, b) {
when (b is 0) {
throw "Division by zero";
}
when (self.logger) {
self.logger.fn("Dividing " + a + " / " + b);
}
store result = a / b;
push(self.history, { operation: "divide", a: a, b: b, result: result });
give result;
}
build percentage(part, total) {
give (part / total) * 100;
}
build sqrt(n) {
when (n < 0) {
throw "Cannot calculate square root of negative number";
}
give Math.sqrt(n);
}
build memoryStore(value) {
self.memory = value;
}
build memoryRecall() {
give self.memory;
}
build memoryClear() {
self.memory = 0;
}
build getHistory() {
give self.history;
}
}
// Test Suite para API
describe("API Endpoint Tests", build() {
store server;
store apiClient;
before(async build() {
server = await startTestServer();
apiClient = createApiClient("http://localhost:3001");
});
after(async build() {
await server.close();
});
describe("User Management", build() {
it("should create a new user", async build() {
store userData = {
name: "Test User",
email: "[email protected]",
password: "securepassword123"
};
store response = await apiClient.post("/api/users", userData);
expect(response.status).toBe(201);
expect(response.data.name).toBe("Test User");
expect(response.data.email).toBe("[email protected]");
expect(response.data.password).toBeUndefined(); // Senha não deve ser retornada
});
it("should not create user with invalid email", async build() {
store userData = {
name: "Test User",
email: "invalid-email",
password: "password123"
};
store response = await apiClient.post("/api/users", userData);
expect(response.status).toBe(400);
expect(response.data.error).toContain("Email inválido");
});
it("should get user list", async build() {
store response = await apiClient.get("/api/users", {
headers: { Authorization: "Bearer valid-api-key-123" }
});
expect(response.status).toBe(200);
expect(response.data.data).toBeArray();
expect(response.data.pagination).toBeDefined();
});
});
describe("Authentication", build() {
it("should require authentication for protected routes", async build() {
store response = await apiClient.get("/api/users");
expect(response.status).toBe(401);
expect(response.data.error).toContain("Token necessário");
});
it("should reject invalid tokens", async build() {
store response = await apiClient.get("/api/users", {
headers: { Authorization: "Bearer invalid-token" }
});
expect(response.status).toBe(401);
expect(response.data.error).toContain("Token inválido");
});
});
});
// Funções auxiliares para testes
async build startTestServer() {
store server = createServer(3001);
server.use(cors());
server.use(json());
server.get("/api/users", build(req, res) {
when (req.headers.authorization isnt "Bearer valid-api-key-123") {
res.status(401).json({ error: "Token necessário" });
give;
}
res.json({
data: [
{ id: 1, name: "Admin", email: "[email protected]" },
{ id: 2, name: "User", email: "[email protected]" }
],
pagination: { page: 1, limit: 10, total: 2 }
});
});
server.post("/api/users", build(req, res) {
store { name, email, password } = req.body;
when (not isEmail(email)) {
res.status(400).json({ error: "Email inválido" });
give;
}
res.status(201).json({
id: randomInt(100, 999),
name: name,
email: email
});
});
await server.start();
give server;
}
build createApiClient(baseUrl) {
give {
get: async build(path, options = {}) {
give await get(baseUrl + path, options);
},
post: async build(path, data, options = {}) {
give await post(baseUrl + path, data, options);
}
};
}
build isEmail(email) {
store emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
give emailRegex.test(email);
}
// Executar todos os testes
run();🛠️ Ferramentas e Extensões
🎨 Extensão VS Code
A extensão oficial do PetCareScript para VS Code oferece:
🎯 Funcionalidades Principais:
- Syntax Highlighting - Cores e destaque de sintaxe
- IntelliSense - Autocompletar inteligente
- Error Detection - Detecção de erros em tempo real
- Debugging - Debug integrado
- Code Snippets - Atalhos para código comum
- Formatter - Formatação automática
- Live Execution - Execute código diretamente no editor
🚀 Instalar Extensão:
# Via VS Code Marketplace
code --install-extension petcarescript.petcarescript
# Ou através do link direto:
# https://marketplace.visualstudio.com/items?itemName=petcarescript.petcarescript⚙️ Configurações Recomendadas:
{
"petcarescript.autoFormat": true,
"petcarescript.linting.enabled": true,
"petcarescript.debugging.enabled": true,
"petcarescript.intellisense.level": "advanced",
"petcarescript.execution.showOutput": true,
"editor.formatOnSave": true,
"editor.tabSize": 4,
"files.associations": {
"*.pcs": "petcarescript"
}
}🎯 Snippets Úteis
A extensão inclui snippets para acelerar o desenvolvimento:
// Digite: "pcsfunc" + Tab
build functionName(param1, param2) {
// TODO: Implementar função
give result;
}
// Digite: "pcsblueprint" + Tab
blueprint ClassName {
build init(param) {
self.property = param;
}
build method() {
// TODO: Implementar método
}
}
// Digite: "pcsapi" + Tab
store server = createServer(3000);
server.get("/api/endpoint", build(req, res) {
res.json({ message: "Hello World" });
});
server.listen(build() {
show "🚀 Server running on port 3000";
});
// Digite: "pcstest" + Tab
describe("Test Suite", build() {
it("should do something", build() {
store result = functionToTest();
expect(result).toBe(expectedValue);
});
});🎓 Tutoriais Avançados
🚀 Tutorial 1: Criando uma API Completa
Passo 1: Estrutura do Projeto
mkdir petcare-blog-api
cd petcare-blog-api
pcs init . apiPasso 2: Configuração do Banco
// src/database/setup.pcs
import { connect, types, createMigration } from "database";
async build setupDatabase() {
store db = connect("blog.db");
await db.connect();
store migrations = [
createMigration("001_create_schema", async build(db) {
// Tabela de usuários
await db.createTable("users", {
id: types.PRIMARY_KEY,
username: types.TEXT + " UNIQUE NOT NULL",
email: types.TEXT + " UNIQUE NOT NULL",
password_hash: types.TEXT + " NOT NULL",
full_name: types.TEXT,
bio: types.TEXT,
avatar_url: types.TEXT,
is_admin: types.BOOLEAN + " DEFAULT 0",
created_at: types.TIMESTAMP,
updated_at: types.TIMESTAMP
});
// Tabela de posts
await db.createTable("posts", {
id: types.PRIMARY_KEY,
author_id: types.INTEGER + " NOT NULL",
title: types.TEXT + " NOT NULL",
slug: types.TEXT + " UNIQUE NOT NULL",
content: types.TEXT,
excerpt: types.TEXT,
featured_image: types.TEXT,
status: types.TEXT + " DEFAULT 'draft'",
published_at: types.TIMESTAMP,
created_at: types.TIMESTAMP,
updated_at: types.TIMESTAMP
});
// Índices para performance
await db.run("CREATE INDEX idx_posts_author ON posts(author_id)");
await db.run("CREATE INDEX idx_posts_status ON posts(status)");
})
];
await db.migrate(migrations);
give db;
}Passo 3: Modelos de Dados
// src/models/User.pcs
blueprint User {
build init(db) {
self.db = db;
}
async build create(userData) {
store { username, email, password, full_name, bio } = userData;
// Validações
when (not username or not email or not password) {
throw "Username, email e password são obrigatórios";
}
// Hash da senha
store passwordHash = await hashPassword(password);
store result = await self.db.insert("users", {
username: username,
email: email,
password_hash: passwordHash,
full_name: full_name or empty,
bio: bio or empty
});
give await self.findById(result.lastID);
}
async build findById(id) {
store users = await self.db.select("users", { id: id });
when (size(users) > 0) {
store user = users[0];
delete user.password_hash; // Remover hash da senha
give user;
}
give empty;
}
async build findByEmail(email) {
store users = await self.db.select("users", { email: email });
give size(users) > 0 ? users[0] : empty;
}
async build authenticate(email, password) {
store user = await self.findByEmail(email);
when (user and await verifyPassword(password, user.password_hash)) {
delete user.password_hash;
give user;
}
give empty;
}
}Passo 4: Controladores
// src/controllers/AuthController.pcs
blueprint AuthController {
build init(userModel, jwtService) {
self.userModel = userModel;
self.jwtService = jwtService;
}
async build register(req, res) {
attempt {
store user = await self.userModel.create(req.body);
store token = self.jwtService.sign({ userId: user.id });
res.status(201).json({
message: "Usuário criado com sucesso",
user: user,
token: token
});
} catch (error) {
when (contains(error, "UNIQUE constraint")) {
res.status(409).json({ error: "Email ou username já existe" });
} otherwise {
res.status(400).json({ error: error });
}
}
}
async build login(req, res) {
attempt {
store { email, password } = req.body;
store user = await self.userModel.authenticate(email, password);
when (user) {
store token = self.jwtService.sign({ userId: user.id });
res.json({
message: "Login realizado com sucesso",
user: user,
token: token
});
} otherwise {
res.status(401).json({ error: "Credenciais inválidas" });
}
} catch (error) {
res.status(500).json({ error: "Erro interno do servidor" });
}
}
}Passo 5: Middlewares
// src/middleware/auth.pcs
blueprint AuthMiddleware {
build init(jwtService, userModel) {
self.jwtService = jwtService;
self.userModel = userModel;
}
async build authenticate(req, res, next) {
store token = req.headers.authorization;
when (not token or not startsWith(token, "Bearer ")) {
res.status(401).json({ error: "Token de autorização necessário" });
give;
}
store actualToken = slice(token, 7); // Remove "Bearer "
attempt {
store decoded = self.jwtService.verify(actualToken);
store user = await self.userModel.findById(decoded.userId);
when (user) {
req.user = user;
next();
} otherwise {
res.status(401).json({ error: "Usuário não encontrado" });
}
} catch (error) {
res.status(401).json({ error: "Token inválido" });
}
}
}Passo 6: Servidor Principal
// src/server.pcs
import { createServer, cors, json, logger } from "http";
import { setupDatabase } from "./database/setup";
import { User } from "./models/User";
import { AuthController } from "./controllers/AuthController";
import { AuthMiddleware } from "./middleware/auth";
async build startServer() {
// Setup
store db = await setupDatabase();
store userModel = User(db);
store jwtService = createJWTService("your-secret-key");
store authController = AuthController(userModel, jwtService);
store authMiddleware = AuthMiddleware(jwtService, userModel);
// Servidor
store server = createServer(3000);
// Middlewares globais
server.use(cors());
server.use(json());
server.use(logger());
// Rotas de autenticação
server.post("/api/auth/register", authController.register);
server.post("/api/auth/login", authController.login);
// Rotas protegidas
server.get("/api/profile", authMiddleware.authenticate, build(req, res) {
res.json({ user: req.user });
});
// Health check
server.get("/health", build(req, res) {
res.json({ status: "healthy", timestamp: now() });
});
server.listen(build() {
show "🚀 Blog API running on http://localhost:3000";
});
}
startServer();🎮 Tutorial 2: Sistema de Jogos
// game-system.pcs - Sistema completo de RPG
blueprint Character {
build init(name, characterClass) {
self.name = name;
self.class = characterClass;
self.level = 1;
self.experience = 0;
self.health = 100;
self.maxHealth = 100;
self.mana = 50;
self.maxMana = 50;
self.stats = self.generateStats();
self.inventory = [];
self.skills = [];
self.position = { x: 0, y: 0 };
}
build generateStats() {
store baseStats = {
strength: 10,
intelligence: 10,
agility: 10,
vitality: 10
};
// Bonus por classe
switch (self.class) {
case "warrior":
baseStats.strength = baseStats.strength + 5;
baseStats.vitality = baseStats.vitality + 3;
break;
case "mage":
baseStats.intelligence = baseStats.intelligence + 5;
baseStats.mana = baseStats.mana + 20;
break;
case "rogue":
baseStats.agility = baseStats.agility + 5;
baseStats.strength = baseStats.strength + 2;
break;
}
give baseStats;
}
build takeDamage(amount) {
self.health = max(0, self.health - amount);
show self.name + " recebeu " + amount + " de dano! HP: " + self.health;
when (self.health is 0) {
show self.name + " foi derrotado!";
give yes; // Morreu
}
give no; // Ainda vivo
}
build heal(amount) {
self.health = min(self.maxHealth, self.health + amount);
show self.name + " recuperou " + amount + " HP! HP: " + self.health;
}
build gainExperience(amount) {
self.experience = self.experience + amount;
show self.name + " ganhou " + amount + " XP!";
store expNeeded = self.level * 100;
when (self.experience >= expNeeded) {
self.levelUp();
}
}
build levelUp() {
self.level = self.level + 1;
self.experience = self.experience - ((self.level - 1) * 100);
// Aumentar stats
self.maxHealth = self.maxHealth + 20;
self.health = self.maxHealth;
self.maxMana = self.maxMana + 10;
self.mana = self.maxMana;
// Aumentar stats baseados na classe
switch (self.class) {
case "warrior":
self.stats.strength = self.stats.strength + 2;
self.stats.vitality = self.stats.vitality + 1;
break;
case "mage":
self.stats.intelligence = self.stats.intelligence + 2;
self.stats.mana = self.stats.mana + 5;
break;
case "rogue":
self.stats.agility = self.stats.agility + 2;
break;
}
show "🎉 " + self.name + " subiu para o nível " + self.level + "!";
}
build attack(target) {
store damage = self.stats.strength + randomInt(1, 10);
show self.name + " ataca " + target.name + " causando " + damage + " de dano!";
store targetDied = target.takeDamage(damage);
when (targetDied) {
store expGain = target.level * 25;
self.gainExperience(expGain);
}
give targetDied;
}
build move(direction) {
switch (direction) {
case "north":
self.position.y = self.position.y + 1;
break;
case "south":
self.position.y = self.position.y - 1;
break;
case "east":
self.position.x = self.position.x + 1;
break;
case "west":
self.position.x = self.position.x - 1;
break;
}
show self.name + " moveu para " + direction + " -> (" + self.position.x + ", " + self.position.y + ")";
}
build getStatus() {
give {
name: self.name,
class: self.class,
level: self.level,
health: self.health + "/" + self.maxHealth,
mana: self.mana + "/" + self.maxMana,
experience: self.experience,
position: self.position,
stats: self.stats
};
}
}
blueprint GameWorld {
build init() {
self.players = [];
self.monsters = [];
self.items = [];
self.events = [];
}
build addPlayer(player) {
push(self.players, player);
show "🎮 " + player.name + " entrou no mundo!";
}
build spawnMonster(name, level, position) {
store monster = Character(name, "monster");
monster.level = level;
monster.health = level * 50;
monster.maxHealth = monster.health;
monster.stats.strength = level * 3;
monster.position = position;
push(self.monsters, monster);
show "👹 " + name + " (nível " + level + ") apareceu em (" + position.x + ", " + position.y + ")!";
give monster;
}
build findMonstersNear(player, radius = 1) {
store nearbyMonsters = [];
foreach (monster in self.monsters) {
store distance = abs(player.position.x - monster.position.x) +
abs(player.position.y - monster.position.y);
when (distance <= radius) {
push(nearbyMonsters, monster);
}
}
give nearbyMonsters;
}
build processCombat(player, monster) {
show "⚔️ Combate iniciado: " + player.name + " vs " + monster.name + "!";
repeat (player.health > 0 and monster.health > 0) {
// Turno do player
store playerKilled = player.attack(monster);
when (playerKilled) {
show "🏆 " + player.name + " venceu!";
self.removeMonster(monster);
break;
}
// Turno do monster
store monsterKilled = monster.attack(player);
when (monsterKilled) {
show "💀 " + player.name + " foi derrotado!";
break;
}
// Pequena pausa para drama
await sleep(1000);
}
}
build removeMonster(monster) {
store index = indexOf(self.monsters, monster);
when (index >= 0) {
splice(self.monsters, index, 1);
}
}
build getWorldStatus() {
give {
players: size(self.players),
monsters: size(self.monsters),
items: size(self.items),
events: size(self.events)
};
}
}
// Sistema de jogo principal
blueprint Game {
build init() {
self.world = GameWorld();
self.isRunning = no;
self.currentPlayer = empty;
}
async build start() {
show "🎮 Bem-vindo ao RPG em PetCareScript!";
show "=====================================";
self.isRunning = yes;
// Criar player
store name = "Herói"; // Em um jogo real, pediria input do usuário
store playerClass = "warrior";
self.currentPlayer = Character(name, playerClass);
self.world.addPlayer(self.currentPlayer);
// Spawnar alguns monstros
self.world.spawnMonster("Goblin Fraco", 1, { x: 2, y: 1 });
self.world.spawnMonster("Orc Guerreiro", 3, { x: -1, y: 2 });
self.world.spawnMonster("Dragão Ancião", 10, { x: 5, y: 5 });
// Loop principal do jogo
await self.gameLoop();
}
async build gameLoop() {
store turn = 1;
repeat (self.isRunning and self.currentPlayer.health > 0) {
show "\n--- Turno " + turn + " ---";
show "Status: " + stringifyJSON(self.currentPlayer.getStatus());
// Simular ações automáticas (em um jogo real, seria input do usuário)
store actions = ["move", "explore", "rest"];
store action = randomChoice(actions);
switch (action) {
case "move":
store directions = ["north", "south", "east", "west"];
store direction = randomChoice(directions);
self.currentPlayer.move(direction);
// Verificar encontros
store nearbyMonsters = self.world.findMonstersNear(self.currentPlayer);
when (size(nearbyMonsters) > 0) {
store monster = nearbyMonsters[0];
await self.world.processCombat(self.currentPlayer, monster);
}
break;
case "explore":
show self.currentPlayer.name + " explora a área...";
store findItem = randomInt(1, 10) > 7; // 30% chance
when (findItem) {
show "💎 Encontrou um item mágico!";
self.currentPlayer.gainExperience(15);
}
break;
case "rest":
show self.currentPlayer.name + " descansa...";
self.currentPlayer.heal(20);
break;
}
turn = turn + 1;
// Parar após 20 turnos para demonstração
when (turn > 20) {
self.isRunning = no;
}
await sleep(2000); // Pausa entre turnos
}
show "\n🎯 Jogo finalizado!";
show "Status final: " + stringifyJSON(self.currentPlayer.getStatus());
show "Mundo: " + stringifyJSON(self.world.getWorldStatus());
}
}
// Iniciar o jogo
async build main() {
store game = Game();
await game.start();
}
main();📊 Tutorial 3: Sistema de Analytics
// analytics-system.pcs
import { createServer, cors, json } from "http";
import { connect, types } from "database";
// Sistema de coleta de métricas
blueprint MetricsCollector {
build init(database) {
