chaincss 1.13.2 → 2.0.0
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/CHANGELOG.md +81 -0
- package/LICENSE +2 -3
- package/README.md +239 -114
- package/dist/cli/commands/build.d.ts +3 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/compile.d.ts +3 -0
- package/dist/cli/commands/compile.d.ts.map +1 -0
- package/dist/cli/commands/init.d.ts +5 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/timeline.d.ts +2 -0
- package/dist/cli/commands/timeline.d.ts.map +1 -0
- package/dist/cli/commands/watch.d.ts +6 -0
- package/dist/cli/commands/watch.d.ts.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +5960 -0
- package/dist/cli/types.d.ts +51 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/utils/config-loader.d.ts +8 -0
- package/dist/cli/utils/config-loader.d.ts.map +1 -0
- package/dist/cli/utils/file-utils.d.ts +9 -0
- package/dist/cli/utils/file-utils.d.ts.map +1 -0
- package/dist/cli/utils/logger.d.ts +17 -0
- package/dist/cli/utils/logger.d.ts.map +1 -0
- package/dist/compiler/atomic-optimizer.d.ts +76 -0
- package/dist/compiler/atomic-optimizer.d.ts.map +1 -0
- package/dist/compiler/btt.d.ts +138 -0
- package/dist/compiler/btt.d.ts.map +1 -0
- package/dist/compiler/cache-manager.d.ts +20 -0
- package/dist/compiler/cache-manager.d.ts.map +1 -0
- package/dist/compiler/commonProps.d.ts +2 -0
- package/dist/compiler/commonProps.d.ts.map +1 -0
- package/dist/compiler/index.d.ts +12 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +5177 -0
- package/dist/compiler/prefixer.d.ts +42 -0
- package/dist/compiler/prefixer.d.ts.map +1 -0
- package/dist/compiler/theme-contract.d.ts +61 -0
- package/dist/compiler/theme-contract.d.ts.map +1 -0
- package/dist/compiler/tokens.d.ts +52 -0
- package/dist/compiler/tokens.d.ts.map +1 -0
- package/dist/compiler/types.d.ts +57 -0
- package/dist/compiler/types.d.ts.map +1 -0
- package/dist/core/compiler.d.ts +32 -0
- package/dist/core/compiler.d.ts.map +1 -0
- package/dist/core/constants.d.ts +129 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/types.d.ts +88 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/utils.d.ts +37 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5667 -0
- package/dist/plugins/vite.d.ts +11 -0
- package/dist/plugins/vite.d.ts.map +1 -0
- package/dist/plugins/vite.js +25839 -0
- package/dist/plugins/webpack.d.ts +45 -0
- package/dist/plugins/webpack.d.ts.map +1 -0
- package/dist/plugins/webpack.js +107 -0
- package/dist/runtime/hmr.d.ts +3 -0
- package/dist/runtime/hmr.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +15 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +552 -0
- package/dist/runtime/injector.d.ts +85 -0
- package/dist/runtime/injector.d.ts.map +1 -0
- package/dist/runtime/react.d.ts +54 -0
- package/dist/runtime/react.d.ts.map +1 -0
- package/dist/runtime/react.js +270 -0
- package/dist/runtime/types.d.ts +45 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/utils.d.ts +62 -0
- package/dist/runtime/utils.d.ts.map +1 -0
- package/dist/runtime/vue.d.ts +52 -0
- package/dist/runtime/vue.d.ts.map +1 -0
- package/dist/runtime/vue.js +232 -0
- package/package.json +90 -109
- package/browser/commonProps.js +0 -14
- package/browser/index.js +0 -3
- package/browser/react-hooks.js +0 -162
- package/browser/rtt.js +0 -370
- package/node/atomic-optimizer.js +0 -391
- package/node/btt.js +0 -962
- package/node/cache-manager.js +0 -56
- package/node/chaincss.js +0 -489
- package/node/css-properties.json +0 -633
- package/node/index.js +0 -2
- package/node/loaders/chaincss-loader.js +0 -62
- package/node/plugins/next-plugin.js +0 -120
- package/node/plugins/vite-plugin.js +0 -383
- package/node/plugins/webpack-plugin.js +0 -41
- package/node/prefixer.js +0 -237
- package/node/strVal.js +0 -106
- package/node/theme-validator.js +0 -32
- package/shared/theme-contract.js +0 -98
- package/shared/tokens.cjs +0 -256
- package/shared/tokens.mjs +0 -320
- package/types.d.ts +0 -277
package/node/cache-manager.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
class CacheManager {
|
|
4
|
-
constructor(cachePath = './.chaincss-cache') {
|
|
5
|
-
this.cachePath = path.resolve(process.cwd(), cachePath);
|
|
6
|
-
this.cacheDir = path.dirname(this.cachePath);
|
|
7
|
-
this.cache = {};
|
|
8
|
-
this.load();
|
|
9
|
-
}
|
|
10
|
-
load() {
|
|
11
|
-
try {
|
|
12
|
-
if (fs.existsSync(this.cachePath)) {
|
|
13
|
-
const data = fs.readFileSync(this.cachePath, 'utf8');
|
|
14
|
-
this.cache = JSON.parse(data);
|
|
15
|
-
//console.log(`Loaded cache from ${this.cachePath}`);
|
|
16
|
-
} else {
|
|
17
|
-
// Ensure cache directory exists
|
|
18
|
-
if (!fs.existsSync(this.cacheDir)) {
|
|
19
|
-
fs.mkdirSync(this.cacheDir, { recursive: true });
|
|
20
|
-
}
|
|
21
|
-
this.cache = {
|
|
22
|
-
version: '1.0',
|
|
23
|
-
created: new Date().toISOString(),
|
|
24
|
-
atomic: {},
|
|
25
|
-
usage: {}
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
} catch (error) {
|
|
29
|
-
console.warn('Could not load cache, starting fresh:', error.message);
|
|
30
|
-
this.cache = {};
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
get(key) {
|
|
34
|
-
return this.cache[key];
|
|
35
|
-
}
|
|
36
|
-
set(key, value) {
|
|
37
|
-
this.cache[key] = value;
|
|
38
|
-
}
|
|
39
|
-
save() {
|
|
40
|
-
try {
|
|
41
|
-
const data = JSON.stringify(this.cache, null, 2);
|
|
42
|
-
fs.writeFileSync(this.cachePath, data, 'utf8');
|
|
43
|
-
//console.log(`Saved cache to ${this.cachePath}`);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
console.warn('Could not save cache:', error.message);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
clear() {
|
|
49
|
-
this.cache = {};
|
|
50
|
-
if (fs.existsSync(this.cachePath)) {
|
|
51
|
-
fs.unlinkSync(this.cachePath);
|
|
52
|
-
}
|
|
53
|
-
console.log('Cache cleared');
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
module.exports = { CacheManager };
|
package/node/chaincss.js
DELETED
|
@@ -1,489 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const Module = require('module');
|
|
5
|
-
const chokidar = require('chokidar');
|
|
6
|
-
const CleanCSS = require('clean-css');
|
|
7
|
-
const { $, run, compile: originalCompile, chain } = require('./btt');
|
|
8
|
-
const ChainCSSPrefixer = require('./prefixer.js');
|
|
9
|
-
const strVal = require('./strVal.js');
|
|
10
|
-
const { AtomicOptimizer } = require('./atomic-optimizer');
|
|
11
|
-
const { CacheManager } = require('./cache-manager');
|
|
12
|
-
|
|
13
|
-
const fileCache = new Map();
|
|
14
|
-
const compiledCache = new Map();
|
|
15
|
-
let atomicOptimizer = null;
|
|
16
|
-
|
|
17
|
-
let config = {
|
|
18
|
-
atomic: {
|
|
19
|
-
enabled: false,
|
|
20
|
-
threshold: 3,
|
|
21
|
-
naming: 'hash',
|
|
22
|
-
cache: true,
|
|
23
|
-
cachePath: './.chaincss-cache',
|
|
24
|
-
minify: true
|
|
25
|
-
},
|
|
26
|
-
prefixer: {
|
|
27
|
-
enabled: true,
|
|
28
|
-
mode: 'auto',
|
|
29
|
-
browsers: ['> 0.5%', 'last 2 versions', 'not dead'],
|
|
30
|
-
sourceMap: true,
|
|
31
|
-
sourceMapInline: false
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
let prefixer = new ChainCSSPrefixer(config.prefixer);
|
|
36
|
-
|
|
37
|
-
function deft_to_userConf(target, source) {
|
|
38
|
-
const result = { ...target };
|
|
39
|
-
for (const key in source) {
|
|
40
|
-
if (source[key] instanceof Object && key in target) {
|
|
41
|
-
result[key] = deft_to_userConf(target[key], source[key]);
|
|
42
|
-
} else {
|
|
43
|
-
result[key] = source[key];
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return result;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const ensureConfigExists = () => {
|
|
50
|
-
const configPath = path.join(process.cwd(), 'chaincss.config.cjs');
|
|
51
|
-
const configExists = fs.existsSync(configPath);
|
|
52
|
-
if (!configExists && !process.env.CHAINCSS_SKIP_CONFIG) {
|
|
53
|
-
const defaultConfig = strVal.userConf;
|
|
54
|
-
fs.writeFileSync(configPath, defaultConfig);
|
|
55
|
-
console.log('-- Successfully created config file: ./chaincss.config.cjs\n');
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const loadUserConfig = () => {
|
|
60
|
-
const configPath = path.join(process.cwd(), 'chaincss.config.cjs');
|
|
61
|
-
if (fs.existsSync(configPath)) {
|
|
62
|
-
try {
|
|
63
|
-
const userConfig = require(configPath);
|
|
64
|
-
config = deft_to_userConf(config, userConfig);
|
|
65
|
-
if (config.prefixer) {
|
|
66
|
-
if (typeof config.prefixer.browsers === 'string') {
|
|
67
|
-
config.prefixer.browsers = config.prefixer.browsers.split(',').map(b => b.trim());
|
|
68
|
-
}
|
|
69
|
-
if (!Array.isArray(config.prefixer.browsers)) {
|
|
70
|
-
config.prefixer.browsers = ['> 0.5%', 'last 2 versions', 'not dead'];
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
} catch (err) {
|
|
74
|
-
console.log('-- Error loading config:', err.message, '\n');
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const initAtomicOptimizer = () => {
|
|
80
|
-
if (config.atomic.enabled) {
|
|
81
|
-
atomicOptimizer = new AtomicOptimizer(config.atomic);
|
|
82
|
-
} else {
|
|
83
|
-
console.log('-- Atomic optimizer disabled\n');
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const initPrefixer = () => {
|
|
88
|
-
prefixer = new ChainCSSPrefixer(config.prefixer);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
function parseArgs(args) {
|
|
92
|
-
const result = {
|
|
93
|
-
inputFile: null,
|
|
94
|
-
outputFile: null,
|
|
95
|
-
watchMode: false,
|
|
96
|
-
noPrefix: false,
|
|
97
|
-
browsers: null,
|
|
98
|
-
prefixerMode: null,
|
|
99
|
-
sourceMap: null,
|
|
100
|
-
sourceMapInline: false,
|
|
101
|
-
atomic: false
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
for (let i = 0; i < args.length; i++) {
|
|
105
|
-
const arg = args[i];
|
|
106
|
-
|
|
107
|
-
if (arg === '--watch') {
|
|
108
|
-
result.watchMode = true;
|
|
109
|
-
} else if (arg === '--no-prefix') {
|
|
110
|
-
result.noPrefix = true;
|
|
111
|
-
} else if (arg === '--prefixer-mode' && args[i + 1]) {
|
|
112
|
-
result.prefixerMode = args[i + 1];
|
|
113
|
-
i++;
|
|
114
|
-
} else if (arg === '--browsers' && args[i + 1]) {
|
|
115
|
-
result.browsers = args[i + 1].split(',').map(b => b.trim());
|
|
116
|
-
i++;
|
|
117
|
-
} else if (arg === '--no-source-map') {
|
|
118
|
-
result.sourceMap = false;
|
|
119
|
-
} else if (arg === '--source-map-inline') {
|
|
120
|
-
result.sourceMapInline = true;
|
|
121
|
-
} else if (arg === '--atomic') {
|
|
122
|
-
result.atomic = true;
|
|
123
|
-
} else if (!result.inputFile) {
|
|
124
|
-
result.inputFile = arg;
|
|
125
|
-
} else if (!result.outputFile) {
|
|
126
|
-
result.outputFile = arg;
|
|
127
|
-
}else if (arg === '--validate-themes') {
|
|
128
|
-
result.validateThemes = true;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return result;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const applyCliOptions = (cliOptions) => {
|
|
135
|
-
if (cliOptions.sourceMap !== null) {
|
|
136
|
-
config.prefixer.sourceMap = cliOptions.sourceMap;
|
|
137
|
-
}
|
|
138
|
-
if (cliOptions.sourceMapInline) {
|
|
139
|
-
config.prefixer.sourceMapInline = true;
|
|
140
|
-
}
|
|
141
|
-
if (cliOptions.prefixerMode) {
|
|
142
|
-
config.prefixer.mode = cliOptions.prefixerMode;
|
|
143
|
-
}
|
|
144
|
-
if (cliOptions.noPrefix) {
|
|
145
|
-
config.prefixer.enabled = false;
|
|
146
|
-
}
|
|
147
|
-
if (cliOptions.browsers) {
|
|
148
|
-
config.prefixer.browsers = cliOptions.browsers;
|
|
149
|
-
}
|
|
150
|
-
if (cliOptions.atomic) {
|
|
151
|
-
config.atomic.enabled = true;
|
|
152
|
-
}
|
|
153
|
-
/*if (cliOptions.validateThemes) {
|
|
154
|
-
const configPath = path.join(process.cwd(), 'chaincss.config.cjs');
|
|
155
|
-
if (fs.existsSync(configPath)) {
|
|
156
|
-
await import('./theme-validator.js').then(module => {
|
|
157
|
-
module.validateThemeFiles(configPath);
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}*/
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
function watch(inputFile, outputFile) {
|
|
164
|
-
chokidar.watch(inputFile).on('change', async () => {
|
|
165
|
-
try {
|
|
166
|
-
await processor(inputFile, outputFile);
|
|
167
|
-
} catch (err) {
|
|
168
|
-
console.error('Error during watch processing:', err);
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const compile = (obj) => {
|
|
174
|
-
originalCompile(obj);
|
|
175
|
-
let css = chain.cssOutput || '';
|
|
176
|
-
if (atomicOptimizer && config.atomic.enabled) {
|
|
177
|
-
const result = atomicOptimizer.optimize(obj);
|
|
178
|
-
css = result.css;
|
|
179
|
-
chain.cssOutput = css;
|
|
180
|
-
chain.classMap = result.map;
|
|
181
|
-
chain.atomicStats = result.stats;
|
|
182
|
-
}
|
|
183
|
-
return css;
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
const transpilerModule = {
|
|
187
|
-
$,
|
|
188
|
-
run,
|
|
189
|
-
compile: originalCompile,
|
|
190
|
-
chain
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
// Native module-based JCSS file processor (replaces vm2)
|
|
194
|
-
const processJCSSFile = (filePath) => {
|
|
195
|
-
const abs = path.resolve(filePath);
|
|
196
|
-
|
|
197
|
-
if (fileCache.has(abs)) return fileCache.get(abs);
|
|
198
|
-
|
|
199
|
-
if (!fs.existsSync(abs)) {
|
|
200
|
-
throw new Error(`File not found: ${abs}`);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const content = fs.readFileSync(abs, 'utf8');
|
|
204
|
-
const dirname = path.dirname(abs);
|
|
205
|
-
|
|
206
|
-
const m = new Module(abs, module.parent);
|
|
207
|
-
m.filename = abs;
|
|
208
|
-
m.paths = Module._nodeModulePaths(dirname);
|
|
209
|
-
|
|
210
|
-
const get = (relativePath) => processJCSSFile(path.resolve(dirname, relativePath));
|
|
211
|
-
|
|
212
|
-
let compiledFn = compiledCache.get(abs);
|
|
213
|
-
if (!compiledFn) {
|
|
214
|
-
compiledFn = new Function(
|
|
215
|
-
'exports',
|
|
216
|
-
'require',
|
|
217
|
-
'module',
|
|
218
|
-
'__filename',
|
|
219
|
-
'__dirname',
|
|
220
|
-
'$',
|
|
221
|
-
'run',
|
|
222
|
-
'compile',
|
|
223
|
-
'chain',
|
|
224
|
-
'get',
|
|
225
|
-
content
|
|
226
|
-
);
|
|
227
|
-
compiledCache.set(abs, compiledFn);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
try {
|
|
231
|
-
compiledFn(
|
|
232
|
-
m.exports,
|
|
233
|
-
require,
|
|
234
|
-
m,
|
|
235
|
-
abs,
|
|
236
|
-
dirname,
|
|
237
|
-
$,
|
|
238
|
-
run,
|
|
239
|
-
originalCompile,
|
|
240
|
-
chain,
|
|
241
|
-
get
|
|
242
|
-
);
|
|
243
|
-
} catch (err) {
|
|
244
|
-
console.error(`Error processing ${abs}:`, err.message);
|
|
245
|
-
throw err;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
fileCache.set(abs, m.exports);
|
|
249
|
-
return m.exports;
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
const processScript = (scriptBlock, filename) => {
|
|
253
|
-
const dirname = path.dirname(filename);
|
|
254
|
-
const get = (relativePath) => processJCSSFile(path.resolve(dirname, relativePath));
|
|
255
|
-
|
|
256
|
-
chain.cssOutput = '';
|
|
257
|
-
|
|
258
|
-
let compiledFn = compiledCache.get(`script:${filename}`);
|
|
259
|
-
if (!compiledFn) {
|
|
260
|
-
compiledFn = new Function(
|
|
261
|
-
'$',
|
|
262
|
-
'run',
|
|
263
|
-
'compile',
|
|
264
|
-
'chain',
|
|
265
|
-
'get',
|
|
266
|
-
'__filename',
|
|
267
|
-
'__dirname',
|
|
268
|
-
scriptBlock
|
|
269
|
-
);
|
|
270
|
-
compiledCache.set(`script:${filename}`, compiledFn);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
try {
|
|
274
|
-
compiledFn($, run, originalCompile, chain, get, filename, dirname);
|
|
275
|
-
} catch (err) {
|
|
276
|
-
console.error(`Error processing script in ${filename}:`, err.message);
|
|
277
|
-
throw err;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return chain.cssOutput || '';
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
const processJavascriptBlocks = (content, inputpath) => {
|
|
284
|
-
const blocks = content.split(/<@([\s\S]*?)@>/gm);
|
|
285
|
-
let outputCSS = '';
|
|
286
|
-
|
|
287
|
-
for (let i = 0; i < blocks.length; i++) {
|
|
288
|
-
if (i % 2 === 0) {
|
|
289
|
-
outputCSS += blocks[i];
|
|
290
|
-
} else {
|
|
291
|
-
const scriptBlock = blocks[i];
|
|
292
|
-
try {
|
|
293
|
-
const blockCSS = processScript(scriptBlock, inputpath);
|
|
294
|
-
if (typeof blockCSS !== 'object' && typeof blockCSS !== 'undefined') {
|
|
295
|
-
outputCSS += blockCSS;
|
|
296
|
-
}
|
|
297
|
-
} catch (err) {
|
|
298
|
-
console.error(`Error processing script block:`, err.stack);
|
|
299
|
-
throw err;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
return outputCSS.trim();
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
const validateCSS = (css) => {
|
|
307
|
-
const openBraces = (css.match(/{/g) || []).length;
|
|
308
|
-
const closeBraces = (css.match(/}/g) || []).length;
|
|
309
|
-
if (openBraces !== closeBraces) {
|
|
310
|
-
console.error(`CSS syntax error: Unclosed blocks (${openBraces} opening vs ${closeBraces} closing braces)`);
|
|
311
|
-
return false;
|
|
312
|
-
}
|
|
313
|
-
return true;
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
const processAndMinifyCss = async (css, inputFile, outputFile) => {
|
|
317
|
-
if (!validateCSS(css)) {
|
|
318
|
-
throw new Error('Invalid CSS syntax - check for missing braces');
|
|
319
|
-
}
|
|
320
|
-
let processedCss = css;
|
|
321
|
-
let sourceMapFromPrefixer = null;
|
|
322
|
-
if (config.prefixer.enabled) {
|
|
323
|
-
try {
|
|
324
|
-
const result = await prefixer.process(css, {
|
|
325
|
-
from: inputFile,
|
|
326
|
-
to: outputFile,
|
|
327
|
-
map: config.prefixer.sourceMap !== false
|
|
328
|
-
});
|
|
329
|
-
processedCss = result.css;
|
|
330
|
-
sourceMapFromPrefixer = result.map;
|
|
331
|
-
} catch (err) {
|
|
332
|
-
console.error('Prefixer error:', err.message);
|
|
333
|
-
processedCss = css;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
const minifyOptions = {
|
|
337
|
-
sourceMap: config.prefixer.sourceMap === true,
|
|
338
|
-
sourceMapInlineSources: true
|
|
339
|
-
};
|
|
340
|
-
const output = new CleanCSS(minifyOptions).minify(processedCss);
|
|
341
|
-
if (output.errors.length > 0) {
|
|
342
|
-
console.error('CSS Minification Errors:', output.errors);
|
|
343
|
-
return { css: null, map: null };
|
|
344
|
-
}
|
|
345
|
-
let finalCss = output.styles;
|
|
346
|
-
let finalSourceMap = output.sourceMap ? JSON.stringify(output.sourceMap) : sourceMapFromPrefixer;
|
|
347
|
-
if (finalSourceMap && !config.prefixer.sourceMapInline) {
|
|
348
|
-
const mapFileName = path.basename(`${outputFile}.map`);
|
|
349
|
-
finalCss += `\n/*# sourceMappingURL=${mapFileName} */`;
|
|
350
|
-
}
|
|
351
|
-
return { css: finalCss, map: finalSourceMap };
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
const processor = async (inputFile, outputFile) => {
|
|
355
|
-
try {
|
|
356
|
-
const input = path.resolve(inputFile);
|
|
357
|
-
const outputDir = path.resolve(outputFile);
|
|
358
|
-
if (!fs.existsSync(outputDir)) {
|
|
359
|
-
fs.mkdirSync(outputDir, { recursive: true });
|
|
360
|
-
}
|
|
361
|
-
const content = fs.readFileSync(input, 'utf8');
|
|
362
|
-
const processedCSS = processJavascriptBlocks(content, input);
|
|
363
|
-
if (!validateCSS(processedCSS)) {
|
|
364
|
-
throw new Error('Invalid CSS syntax');
|
|
365
|
-
}
|
|
366
|
-
const stylePath = path.join(outputDir, 'global.css');
|
|
367
|
-
const result = await processAndMinifyCss(processedCSS, input, stylePath);
|
|
368
|
-
if (result.css) {
|
|
369
|
-
fs.writeFileSync(stylePath, result.css, 'utf8');
|
|
370
|
-
if (result.map) {
|
|
371
|
-
const mapFile = `${stylePath}.map`;
|
|
372
|
-
fs.writeFileSync(mapFile, result.map, 'utf8');
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// ========== ATOMIC CLASS MAP GENERATION ==========
|
|
376
|
-
if (atomicOptimizer && config.atomic.enabled && chain.classMap && Object.keys(chain.classMap).length > 0) {
|
|
377
|
-
// Write map.json (selector → atomic class string)
|
|
378
|
-
const mapJsonPath = path.join(outputDir, 'global.map.json');
|
|
379
|
-
const mapData = {
|
|
380
|
-
version: '1.0.0',
|
|
381
|
-
generated: new Date().toISOString(),
|
|
382
|
-
input: inputFile,
|
|
383
|
-
output: stylePath,
|
|
384
|
-
atomicEnabled: true,
|
|
385
|
-
threshold: config.atomic.threshold,
|
|
386
|
-
classMap: chain.classMap,
|
|
387
|
-
stats: chain.atomicStats
|
|
388
|
-
};
|
|
389
|
-
fs.writeFileSync(mapJsonPath, JSON.stringify(mapData, null, 2), 'utf8');
|
|
390
|
-
console.log(` Class map: ${mapJsonPath}`);
|
|
391
|
-
|
|
392
|
-
// Write JS module for easy import
|
|
393
|
-
const jsPath = path.join(outputDir, 'global.classes.js');
|
|
394
|
-
const jsContent = `/**
|
|
395
|
-
* ChainCSS Atomic Class Map
|
|
396
|
-
* Generated: ${new Date().toISOString()}
|
|
397
|
-
* Threshold: ${config.atomic.threshold}
|
|
398
|
-
*/
|
|
399
|
-
|
|
400
|
-
export const classMap = ${JSON.stringify(chain.classMap, null, 2)};
|
|
401
|
-
|
|
402
|
-
export const getClass = (selector) => classMap[selector] || '';
|
|
403
|
-
|
|
404
|
-
export default classMap;
|
|
405
|
-
`;
|
|
406
|
-
fs.writeFileSync(jsPath, jsContent, 'utf8');
|
|
407
|
-
console.log(` JS module: ${jsPath}`);
|
|
408
|
-
|
|
409
|
-
// Write TypeScript definitions
|
|
410
|
-
const dtsPath = path.join(outputDir, 'global.classes.d.ts');
|
|
411
|
-
const dtsContent = `/**
|
|
412
|
-
* ChainCSS Atomic Class Map Type Definitions
|
|
413
|
-
* Generated: ${new Date().toISOString()}
|
|
414
|
-
*/
|
|
415
|
-
|
|
416
|
-
export const classMap: Record<string, string>;
|
|
417
|
-
export const getClass: (selector: string) => string;
|
|
418
|
-
declare const _default: Record<string, string>;
|
|
419
|
-
export default _default;
|
|
420
|
-
`;
|
|
421
|
-
fs.writeFileSync(dtsPath, dtsContent, 'utf8');
|
|
422
|
-
console.log(` TypeScript definitions: ${dtsPath}`);
|
|
423
|
-
|
|
424
|
-
// Update manifest
|
|
425
|
-
const manifestPath = path.join(outputDir, 'chaincss-manifest.json');
|
|
426
|
-
let manifest = {};
|
|
427
|
-
if (fs.existsSync(manifestPath)) {
|
|
428
|
-
try {
|
|
429
|
-
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
430
|
-
} catch (e) {}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
manifest[path.basename(stylePath)] = {
|
|
434
|
-
css: path.basename(stylePath),
|
|
435
|
-
map: path.basename(mapJsonPath),
|
|
436
|
-
js: path.basename(jsPath),
|
|
437
|
-
dts: path.basename(dtsPath),
|
|
438
|
-
generated: new Date().toISOString(),
|
|
439
|
-
input: inputFile,
|
|
440
|
-
threshold: config.atomic.threshold,
|
|
441
|
-
stats: chain.atomicStats
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf8');
|
|
445
|
-
console.log(` Manifest: ${manifestPath}`);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
} catch (err) {
|
|
449
|
-
console.error(`Failed to process ${inputFile}:`, err.message);
|
|
450
|
-
throw err;
|
|
451
|
-
}
|
|
452
|
-
};
|
|
453
|
-
|
|
454
|
-
if (require.main === module) {
|
|
455
|
-
ensureConfigExists();
|
|
456
|
-
loadUserConfig();
|
|
457
|
-
const args = process.argv.slice(2);
|
|
458
|
-
const cliOptions = parseArgs(args);
|
|
459
|
-
if (!cliOptions.inputFile || !cliOptions.outputFile) {
|
|
460
|
-
console.log(strVal.cli_opt_guide);
|
|
461
|
-
process.exit(1);
|
|
462
|
-
}
|
|
463
|
-
applyCliOptions(cliOptions);
|
|
464
|
-
initAtomicOptimizer();
|
|
465
|
-
initPrefixer();
|
|
466
|
-
(async () => {
|
|
467
|
-
try {
|
|
468
|
-
await processor(cliOptions.inputFile, cliOptions.outputFile);
|
|
469
|
-
if (cliOptions.watchMode) {
|
|
470
|
-
console.log('-- Watching for changes...\n');
|
|
471
|
-
watch(cliOptions.inputFile, cliOptions.outputFile);
|
|
472
|
-
}
|
|
473
|
-
} catch (err) {
|
|
474
|
-
console.error('Fatal error:', err);
|
|
475
|
-
process.exit(1);
|
|
476
|
-
}
|
|
477
|
-
})();
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
module.exports = {
|
|
481
|
-
processor,
|
|
482
|
-
watch,
|
|
483
|
-
$,
|
|
484
|
-
run,
|
|
485
|
-
compile,
|
|
486
|
-
chain,
|
|
487
|
-
atomicOptimizer,
|
|
488
|
-
config
|
|
489
|
-
};
|