treste 2.5.1 → 2.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,12 +37,51 @@ var __importStar = (this && this.__importStar) || (function () {
37
37
  };
38
38
  })();
39
39
  Object.defineProperty(exports, "__esModule", { value: true });
40
- exports.StdModules = exports.StdIO = exports.StdProcess = exports.StdPath = exports.StdRegEx = exports.StdCrypto = exports.StdDate = exports.StdJSON = exports.StdFileSystem = exports.StdDatabase = exports.StdGUI = exports.StdAsync = exports.StdHTTP = void 0;
40
+ exports.StdModules = exports.StdTest = exports.StdStyle = exports.StdDOM = exports.StdIO = exports.StdProcess = exports.StdPath = exports.StdRegEx = exports.StdCrypto = exports.StdDate = exports.StdJSON = exports.StdFileSystem = exports.StdDatabase = exports.StdGUI = exports.StdAsync = exports.StdHTTP = void 0;
41
41
  const http = __importStar(require("http"));
42
42
  const https = __importStar(require("https"));
43
43
  const fs = __importStar(require("fs"));
44
44
  const path = __importStar(require("path"));
45
45
  const url_1 = require("url");
46
+ const crypto = __importStar(require("crypto"));
47
+ const readline = __importStar(require("readline"));
48
+ // Database drivers - lazy loading
49
+ let Database;
50
+ let mysql;
51
+ let pg;
52
+ function loadSQLite() {
53
+ if (!Database) {
54
+ try {
55
+ Database = require('better-sqlite3');
56
+ }
57
+ catch (e) {
58
+ // Silently fail - will throw error when used
59
+ }
60
+ }
61
+ return Database;
62
+ }
63
+ function loadMySQL() {
64
+ if (!mysql) {
65
+ try {
66
+ mysql = require('mysql2/promise');
67
+ }
68
+ catch (e) {
69
+ // Silently fail - will throw error when used
70
+ }
71
+ }
72
+ return mysql;
73
+ }
74
+ function loadPostgreSQL() {
75
+ if (!pg) {
76
+ try {
77
+ pg = require('pg');
78
+ }
79
+ catch (e) {
80
+ // Silently fail - will throw error when used
81
+ }
82
+ }
83
+ return pg;
84
+ }
46
85
  /**
47
86
  * ========================================
48
87
  * HTTP Module - Cliente e Servidor HTTP
@@ -1365,68 +1404,380 @@ StdGUI._ipcHandlersRegistered = false;
1365
1404
  */
