esm-styles 0.2.8 → 0.3.1

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.
@@ -1,79 +0,0 @@
1
- /**
2
- * Utilities for converting JavaScript objects to CSS strings
3
- */
4
- /**
5
- * Converts a CSS object to a string representation
6
- * @param cssObject - Object with CSS selectors and properties
7
- * @returns CSS string
8
- */
9
- export function obj2css(cssObject) {
10
- // Convert object to JSON string with indentation
11
- const json = JSON.stringify(cssObject, null, 2);
12
- // Process the JSON string to convert to valid CSS
13
- const css = json
14
- // Replace double quotes with single quotes for strings
15
- .replace(/\\"/g, "'")
16
- // Convert object keys to CSS selectors
17
- .replace(/"([^"]+)":\s*{/g, '$1 {')
18
- // Remove commas between rule sets and add empty line
19
- .replace(/},/g, '}')
20
- // Remove remaining double quotes
21
- .replace(/"/g, '')
22
- // Restore quotes for inlined URLs
23
- .replace(/url\('(.+)'\)/g, 'url("$1")')
24
- // Convert property-value commas to semicolons
25
- .replace(/,(\s*})/g, ';$1')
26
- // Remove the outermost curly braces
27
- .replace(/^{|}$/g, '')
28
- // Convert commas between property values to semicolons
29
- .replace(/,\s*(?=[a-z-]+:)/g, ';\n ')
30
- // Remove indentation from the start of lines
31
- .replace(/^( {2})/gm, '')
32
- // Add semicolons before closing brackets if missing
33
- .replace(/([^;])\s*}/g, '$1;\n}')
34
- // Ensure space between property name and value
35
- .replace(/:\s*/g, ': ')
36
- // Clean up extra spaces
37
- .replace(/\s+/g, ' ')
38
- // Fix colon spacing in selectors
39
- .replace(/([:#]) /g, '$1');
40
- // Split into lines for additional processing
41
- const lines = css.split('\n');
42
- const result = [];
43
- for (let i = 0; i < lines.length; i++) {
44
- const line = lines[i];
45
- // Handle property lines
46
- if (line.includes(': ')) {
47
- result.push(' ' + line.trim());
48
- }
49
- // Handle selector lines
50
- else if (line.includes('{')) {
51
- result.push(line.trim());
52
- }
53
- // Handle closing bracket lines
54
- else if (line.includes('}')) {
55
- result.push('}');
56
- }
57
- // Other lines
58
- else {
59
- result.push(line);
60
- }
61
- }
62
- return result.join('\n');
63
- }
64
- /**
65
- * Prettifies a CSS string by ensuring consistent spacing and formatting
66
- * @param cssString - CSS string to prettify
67
- * @returns Prettified CSS string
68
- */
69
- export function prettifyCss(cssString) {
70
- return (cssString
71
- // Ensure consistent newlines between rule sets
72
- .replace(/}\s*/g, '}\n\n')
73
- // Fix spacing inside brackets
74
- .replace(/{\s*/g, ' {\n')
75
- // Clean up extra newlines
76
- .replace(/\n{3,}/g, '\n\n')
77
- // Trim the string
78
- .trim());
79
- }
@@ -1,15 +0,0 @@
1
- /**
2
- * Utilities for working with CSS selectors
3
- */
4
- /**
5
- * Joins selector parts into a valid CSS selector
6
- * @param path - Array of selector parts or a single selector
7
- * @returns Combined CSS selector
8
- */
9
- export declare function joinSelectors(path: string | string[]): string;
10
- /**
11
- * Creates a Cartesian product of selector parts and joins them
12
- * @param parts - Array of selector parts arrays
13
- * @returns Array of all possible combined selectors
14
- */
15
- export declare function cartesianSelectors(parts: string[][]): string[];
@@ -1,87 +0,0 @@
1
- /**
2
- * Utilities for working with CSS selectors
3
- */
4
- import { isHtmlTag } from './tags.js';
5
- /**
6
- * Joins selector parts into a valid CSS selector
7
- * @param path - Array of selector parts or a single selector
8
- * @returns Combined CSS selector
9
- */
10
- export function joinSelectors(path) {
11
- const array = typeof path === 'string' ? [path] : path;
12
- let result = '';
13
- for (const keyStr of array) {
14
- // Skip empty key strings
15
- if (!keyStr.trim())
16
- continue;
17
- const key = keyStr.replace(/&/g, '').trim();
18
- if (isHtmlTag(key)) {
19
- // If it's an HTML tag, just add it with a space
20
- result += ` ${key}`;
21
- }
22
- else {
23
- let prefix = '';
24
- let selector = key;
25
- // Handle reference to parent selector with &
26
- if (/^&/.test(keyStr)) {
27
- prefix += ' ';
28
- }
29
- // Handle double underscore for descendant of any level (T6)
30
- if (/^__/.test(key)) {
31
- prefix += ' ';
32
- selector = selector.replace(/^__/, '');
33
- }
34
- // Handle single underscore for class selector (T5)
35
- if (/^_/.test(key)) {
36
- selector = selector.replace(/^_/, '');
37
- if (!isHtmlTag(selector)) {
38
- // If not a tag, increase level
39
- prefix += ' ';
40
- }
41
- }
42
- // Add dot for class selectors if needed
43
- if (!/^[.:#*[~+>]/.test(selector)) {
44
- if (!/\./.test(prefix))
45
- prefix += '.';
46
- }
47
- // Special handling for universal selector
48
- if (/^\*/.test(selector)) {
49
- prefix = ' ' + prefix;
50
- }
51
- result += prefix + selector;
52
- }
53
- }
54
- // Fix any double dots that might have been created
55
- result = result.replace(/\.\s*\./g, '.');
56
- // Clean up whitespace
57
- result = result
58
- // Remove extra spaces
59
- .replace(/\s+/g, ' ')
60
- // Preserve proper spacing around combinators
61
- .replace(/\s*([>+~])\s*/g, ' $1 ')
62
- // Fix pseudo-classes and pseudo-elements
63
- .replace(/\s+:/g, ':')
64
- // Fix attribute selectors
65
- .replace(/\s+\[/g, '[')
66
- // Trim whitespace
67
- .trim();
68
- return result;
69
- }
70
- /**
71
- * Creates a Cartesian product of selector parts and joins them
72
- * @param parts - Array of selector parts arrays
73
- * @returns Array of all possible combined selectors
74
- */
75
- export function cartesianSelectors(parts) {
76
- // Base case: If empty or just one part, return it flattened
77
- if (parts.length === 0)
78
- return [];
79
- if (parts.length === 1)
80
- return parts[0];
81
- // Implementation of cartesian product
82
- const result = parts.reduce((acc, curr) => acc.flatMap((x) => curr.map((y) => [...x, y])), [[]]);
83
- return result.map((selectors) => {
84
- // Handle comma-separated selectors by creating real CSS selector lists
85
- return joinSelectors(selectors.filter(Boolean));
86
- });
87
- }
@@ -1,10 +0,0 @@
1
- /**
2
- * List of all HTML tags used to identify selectors
3
- */
4
- export declare const htmlTags: string[];
5
- /**
6
- * Checks if a string is an HTML tag name
7
- * @param key - String to check
8
- * @returns True if the string is an HTML tag name
9
- */
10
- export declare function isHtmlTag(key: string): boolean;
@@ -1,128 +0,0 @@
1
- /**
2
- * List of all HTML tags used to identify selectors
3
- */
4
- export const htmlTags = [
5
- 'a',
6
- 'abbr',
7
- 'address',
8
- 'area',
9
- 'article',
10
- 'aside',
11
- 'audio',
12
- 'b',
13
- 'base',
14
- 'bdi',
15
- 'bdo',
16
- 'blockquote',
17
- 'body',
18
- 'br',
19
- 'button',
20
- 'canvas',
21
- 'caption',
22
- 'cite',
23
- 'code',
24
- 'col',
25
- 'colgroup',
26
- 'data',
27
- 'datalist',
28
- 'dd',
29
- 'del',
30
- 'details',
31
- 'dfn',
32
- 'dialog',
33
- 'div',
34
- 'dl',
35
- 'dt',
36
- 'em',
37
- 'embed',
38
- 'fieldset',
39
- 'figcaption',
40
- 'figure',
41
- 'footer',
42
- 'form',
43
- 'h1',
44
- 'h2',
45
- 'h3',
46
- 'h4',
47
- 'h5',
48
- 'h6',
49
- 'head',
50
- 'header',
51
- 'hgroup',
52
- 'hr',
53
- 'html',
54
- 'i',
55
- 'iframe',
56
- 'img',
57
- 'input',
58
- 'ins',
59
- 'kbd',
60
- 'label',
61
- 'legend',
62
- 'li',
63
- 'link',
64
- 'main',
65
- 'map',
66
- 'mark',
67
- 'meta',
68
- 'meter',
69
- 'nav',
70
- 'noscript',
71
- 'object',
72
- 'ol',
73
- 'optgroup',
74
- 'option',
75
- 'output',
76
- 'p',
77
- 'param',
78
- 'picture',
79
- 'pre',
80
- 'progress',
81
- 'q',
82
- 'rp',
83
- 'rt',
84
- 'ruby',
85
- 's',
86
- 'samp',
87
- 'script',
88
- 'section',
89
- 'select',
90
- 'slot',
91
- 'small',
92
- 'source',
93
- 'span',
94
- 'strong',
95
- 'style',
96
- 'sub',
97
- 'summary',
98
- 'sup',
99
- 'svg',
100
- 'table',
101
- 'tbody',
102
- 'td',
103
- 'template',
104
- 'textarea',
105
- 'tfoot',
106
- 'th',
107
- 'thead',
108
- 'time',
109
- 'title',
110
- 'tr',
111
- 'track',
112
- 'u',
113
- 'ul',
114
- 'var',
115
- 'video',
116
- 'wbr',
117
- ];
118
- /**
119
- * Checks if a string is an HTML tag name
120
- * @param key - String to check
121
- * @returns True if the string is an HTML tag name
122
- */
123
- export function isHtmlTag(key) {
124
- if (/^\w+[.#:[~+ ]/.test(key)) {
125
- return htmlTags.includes(key.split(/[.#:[~+ ]/)[0]);
126
- }
127
- return htmlTags.includes(key);
128
- }
@@ -1,25 +0,0 @@
1
- /**
2
- * Utility for traversing and transforming nested objects
3
- */
4
- /**
5
- * Type for node visitor functions
6
- */
7
- export type NodeVisitor<T> = (node: any, path: string, root: any, index: number) => T;
8
- /**
9
- * Traverses a nested object and applies a visitor function to each node
10
- * @param node - The object to traverse
11
- * @param visitor - Function to call for each node
12
- * @param path - Current path in the object (for tracking)
13
- * @param root - Root object (for reference)
14
- * @param index - Current index in array (if applicable)
15
- * @param separator - Path separator character
16
- * @returns The result of the visitor function on the current node
17
- */
18
- export declare function traverseObject<T>(node: any, visitor: NodeVisitor<T>, path?: string, root?: any, index?: number, separator?: string): T;
19
- /**
20
- * Determines the type of a node in the CSS object
21
- * @param node - The node to check
22
- * @param path - Current path in the object
23
- * @returns The identified node type as a string
24
- */
25
- export declare function determineNodeType(node: any, path?: string): string;
@@ -1,78 +0,0 @@
1
- /**
2
- * Utility for traversing and transforming nested objects
3
- */
4
- /**
5
- * Traverses a nested object and applies a visitor function to each node
6
- * @param node - The object to traverse
7
- * @param visitor - Function to call for each node
8
- * @param path - Current path in the object (for tracking)
9
- * @param root - Root object (for reference)
10
- * @param index - Current index in array (if applicable)
11
- * @param separator - Path separator character
12
- * @returns The result of the visitor function on the current node
13
- */
14
- export function traverseObject(node, visitor, path = '', root, index = -1, separator = '\\') {
15
- const realRoot = root || node;
16
- // Handle arrays
17
- if (Array.isArray(node)) {
18
- const processedItems = node.map((item, idx) => traverseObject(item, visitor, path, realRoot, idx, separator));
19
- return visitor(processedItems, path, realRoot, index);
20
- }
21
- // Handle objects (but not null)
22
- if (node !== null && typeof node === 'object') {
23
- const processedObject = Object.keys(node).reduce((result, key) => {
24
- const newPath = path ? `${path}${separator}${key}` : key;
25
- const processedValue = traverseObject(node[key], visitor, newPath, realRoot, index, separator);
26
- result[key] = processedValue;
27
- return result;
28
- }, {});
29
- return visitor(processedObject, path, realRoot, index);
30
- }
31
- // Handle primitive values
32
- return visitor(node, path, realRoot, index);
33
- }
34
- /**
35
- * Determines the type of a node in the CSS object
36
- * @param node - The node to check
37
- * @param path - Current path in the object
38
- * @returns The identified node type as a string
39
- */
40
- export function determineNodeType(node, path) {
41
- if (!path)
42
- return 'unknown';
43
- const lastKey = path.split('\\').pop() || '';
44
- // Layer statement
45
- if (/^@layer/.test(lastKey) && typeof node === 'string') {
46
- return 'layer statement';
47
- }
48
- // Layer block
49
- if (/^@layer/.test(lastKey) && typeof node === 'object' && node !== null) {
50
- return 'layer block';
51
- }
52
- // Container query
53
- if (/^@container/.test(lastKey) &&
54
- typeof node === 'object' &&
55
- node !== null) {
56
- return 'container query block';
57
- }
58
- // Media query or prefix
59
- if (/^@/.test(lastKey)) {
60
- return 'media query or prefix';
61
- }
62
- // CSS property-value pair (end value)
63
- if (isPrimitiveValue(node)) {
64
- return 'selector';
65
- }
66
- return 'unknown';
67
- }
68
- /**
69
- * Checks if a value is a primitive that can be used as a CSS property value
70
- * @param value - Value to check
71
- * @returns True if the value is a primitive
72
- */
73
- function isPrimitiveValue(value) {
74
- return (value === null ||
75
- typeof value === 'string' ||
76
- typeof value === 'number' ||
77
- typeof value === 'boolean');
78
- }
package/dist/watch.js DELETED
@@ -1,37 +0,0 @@
1
- #!/usr/bin/env node
2
- import { spawn } from 'child_process'
3
- import path from 'path'
4
- import process from 'process'
5
-
6
- const configPath = process.argv[2] || 'esm-styles.config.js'
7
- const configModule = await import(
8
- path.isAbsolute(configPath)
9
- ? configPath
10
- : path.resolve(process.cwd(), configPath)
11
- )
12
- const config = configModule.default
13
-
14
- const basePath = path.resolve(process.cwd(), config.basePath || '.')
15
- const sourcePath = path.join(basePath, config.sourcePath || '')
16
-
17
- const buildJsPath = path.resolve(
18
- path.dirname(new URL(import.meta.url).pathname),
19
- 'build.js'
20
- )
21
-
22
- const nodemonArgs = [
23
- '--watch',
24
- sourcePath,
25
- '--ext',
26
- 'mjs',
27
- '--ignore',
28
- path.join(sourcePath, '$*.mjs'),
29
- '--exec',
30
- `node ${buildJsPath} ${configPath}`,
31
- ]
32
-
33
- console.log('[esm-styles] Running:', 'nodemon', ...nodemonArgs)
34
-
35
- const nodemon = spawn('nodemon', nodemonArgs, { stdio: 'inherit' })
36
-
37
- nodemon.on('exit', (code) => process.exit(code))