zero-query 0.2.9 → 0.4.9

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.
package/cli/utils.js ADDED
@@ -0,0 +1,122 @@
1
+ /**
2
+ * cli/utils.js — shared utility functions
3
+ *
4
+ * Context-aware comment stripping, quick minification, size formatting,
5
+ * and recursive directory copying. These are consumed by both the
6
+ * build and bundle commands.
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // stripComments — context-aware, skips strings / templates / regex
16
+ // ---------------------------------------------------------------------------
17
+
18
+ function stripComments(code) {
19
+ let out = '';
20
+ let i = 0;
21
+ while (i < code.length) {
22
+ const ch = code[i];
23
+ const next = code[i + 1];
24
+
25
+ // String literals
26
+ if (ch === '"' || ch === "'" || ch === '`') {
27
+ const quote = ch;
28
+ out += ch; i++;
29
+ while (i < code.length) {
30
+ if (code[i] === '\\') { out += code[i] + (code[i + 1] || ''); i += 2; continue; }
31
+ out += code[i];
32
+ if (code[i] === quote) { i++; break; }
33
+ i++;
34
+ }
35
+ continue;
36
+ }
37
+
38
+ // Block comment
39
+ if (ch === '/' && next === '*') {
40
+ i += 2;
41
+ while (i < code.length && !(code[i] === '*' && code[i + 1] === '/')) i++;
42
+ i += 2;
43
+ continue;
44
+ }
45
+
46
+ // Line comment
47
+ if (ch === '/' && next === '/') {
48
+ i += 2;
49
+ while (i < code.length && code[i] !== '\n') i++;
50
+ continue;
51
+ }
52
+
53
+ // Regex literal
54
+ if (ch === '/') {
55
+ const before = out.replace(/\s+$/, '');
56
+ const last = before[before.length - 1];
57
+ const isRegexCtx = !last || '=({[,;:!&|?~+-*/%^>'.includes(last)
58
+ || before.endsWith('return') || before.endsWith('typeof')
59
+ || before.endsWith('case') || before.endsWith('in')
60
+ || before.endsWith('delete') || before.endsWith('void')
61
+ || before.endsWith('throw') || before.endsWith('new');
62
+ if (isRegexCtx) {
63
+ out += ch; i++;
64
+ let inCharClass = false;
65
+ while (i < code.length) {
66
+ const rc = code[i];
67
+ if (rc === '\\') { out += rc + (code[i + 1] || ''); i += 2; continue; }
68
+ if (rc === '[') inCharClass = true;
69
+ if (rc === ']') inCharClass = false;
70
+ out += rc; i++;
71
+ if (rc === '/' && !inCharClass) {
72
+ while (i < code.length && /[gimsuy]/.test(code[i])) { out += code[i]; i++; }
73
+ break;
74
+ }
75
+ }
76
+ continue;
77
+ }
78
+ }
79
+
80
+ out += ch; i++;
81
+ }
82
+ return out;
83
+ }
84
+
85
+ // ---------------------------------------------------------------------------
86
+ // minify — quick minification (strips comments + collapses whitespace)
87
+ // ---------------------------------------------------------------------------
88
+
89
+ function minify(code, banner) {
90
+ const body = stripComments(code.replace(banner, ''))
91
+ .replace(/^\s*\n/gm, '')
92
+ .replace(/\n\s+/g, '\n')
93
+ .replace(/\s{2,}/g, ' ');
94
+ return banner + '\n' + body;
95
+ }
96
+
97
+ // ---------------------------------------------------------------------------
98
+ // sizeKB — human-readable file size
99
+ // ---------------------------------------------------------------------------
100
+
101
+ function sizeKB(buf) {
102
+ return (buf.length / 1024).toFixed(1);
103
+ }
104
+
105
+ // ---------------------------------------------------------------------------
106
+ // copyDirSync — recursive directory copy
107
+ // ---------------------------------------------------------------------------
108
+
109
+ function copyDirSync(src, dest) {
110
+ if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true });
111
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
112
+ const srcPath = path.join(src, entry.name);
113
+ const destPath = path.join(dest, entry.name);
114
+ if (entry.isDirectory()) {
115
+ copyDirSync(srcPath, destPath);
116
+ } else {
117
+ fs.copyFileSync(srcPath, destPath);
118
+ }
119
+ }
120
+ }
121
+
122
+ module.exports = { stripComments, minify, sizeKB, copyDirSync };
Binary file