1366
1405
  class StdDatabase {
1367
1406
  /**
1368
- * Open Database
1407
+ * Sanitiza query SQL substituindo ? pelos valores de forma segura (Prevent SQL Injection)
1408
+ */
1409
+ static sanitizeQuery(query, params) {
1410
+ if (!params || params.length === 0) {
1411
+ return query;
1412
+ }
1413
+ // Escapar valores para prevenir SQL Injection
1414
+ const escapeValue = (value) => {
1415
+ if (value === null || value === undefined) {
1416
+ return 'NULL';
1417
+ }
1418
+ if (typeof value === 'number') {
1419
+ return String(value);
1420
+ }
1421
+ if (typeof value === 'boolean') {
1422
+ return value ? '1' : '0';
1423
+ }
1424
+ // String: escapar aspas simples e barras
1425
+ const escaped = String(value)
1426
+ .replace(/\\/g, '\\\\')
1427
+ .replace(/'/g, "''")
1428
+ .replace(/"/g, '""');
1429
+ return `'${escaped}'`;
1430
+ };
1431
+ // Substituir cada ? pelo valor correspondente
1432
+ let safeQuery = query;
1433
+ let paramIndex = 0;
1434
+ // Substituir ? pelos valores escapados
1435
+ safeQuery = safeQuery.replace(/\?/g, () => {
1436
+ if (paramIndex < params.length) {
1437
+ const value = escapeValue(params[paramIndex]);
1438
+ paramIndex++;
1439
+ return value;
1440
+ }
1441
+ return '?'; // Se não houver parâmetro suficiente, manter ?
1442
+ });
1443
+ return safeQuery;
1444
+ }
1445
+ /**
1446
+ * Detect database type from connection string or path
1447
+ */
1448
+ static detectDBType(connection) {
1449
+ if (connection.startsWith('mysql://') || connection.startsWith('mysql2://')) {
1450
+ return 'mysql';
1451
+ }
1452
+ if (connection.startsWith('postgresql://') || connection.startsWith('postgres://')) {
1453
+ return 'postgresql';
1454
+ }
1455
+ if (connection.endsWith('.db') || connection.includes('/') || connection.includes('\\')) {
1456
+ return 'sqlite';
1457
+ }
1458
+ return 'unknown';
1459
+ }
1460
+ /**
1461
+ * Parse MySQL connection string
1462
+ */
1463
+ static parseMySQLConnection(connectionString) {
1464
+ try {
1465
+ const url = new url_1.URL(connectionString);
1466
+ return {
1467
+ host: url.hostname,
1468
+ port: parseInt(url.port) || 3306,
1469
+ user: url.username,
1470
+ password: url.password,
1471
+ database: url.pathname.substring(1),
1472
+ };
1473
+ }
1474
+ catch (e) {
1475
+ throw new Error(`Invalid MySQL connection string: ${connectionString}`);
1476
+ }
1477
+ }
1478
+ /**
1479
+ * Parse PostgreSQL connection string
1369
1480
  */
1370
- static openDB(dbPath) {
1481
+ static parsePostgreSQLConnection(connectionString) {
1482
+ try {
1483
+ const url = new url_1.URL(connectionString);
1484
+ return {
1485
+ host: url.hostname,
1486
+ port: parseInt(url.port) || 5432,
1487
+ user: url.username,
1488
+ password: url.password,
1489
+ database: url.pathname.substring(1),
1490
+ ssl: url.searchParams.get('ssl') === 'true',
1491
+ };
1492
+ }
1493
+ catch (e) {
1494
+ throw new Error(`Invalid PostgreSQL connection string: ${connectionString}`);
1495
+ }
1496
+ }
1497
+ /**
1498
+ * Open Database - Supports SQLite, MySQL, PostgreSQL
1499
+ */
1500
+ static openDB(connection) {
1501
+ // If it's an object, treat as config
1502
+ if (typeof connection === 'object' && connection !== null) {
1503
+ if (connection.type === 'mysql' || connection.host && !connection.path) {
1504
+ return this.openMySQL(connection);
1505
+ }
1506
+ if (connection.type === 'postgresql' || connection.type === 'postgres') {
1507
+ return this.openPostgreSQL(connection);
1508
+ }
1509
+ }
1510
+ // Detect type from connection string
1511
+ const dbType = this.detectDBType(String(connection));
1512
+ if (dbType === 'mysql') {
1513
+ const config = this.parseMySQLConnection(String(connection));
1514
+ return this.openMySQL(config);
1515
+ }
1516
+ if (dbType === 'postgresql') {
1517
+ const config = this.parsePostgreSQLConnection(String(connection));
1518
+ return this.openPostgreSQL(config);
1519
+ }
1520
+ // Default to SQLite
1521
+ return this.openSQLite(String(connection));
1522
+ }
1523
+ /**
1524
+ * Open SQLite Database (real implementation)
1525
+ */
1526
+ static openSQLite(dbPath) {
1371
1527
  if (this.dbConnections.has(dbPath)) {
1372
1528
  return this.dbConnections.get(dbPath);
1373
1529
  }
1374
- // For now, use file-based mock database
1375
- const db = {
1376
- path: dbPath,
1377
- execute: (query, params = []) => {
1378
- console.log(`[DB] Executing: ${query}`, params);
1379
- return { success: true };
1380
- },
1381
- query: (query, params = []) => {
1382
- console.log(`[DB] Querying: ${query}`, params);
1383
- return [];
1384
- },
1385
- transaction: (fn) => {
1386
- console.log('[DB] Transaction started');
1387
- fn();
1388
- console.log('[DB] Transaction committed');
1389
- },
1390
- close: () => {
1391
- console.log(`[DB] Closed: ${dbPath}`);
1392
- this.dbConnections.delete(dbPath);
1393
- },
1394
- };
1395
- this.dbConnections.set(dbPath, db);
1396
- return db;
1530
+ const Database = loadSQLite();
1531
+ if (!Database) {
1532
+ throw new Error('better-sqlite3 is not installed. Install it with: npm install better-sqlite3');
1533
+ }
1534
+ try {
1535
+ const db = new Database(dbPath);
1536
+ const dbWrapper = {
1537
+ path: dbPath,
1538
+ _db: db,
1539
+ execute: (query, params = []) => {
1540
+ try {
1541
+ const stmt = db.prepare(query);
1542
+ const result = stmt.run(...params);
1543
+ return {
1544
+ success: true,
1545
+ lastInsertRowid: result.lastInsertRowid,
1546
+ changes: result.changes
1547
+ };
1548
+ }
1549
+ catch (error) {
1550
+ throw new Error(`SQLite execute error: ${error.message}`);
1551
+ }
1552
+ },
1553
+ query: (query, params = []) => {
1554
+ try {
1555
+ const stmt = db.prepare(query);
1556
+ return stmt.all(...params);
1557
+ }
1558
+ catch (error) {
1559
+ throw new Error(`SQLite query error: ${error.message}`);
1560
+ }
1561
+ },
1562
+ transaction: (fn) => {
1563
+ try {
1564
+ const transaction = db.transaction(fn);
1565
+ transaction();
1566
+ }
1567
+ catch (error) {
1568
+ throw new Error(`SQLite transaction error: ${error.message}`);
1569
+ }
1570
+ },
1571
+ close: () => {
1572
+ try {
1573
+ db.close();
1574
+ this.dbConnections.delete(dbPath);
1575
+ }
1576
+ catch (error) {
1577
+ throw new Error(`SQLite close error: ${error.message}`);
1578
+ }
1579
+ },
1580
+ };
1581
+ this.dbConnections.set(dbPath, dbWrapper);
1582
+ return dbWrapper;
1583
+ }
1584
+ catch (error) {
1585
+ throw new Error(`Failed to open SQLite database: ${error.message}`);
1586
+ }
1587
+ }
1588
+ /**
1589
+ * Open MySQL Database (real implementation)
1590
+ */
1591
+ static openMySQL(config) {
1592
+ const connectionKey = `mysql://${config.host}:${config.port}/${config.database}`;
1593
+ if (this.dbConnections.has(connectionKey)) {
1594
+ return this.dbConnections.get(connectionKey);
1595
+ }
1596
+ const mysql = loadMySQL();
1597
+ if (!mysql) {
1598
+ throw new Error('mysql2 is not installed. Install it with: npm install mysql2');
1599
+ }
1600
+ try {
1601
+ const pool = mysql.createPool({
1602
+ host: config.host || 'localhost',
1603
+ port: config.port || 3306,
1604
+ user: config.user || 'root',
1605
+ password: config.password || '',
1606
+ database: config.database,
1607
+ waitForConnections: true,
1608
+ connectionLimit: 10,
1609
+ queueLimit: 0,
1610
+ });
1611
+ const dbWrapper = {
1612
+ _pool: pool,
1613
+ _config: config,
1614
+ execute: async (query, params = []) => {
1615
+ try {
1616
+ const [result] = await pool.execute(query, params);
1617
+ return {
1618
+ success: true,
1619
+ insertId: result.insertId,
1620
+ affectedRows: result.affectedRows
1621
+ };
1622
+ }
1623
+ catch (error) {
1624
+ throw new Error(`MySQL execute error: ${error.message}`);
1625
+ }
1626
+ },
1627
+ query: async (query, params = []) => {
1628
+ try {
1629
+ const [rows] = await pool.execute(query, params);
1630
+ return rows;
1631
+ }
1632
+ catch (error) {
1633
+ throw new Error(`MySQL query error: ${error.message}`);
1634
+ }
1635
+ },
1636
+ transaction: async (fn) => {
1637
+ const connection = await pool.getConnection();
1638
+ try {
1639
+ await connection.beginTransaction();
1640
+ await fn(connection);
1641
+ await connection.commit();
1642
+ }
1643
+ catch (error) {
1644
+ await connection.rollback();
1645
+ throw new Error(`MySQL transaction error: ${error.message}`);
1646
+ }
1647
+ finally {
1648
+ connection.release();
1649
+ }
1650
+ },
1651
+ close: async () => {
1652
+ try {
1653
+ await pool.end();
1654
+ this.dbConnections.delete(connectionKey);
1655
+ }
1656
+ catch (error) {
1657
+ throw new Error(`MySQL close error: ${error.message}`);
1658
+ }
1659
+ },
1660
+ };
1661
+ this.dbConnections.set(connectionKey, dbWrapper);
1662
+ return dbWrapper;
1663
+ }
1664
+ catch (error) {
1665
+ throw new Error(`Failed to open MySQL database: ${error.message}`);
1666
+ }
1667
+ }
1668
+ /**
1669
+ * Open PostgreSQL Database (real implementation)
1670
+ */
1671
+ static openPostgreSQL(config) {
1672
+ const connectionKey = `postgresql://${config.host}:${config.port}/${config.database}`;
1673
+ if (this.dbConnections.has(connectionKey)) {
1674
+ return this.dbConnections.get(connectionKey);
1675
+ }
1676
+ const pgLib = loadPostgreSQL();
1677
+ if (!pgLib) {
1678
+ throw new Error('pg is not installed. Install it with: npm install pg');
1679
+ }
1680
+ try {
1681
+ const pool = new pgLib.Pool({
1682
+ host: config.host || 'localhost',
1683
+ port: config.port || 5432,
1684
+ user: config.user || 'postgres',
1685
+ password: config.password || '',
1686
+ database: config.database,
1687
+ max: 20,
1688
+ idleTimeoutMillis: 30000,
1689
+ connectionTimeoutMillis: 2000,
1690
+ ssl: config.ssl || false,
1691
+ });
1692
+ const dbWrapper = {
1693
+ _pool: pool,
1694
+ _config: config,
1695
+ execute: async (query, params = []) => {
1696
+ try {
1697
+ const result = await pool.query(query, params);
1698
+ return {
1699
+ success: true,
1700
+ rowCount: result.rowCount,
1701
+ rows: result.rows
1702
+ };
1703
+ }
1704
+ catch (error) {
1705
+ throw new Error(`PostgreSQL execute error: ${error.message}`);
1706
+ }
1707
+ },
1708
+ query: async (query, params = []) => {
1709
+ try {
1710
+ const result = await pool.query(query, params);
1711
+ return result.rows;
1712
+ }
1713
+ catch (error) {
1714
+ throw new Error(`PostgreSQL query error: ${error.message}`);
1715
+ }
1716
+ },
1717
+ transaction: async (fn) => {
1718
+ const client = await pool.connect();
1719
+ try {
1720
+ await client.query('BEGIN');
1721
+ await fn(client);
1722
+ await client.query('COMMIT');
1723
+ }
1724
+ catch (error) {
1725
+ await client.query('ROLLBACK');
1726
+ throw new Error(`PostgreSQL transaction error: ${error.message}`);
1727
+ }
1728
+ finally {
1729
+ client.release();
1730
+ }
1731
+ },
1732
+ close: async () => {
1733
+ try {
1734
+ await pool.end();
1735
+ this.dbConnections.delete(connectionKey);
1736
+ }
1737
+ catch (error) {
1738
+ throw new Error(`PostgreSQL close error: ${error.message}`);
1739
+ }
1740
+ },
1741
+ };
1742
+ this.dbConnections.set(connectionKey, dbWrapper);
1743
+ return dbWrapper;
1744
+ }
1745
+ catch (error) {
1746
+ throw new Error(`Failed to open PostgreSQL database: ${error.message}`);
1747
+ }
1397
1748
  }
1398
1749
  /**
1399
1750
  * Query Builder
1400
1751
  */
1401
1752
  static createQueryBuilder(table) {
1402
1753
  const builder = {
1403
- table,
1754
+ table: table,
1404
1755
  selectFields: '*',
1405
1756
  whereClause: '',
1406
1757
  orderClause: '',
1407
1758
  limitValue: '',
1408
1759
  conditions: [],
1409
- select: function (fields) {
1410
- this.selectFields = fields;
1411
- return this;
1412
- },
1413
- where: function (condition) {
1414
- this.whereClause = `WHERE ${condition}`;
1415
- return this;
1416
- },
1417
- order: function (field) {
1418
- this.orderClause = `ORDER BY ${field}`;
1419
- return this;
1420
- },
1421
- limit: function (n) {
1422
- this.limitValue = `LIMIT ${n}`;
1423
- return this;
1424
- },
1425
- execute: function () {
1426
- const sql = `SELECT ${this.selectFields} FROM ${this.table} ${this.whereClause} ${this.orderClause} ${this.limitValue}`;
1427
- console.log(`[Query Builder] ${sql}`);
1428
- return [];
1429
- },
1760
+ };
1761
+ builder.select = function (fields) {
1762
+ builder.selectFields = fields;
1763
+ return builder;
1764
+ };
1765
+ builder.where = function (condition) {
1766
+ builder.whereClause = `WHERE ${condition}`;
1767
+ return builder;
1768
+ };
1769
+ builder.order = function (field) {
1770
+ builder.orderClause = `ORDER BY ${field}`;
1771
+ return builder;
1772
+ };
1773
+ builder.limit = function (n) {
1774
+ builder.limitValue = `LIMIT ${n}`;
1775
+ return builder;
1776
+ };
1777
+ builder.execute = function () {
1778
+ const sql = `SELECT ${builder.selectFields} FROM ${builder.table} ${builder.whereClause} ${builder.orderClause} ${builder.limitValue}`;
1779
+ console.log(`[Query Builder] ${sql}`);
1780
+ return [];
1430
1781
  };
1431
1782
  return builder;
1432
1783
  }
@@ -1634,7 +1985,6 @@ exports.StdDate = StdDate;
1634
1985
  * Crypto Module
1635
1986
  * ========================================
1636
1987
  */
1637
- const crypto = __importStar(require("crypto"));
1638
1988
  class StdCrypto {
1639
1989
  /**
1640
1990
  * Hash MD5
@@ -1876,7 +2226,6 @@ exports.StdProcess = StdProcess;
1876
2226
  * IO Module - Entrada e Saída
1877
2227
  * ========================================
1878
2228
  */
1879
- const readline = __importStar(require("readline"));
1880
2229
  class StdIO {
1881
2230
  /**
1882
2231
  * Initialize readline interface if needed
@@ -1998,6 +2347,427 @@ class StdIO {
1998
2347
  }
1999
2348
  exports.StdIO = StdIO;
2000
2349
  StdIO.rl = null;
2350
+ /**
2351
+ * ========================================
2352
+ * DOM Module - Manipulação de DOM (Front-End)
2353
+ * ========================================
2354
+ */
2355
+ class StdDOM {
2356
+ /**
2357
+ * Verifica se está rodando no navegador
2358
+ */
2359
+ static isBrowser() {
2360
+ return typeof globalThis.window !== 'undefined' && typeof globalThis.document !== 'undefined';
2361
+ }
2362
+ /**
2363
+ * Selecionar elemento (querySelector)
2364
+ */
2365
+ static selecionar(seletor) {
2366
+ if (!this.isBrowser()) {
2367
+ throw new Error('DOM.selecionar só funciona no navegador. Use --mode web para compilar.');
2368
+ }
2369
+ return globalThis.document.querySelector(seletor);
2370
+ }
2371
+ static select(seletor) {
2372
+ return this.selecionar(seletor);
2373
+ }
2374
+ /**
2375
+ * Adicionar evento (addEventListener)
2376
+ */
2377
+ static evento(elemento, tipo, callback) {
2378
+ if (!this.isBrowser()) {
2379
+ throw new Error('DOM.evento só funciona no navegador. Use --mode web para compilar.');
2380
+ }
2381
+ if (elemento && elemento.addEventListener) {
2382
+ elemento.addEventListener(tipo, callback);
2383
+ }
2384
+ }
2385
+ static addEvent(elemento, tipo, callback) {
2386
+ this.evento(elemento, tipo, callback);
2387
+ }
2388
+ /**
2389
+ * Manipular texto (innerText)
2390
+ */
2391
+ static texto(elemento, valor) {
2392
+ if (!this.isBrowser()) {
2393
+ throw new Error('DOM.texto só funciona no navegador. Use --mode web para compilar.');
2394
+ }
2395
+ if (!elemento)
2396
+ return '';
2397
+ if (valor !== undefined) {
2398
+ elemento.innerText = valor;
2399
+ }
2400
+ else {
2401
+ return elemento.innerText || '';
2402
+ }
2403
+ }
2404
+ static setText(elemento, valor) {
2405
+ return this.texto(elemento, valor);
2406
+ }
2407
+ /**
2408
+ * Manipular HTML (innerHTML)
2409
+ */
2410
+ static html(elemento, valor) {
2411
+ if (!this.isBrowser()) {
2412
+ throw new Error('DOM.html só funciona no navegador. Use --mode web para compilar.');
2413
+ }
2414
+ if (!elemento)
2415
+ return '';
2416
+ if (valor !== undefined) {
2417
+ elemento.innerHTML = valor;
2418
+ }
2419
+ else {
2420
+ return elemento.innerHTML || '';
2421
+ }
2422
+ }
2423
+ static setHTML(elemento, valor) {
2424
+ return this.html(elemento, valor);
2425
+ }
2426
+ /**
2427
+ * Obter/definir valor de input (value)
2428
+ */
2429
+ static valor(elemento, valor) {
2430
+ if (!this.isBrowser()) {
2431
+ throw new Error('DOM.valor só funciona no navegador. Use --mode web para compilar.');
2432
+ }
2433
+ if (!elemento)
2434
+ return null;
2435
+ if (valor !== undefined) {
2436
+ elemento.value = valor;
2437
+ }
2438
+ else {
2439
+ return elemento.value !== undefined ? elemento.value : null;
2440
+ }
2441
+ }
2442
+ static val(elemento, valor) {
2443
+ return this.valor(elemento, valor);
2444
+ }
2445
+ /**
2446
+ * Criar elemento (createElement)
2447
+ */
2448
+ static criar(tag) {
2449
+ if (!this.isBrowser()) {
2450
+ throw new Error('DOM.criar só funciona no navegador. Use --mode web para compilar.');
2451
+ }
2452
+ return globalThis.document.createElement(tag);
2453
+ }
2454
+ static create(tag) {
2455
+ return this.criar(tag);
2456
+ }
2457
+ /**
2458
+ * Adicionar elemento ao DOM (appendChild)
2459
+ */
2460
+ static adicionar(parent, child) {
2461
+ if (!this.isBrowser()) {
2462
+ throw new Error('DOM.adicionar só funciona no navegador. Use --mode web para compilar.');
2463
+ }
2464
+ if (parent && parent.appendChild && child) {
2465
+ parent.appendChild(child);
2466
+ }
2467
+ }
2468
+ static append(parent, child) {
2469
+ this.adicionar(parent, child);
2470
+ }
2471
+ /**
2472
+ * Remover elemento (removeChild)
2473
+ */
2474
+ static remover(elemento) {
2475
+ if (!this.isBrowser()) {
2476
+ throw new Error('DOM.remover só funciona no navegador. Use --mode web para compilar.');
2477
+ }
2478
+ if (elemento && elemento.parentNode) {
2479
+ elemento.parentNode.removeChild(elemento);
2480
+ }
2481
+ }
2482
+ static remove(elemento) {
2483
+ this.remover(elemento);
2484
+ }
2485
+ /**
2486
+ * Obter atributo (getAttribute)
2487
+ */
2488
+ static atributo(elemento, nome) {
2489
+ if (!this.isBrowser()) {
2490
+ throw new Error('DOM.atributo só funciona no navegador. Use --mode web para compilar.');
2491
+ }
2492
+ if (!elemento || !elemento.getAttribute)
2493
+ return null;
2494
+ return elemento.getAttribute(nome);
2495
+ }
2496
+ static getAttr(elemento, nome) {
2497
+ return this.atributo(elemento, nome);
2498
+ }
2499
+ /**
2500
+ * Definir atributo (setAttribute)
2501
+ */
2502
+ static definirАтрибут(elemento, nome, valor) {
2503
+ if (!this.isBrowser()) {
2504
+ throw new Error('DOM.definirАтрибут só funciona no navegador. Use --mode web para compilar.');
2505
+ }
2506
+ if (elemento && elemento.setAttribute) {
2507
+ elemento.setAttribute(nome, valor);
2508
+ }
2509
+ }
2510
+ static setAttr(elemento, nome, valor) {
2511
+ this.definirАтрибут(elemento, nome, valor);
2512
+ }
2513
+ }
2514
+ exports.StdDOM = StdDOM;
2515
+ /**
2516
+ * ========================================
2517
+ * Style Module - Gerenciamento de CSS
2518
+ * ========================================
2519
+ */
2520
+ class StdStyle {
2521
+ /**
2522
+ * Verifica se está rodando no navegador
2523
+ */
2524
+ static isBrowser() {
2525
+ return typeof globalThis.window !== 'undefined' && typeof globalThis.document !== 'undefined';
2526
+ }
2527
+ /**
2528
+ * Carregar CSS de CDN (Bootstrap, Tailwind, etc)
2529
+ */
2530
+ static carregarCDN(url) {
2531
+ if (!this.isBrowser()) {
2532
+ throw new Error('Style.carregarCDN só funciona no navegador. Use --mode web para compilar.');
2533
+ }
2534
+ const doc = globalThis.document;
2535
+ const link = doc.createElement('link');
2536
+ link.rel = 'stylesheet';
2537
+ link.href = url;
2538
+ doc.head.appendChild(link);
2539
+ }
2540
+ static loadCDN(url) {
2541
+ this.carregarCDN(url);
2542
+ }
2543
+ /**
2544
+ * Carregar CSS de arquivo local
2545
+ * No modo web, o compilador deve injetar o conteúdo do arquivo
2546
+ */
2547
+ static carregarАрхив(caminho) {
2548
+ if (!this.isBrowser()) {
2549
+ // No Node.js, apenas log (o compilador web deve injetar)
2550
+ console.log(`[Style] Carregando CSS: ${caminho} (será injetado no bundle)`);
2551
+ return;
2552
+ }
2553
+ // No navegador, criar link para o arquivo
2554
+ const doc = globalThis.document;
2555
+ const link = doc.createElement('link');
2556
+ link.rel = 'stylesheet';
2557
+ link.href = caminho;
2558
+ doc.head.appendChild(link);
2559
+ }
2560
+ static loadFile(caminho) {
2561
+ this.carregarАрхив(caminho);
2562
+ }
2563
+ /**
2564
+ * Aplicar estilos inline a um elemento
2565
+ */
2566
+ static aplicar(elemento, estilos) {
2567
+ if (!this.isBrowser()) {
2568
+ throw new Error('Style.aplicar só funciona no navegador. Use --mode web para compilar.');
2569
+ }
2570
+ if (!elemento || !elemento.style)
2571
+ return;
2572
+ // Mapear propriedades em cirílico para CSS
2573
+ const mapeamento = {
2574
+ cor: 'color',
2575
+ фон: 'backgroundColor',
2576
+ фонЦвет: 'backgroundColor',
2577
+ ширина: 'width',
2578
+ высота: 'height',
2579
+ отступ: 'padding',
2580
+ маржа: 'margin',
2581
+ граница: 'border',
2582
+ размерШрифта: 'fontSize',
2583
+ весШрифта: 'fontWeight',
2584
+ выравнивание: 'textAlign',
2585
+ отображение: 'display',
2586
+ };
2587
+ for (const key in estilos) {
2588
+ const cssProp = mapeamento[key] || key;
2589
+ elemento.style[cssProp] = estilos[key];
2590
+ }
2591
+ }
2592
+ static apply(elemento, estilos) {
2593
+ this.aplicar(elemento, estilos);
2594
+ }
2595
+ /**
2596
+ * Obter estilo computado
2597
+ */
2598
+ static obter(elemento, propriedade) {
2599
+ if (!this.isBrowser()) {
2600
+ throw new Error('Style.obter só funciona no navegador. Use --mode web para compilar.');
2601
+ }
2602
+ if (!elemento)
2603
+ return null;
2604
+ const win = globalThis.window;
2605
+ const computed = win.getComputedStyle ? win.getComputedStyle(elemento) : null;
2606
+ return computed ? computed[propriedade] : null;
2607
+ }
2608
+ static get(elemento, propriedade) {
2609
+ return this.obter(elemento, propriedade);
2610
+ }
2611
+ /**
2612
+ * Definir estilo individual
2613
+ */
2614
+ static definir(elemento, propriedade, valor) {
2615
+ if (!this.isBrowser()) {
2616
+ throw new Error('Style.definir só funciona no navegador. Use --mode web para compilar.');
2617
+ }
2618
+ if (elemento && elemento.style) {
2619
+ elemento.style[propriedade] = valor;
2620
+ }
2621
+ }
2622
+ static set(elemento, propriedade, valor) {
2623
+ this.definir(elemento, propriedade, valor);
2624
+ }
2625
+ /**
2626
+ * Adicionar classe CSS
2627
+ */
2628
+ static добавитьКласс(elemento, classe) {
2629
+ if (!this.isBrowser()) {
2630
+ throw new Error('Style.добавитьКласс só funciona no navegador. Use --mode web para compilar.');
2631
+ }
2632
+ if (elemento && elemento.classList) {
2633
+ elemento.classList.add(classe);
2634
+ }
2635
+ }
2636
+ static addClass(elemento, classe) {
2637
+ this.добавитьКласс(elemento, classe);
2638
+ }
2639
+ /**
2640
+ * Remover classe CSS
2641
+ */
2642
+ static удалитьКласс(elemento, classe) {
2643
+ if (!this.isBrowser()) {
2644
+ throw new Error('Style.удалитьКласс só funciona no navegador. Use --mode web para compilar.');
2645
+ }
2646
+ if (elemento && elemento.classList) {
2647
+ elemento.classList.remove(classe);
2648
+ }
2649
+ }
2650
+ static removeClass(elemento, classe) {
2651
+ this.удалитьКласс(elemento, classe);
2652
+ }
2653
+ /**
2654
+ * Alternar classe CSS
2655
+ */
2656
+ static переключитьКласс(elemento, classe) {
2657
+ if (!this.isBrowser()) {
2658
+ throw new Error('Style.переключитьКласс só funciona no navegador. Use --mode web para compilar.');
2659
+ }
2660
+ if (elemento && elemento.classList) {
2661
+ elemento.classList.toggle(classe);
2662
+ }
2663
+ }
2664
+ static toggleClass(elemento, classe) {
2665
+ this.переключитьКласс(elemento, classe);
2666
+ }
2667
+ }
2668
+ exports.StdStyle = StdStyle;
2669
+ /**
2670
+ * ========================================
2671
+ * Test Module - Framework de Testes
2672
+ * ========================================
2673
+ */
2674
+ class StdTest {
2675
+ /**
2676
+ * Descrever um teste
2677
+ */
2678
+ static descrever(nome, callback) {
2679
+ this.tests.push({ name: nome, fn: callback });
2680
+ }
2681
+ static describe(nome, callback) {
2682
+ this.descrever(nome, callback);
2683
+ }
2684
+ /**
2685
+ * Afirmar condição
2686
+ */
2687
+ static afirmar(condicao, mensagem = 'Assertion failed') {
2688
+ if (!condicao) {
2689
+ throw new Error(mensagem);
2690
+ }
2691
+ }
2692
+ static assert(condicao, mensagem = 'Assertion failed') {
2693
+ this.afirmar(condicao, mensagem);
2694
+ }
2695
+ /**
2696
+ * Afirmar igualdade
2697
+ */
2698
+ static igual(esperado, atual, mensagem) {
2699
+ if (esperado !== atual) {
2700
+ const msg = mensagem || `Expected ${esperado}, but got ${atual}`;
2701
+ throw new Error(msg);
2702
+ }
2703
+ }
2704
+ static equal(esperado, atual, mensagem) {
2705
+ this.igual(esperado, atual, mensagem);
2706
+ }
2707
+ /**
2708
+ * Afirmar que é verdadeiro
2709
+ */
2710
+ static verdadeiro(valor, mensagem) {
2711
+ if (valor !== true) {
2712
+ const msg = mensagem || `Expected true, but got ${valor}`;
2713
+ throw new Error(msg);
2714
+ }
2715
+ }
2716
+ static isTrue(valor, mensagem) {
2717
+ this.verdadeiro(valor, mensagem);
2718
+ }
2719
+ /**
2720
+ * Afirmar que é falso
2721
+ */
2722
+ static ложь(valor, mensagem) {
2723
+ if (valor !== false) {
2724
+ const msg = mensagem || `Expected false, but got ${valor}`;
2725
+ throw new Error(msg);
2726
+ }
2727
+ }
2728
+ static isFalse(valor, mensagem) {
2729
+ this.ложь(valor, mensagem);
2730
+ }
2731
+ /**
2732
+ * Executar todos os testes
2733
+ */
2734
+ static выполнить() {
2735
+ this.results = [];
2736
+ let passed = 0;
2737
+ let failed = 0;
2738
+ for (const test of this.tests) {
2739
+ try {
2740
+ test.fn();
2741
+ this.results.push({ name: test.name, passed: true });
2742
+ passed++;
2743
+ console.log(`✅ ${test.name}`);
2744
+ }
2745
+ catch (error) {
2746
+ this.results.push({ name: test.name, passed: false, error: error.message });
2747
+ failed++;
2748
+ console.error(`❌ ${test.name}: ${error.message}`);
2749
+ }
2750
+ }
2751
+ console.log(`\n📊 Testes: ${passed} passaram, ${failed} falharam`);
2752
+ return { passed, failed, results: this.results };
2753
+ }
2754
+ static run() {
2755
+ return this.выполнить();
2756
+ }
2757
+ /**
2758
+ * Limpar testes registrados
2759
+ */
2760
+ static limpar() {
2761
+ this.tests = [];
2762
+ this.results = [];
2763
+ }
2764
+ static clear() {
2765
+ this.limpar();
2766
+ }
2767
+ }
2768
+ exports.StdTest = StdTest;
2769
+ StdTest.tests = [];
2770
+ StdTest.results = [];
2001
2771
  /**
2002
2772
  * Export all modules
2003
2773
  */
@@ -2014,5 +2784,8 @@ exports.StdModules = {
2014
2784
  Path: StdPath,
2015
2785
  Process: StdProcess,
2016
2786
  IO: StdIO,
2787
+ DOM: StdDOM,
2788
+ Style: StdStyle,
2789
+ Test: StdTest,
2017
2790
  };
2018
2791
  //# sourceMappingURL=std-native.js.map