@gustcss/vite 0.1.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.
Files changed (3) hide show
  1. package/index.cjs +186 -0
  2. package/index.mjs +186 -0
  3. package/package.json +30 -0
package/index.cjs ADDED
@@ -0,0 +1,186 @@
1
+ const { execSync, spawn } = require('child_process')
2
+ const path = require('path')
3
+ const fs = require('fs')
4
+
5
+ /**
6
+ * @gustcss/vite - Vite plugin for CSS Utility Generator
7
+ *
8
+ * Usage in vite.config.ts:
9
+ * import gustcss from '@gustcss/vite'
10
+ * export default defineConfig({
11
+ * plugins: [gustcss({ output: 'src/styles/utility.css' })],
12
+ * })
13
+ */
14
+ function cssUtility(opts = {}) {
15
+ const output = opts.output || 'src/styles/utility.css'
16
+ const content = opts.content || ['./src/**/*.{js,ts,jsx,tsx,astro,vue}']
17
+ const configPath = opts.config
18
+ let watchProcess = null
19
+
20
+ function findBinary(cwd) {
21
+ const possiblePaths = [
22
+ path.join(cwd, 'node_modules', '.bin', 'gustcss'),
23
+ path.join(cwd, '..', '..', 'bin', 'gustcss'), // For sample projects
24
+ 'gustcss', // Global installation
25
+ ]
26
+
27
+ for (const p of possiblePaths) {
28
+ if (p === 'gustcss' || fs.existsSync(p)) {
29
+ return p
30
+ }
31
+ }
32
+
33
+ throw new Error('gustcss binary not found')
34
+ }
35
+
36
+ function findConfigFile(cwd) {
37
+ if (configPath) {
38
+ return configPath
39
+ }
40
+ // Auto-detect config file in current directory
41
+ const defaultConfigPaths = [
42
+ 'gustcss.config.json',
43
+ 'gustcss.config.js',
44
+ ]
45
+ for (const configName of defaultConfigPaths) {
46
+ const fullPath = path.join(cwd, configName)
47
+ if (fs.existsSync(fullPath)) {
48
+ return fullPath
49
+ }
50
+ }
51
+ return null
52
+ }
53
+
54
+ function buildArgs(cwd, extraArgs = []) {
55
+ const args = ['build', ...extraArgs]
56
+ const resolvedConfigPath = findConfigFile(cwd)
57
+
58
+ if (resolvedConfigPath) {
59
+ // Use existing config file
60
+ args.push('--config', resolvedConfigPath)
61
+ } else {
62
+ // Create temporary config file to avoid glob pattern issues with CLI
63
+ const tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
64
+ const tempConfig = { content, output }
65
+ fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
66
+ args.push('--config', tempConfigPath)
67
+ // Note: temp file cleanup happens after build in buildCSS
68
+ }
69
+
70
+ return args
71
+ }
72
+
73
+ function buildCSS(cwd, binaryPath) {
74
+ const resolvedConfigPath = findConfigFile(cwd)
75
+ const args = ['build', '-o', output]
76
+
77
+ let tempConfigPath = null
78
+ if (resolvedConfigPath) {
79
+ args.push('--config', resolvedConfigPath)
80
+ } else {
81
+ tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
82
+ const tempConfig = { content }
83
+ fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
84
+ args.push('--config', tempConfigPath)
85
+ }
86
+
87
+ try {
88
+ execSync(`"${binaryPath}" ${args.join(' ')}`, {
89
+ cwd,
90
+ encoding: 'utf-8',
91
+ stdio: ['pipe', 'pipe', 'pipe'],
92
+ })
93
+ } catch (error) {
94
+ const stderr = error.stderr ? error.stderr.toString() : error.message
95
+ console.error(`gustcss build failed: ${stderr}`)
96
+ } finally {
97
+ // Clean up temporary config file
98
+ if (tempConfigPath && fs.existsSync(tempConfigPath)) {
99
+ fs.unlinkSync(tempConfigPath)
100
+ }
101
+ }
102
+ }
103
+
104
+ return {
105
+ name: 'gustcss',
106
+
107
+ configResolved(config) {
108
+ const cwd = config.root || process.cwd()
109
+ const binaryPath = findBinary(cwd)
110
+
111
+ // Always run initial build
112
+ buildCSS(cwd, binaryPath)
113
+ },
114
+
115
+ configureServer(server) {
116
+ const cwd = server.config.root || process.cwd()
117
+ const binaryPath = findBinary(cwd)
118
+ const resolvedConfigPath = findConfigFile(cwd)
119
+ const outputPath = path.resolve(cwd, output)
120
+
121
+ // First, run initial build synchronously before starting watch mode
122
+ buildCSS(cwd, binaryPath)
123
+
124
+ // Start watch mode (without initial build since we just did it)
125
+ const args = ['build', '--watch', '-o', output]
126
+
127
+ let tempConfigPath = null
128
+ if (resolvedConfigPath) {
129
+ args.push('--config', resolvedConfigPath)
130
+ } else {
131
+ tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
132
+ const tempConfig = { content }
133
+ fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
134
+ args.push('--config', tempConfigPath)
135
+ }
136
+
137
+ watchProcess = spawn(binaryPath, args, {
138
+ cwd,
139
+ stdio: ['pipe', 'pipe', 'pipe'],
140
+ })
141
+
142
+ watchProcess.stderr.on('data', (data) => {
143
+ console.error(`gustcss: ${data}`)
144
+ })
145
+
146
+ // Watch generated CSS file for HMR
147
+ server.watcher.add(outputPath)
148
+ server.watcher.on('change', (changedPath) => {
149
+ if (path.resolve(changedPath) === outputPath) {
150
+ server.ws.send({
151
+ type: 'update',
152
+ updates: [
153
+ {
154
+ type: 'css-update',
155
+ path: '/' + path.relative(cwd, outputPath),
156
+ acceptedPath: '/' + path.relative(cwd, outputPath),
157
+ timestamp: Date.now(),
158
+ },
159
+ ],
160
+ })
161
+ }
162
+ })
163
+
164
+ server.httpServer?.on('close', () => {
165
+ if (watchProcess) {
166
+ watchProcess.kill()
167
+ watchProcess = null
168
+ }
169
+ // Clean up temporary config file
170
+ if (tempConfigPath && fs.existsSync(tempConfigPath)) {
171
+ fs.unlinkSync(tempConfigPath)
172
+ }
173
+ })
174
+ },
175
+
176
+ buildEnd() {
177
+ if (watchProcess) {
178
+ watchProcess.kill()
179
+ watchProcess = null
180
+ }
181
+ },
182
+ }
183
+ }
184
+
185
+ module.exports = { cssUtility }
186
+ module.exports.default = cssUtility
package/index.mjs ADDED
@@ -0,0 +1,186 @@
1
+ const { execSync, spawn } = require('child_process')
2
+ const path = require('path')
3
+ const fs = require('fs')
4
+
5
+ /**
6
+ * @gustcss/vite - Vite plugin for CSS Utility Generator
7
+ *
8
+ * Usage in vite.config.ts:
9
+ * import gustcss from '@gustcss/vite'
10
+ * export default defineConfig({
11
+ * plugins: [gustcss({ output: 'src/styles/utility.css' })],
12
+ * })
13
+ */
14
+ function cssUtility(opts = {}) {
15
+ const output = opts.output || 'src/styles/utility.css'
16
+ const content = opts.content || ['./src/**/*.{js,ts,jsx,tsx,astro,vue}']
17
+ const configPath = opts.config
18
+ let watchProcess = null
19
+
20
+ function findBinary(cwd) {
21
+ const possiblePaths = [
22
+ path.join(cwd, 'node_modules', '.bin', 'gustcss'),
23
+ path.join(cwd, '..', '..', 'bin', 'gustcss'), // For sample projects
24
+ 'gustcss', // Global installation
25
+ ]
26
+
27
+ for (const p of possiblePaths) {
28
+ if (p === 'gustcss' || fs.existsSync(p)) {
29
+ return p
30
+ }
31
+ }
32
+
33
+ throw new Error('gustcss binary not found')
34
+ }
35
+
36
+ function findConfigFile(cwd) {
37
+ if (configPath) {
38
+ return configPath
39
+ }
40
+ // Auto-detect config file in current directory
41
+ const defaultConfigPaths = [
42
+ 'gustcss.config.json',
43
+ 'gustcss.config.js',
44
+ ]
45
+ for (const configName of defaultConfigPaths) {
46
+ const fullPath = path.join(cwd, configName)
47
+ if (fs.existsSync(fullPath)) {
48
+ return fullPath
49
+ }
50
+ }
51
+ return null
52
+ }
53
+
54
+ function buildArgs(cwd, extraArgs = []) {
55
+ const args = ['build', ...extraArgs]
56
+ const resolvedConfigPath = findConfigFile(cwd)
57
+
58
+ if (resolvedConfigPath) {
59
+ // Use existing config file
60
+ args.push('--config', resolvedConfigPath)
61
+ } else {
62
+ // Create temporary config file to avoid glob pattern issues with CLI
63
+ const tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
64
+ const tempConfig = { content, output }
65
+ fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
66
+ args.push('--config', tempConfigPath)
67
+ // Note: temp file cleanup happens after build in buildCSS
68
+ }
69
+
70
+ return args
71
+ }
72
+
73
+ function buildCSS(cwd, binaryPath) {
74
+ const resolvedConfigPath = findConfigFile(cwd)
75
+ const args = ['build', '-o', output]
76
+
77
+ let tempConfigPath = null
78
+ if (resolvedConfigPath) {
79
+ args.push('--config', resolvedConfigPath)
80
+ } else {
81
+ tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
82
+ const tempConfig = { content }
83
+ fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
84
+ args.push('--config', tempConfigPath)
85
+ }
86
+
87
+ try {
88
+ execSync(`"${binaryPath}" ${args.join(' ')}`, {
89
+ cwd,
90
+ encoding: 'utf-8',
91
+ stdio: ['pipe', 'pipe', 'pipe'],
92
+ })
93
+ } catch (error) {
94
+ const stderr = error.stderr ? error.stderr.toString() : error.message
95
+ console.error(`gustcss build failed: ${stderr}`)
96
+ } finally {
97
+ // Clean up temporary config file
98
+ if (tempConfigPath && fs.existsSync(tempConfigPath)) {
99
+ fs.unlinkSync(tempConfigPath)
100
+ }
101
+ }
102
+ }
103
+
104
+ return {
105
+ name: 'gustcss',
106
+
107
+ configResolved(config) {
108
+ const cwd = config.root || process.cwd()
109
+ const binaryPath = findBinary(cwd)
110
+
111
+ // Always run initial build
112
+ buildCSS(cwd, binaryPath)
113
+ },
114
+
115
+ configureServer(server) {
116
+ const cwd = server.config.root || process.cwd()
117
+ const binaryPath = findBinary(cwd)
118
+ const resolvedConfigPath = findConfigFile(cwd)
119
+ const outputPath = path.resolve(cwd, output)
120
+
121
+ // First, run initial build synchronously before starting watch mode
122
+ buildCSS(cwd, binaryPath)
123
+
124
+ // Start watch mode (without initial build since we just did it)
125
+ const args = ['build', '--watch', '-o', output]
126
+
127
+ let tempConfigPath = null
128
+ if (resolvedConfigPath) {
129
+ args.push('--config', resolvedConfigPath)
130
+ } else {
131
+ tempConfigPath = path.join(cwd, '.gustcss.vite.tmp.json')
132
+ const tempConfig = { content }
133
+ fs.writeFileSync(tempConfigPath, JSON.stringify(tempConfig))
134
+ args.push('--config', tempConfigPath)
135
+ }
136
+
137
+ watchProcess = spawn(binaryPath, args, {
138
+ cwd,
139
+ stdio: ['pipe', 'pipe', 'pipe'],
140
+ })
141
+
142
+ watchProcess.stderr.on('data', (data) => {
143
+ console.error(`gustcss: ${data}`)
144
+ })
145
+
146
+ // Watch generated CSS file for HMR
147
+ server.watcher.add(outputPath)
148
+ server.watcher.on('change', (changedPath) => {
149
+ if (path.resolve(changedPath) === outputPath) {
150
+ server.ws.send({
151
+ type: 'update',
152
+ updates: [
153
+ {
154
+ type: 'css-update',
155
+ path: '/' + path.relative(cwd, outputPath),
156
+ acceptedPath: '/' + path.relative(cwd, outputPath),
157
+ timestamp: Date.now(),
158
+ },
159
+ ],
160
+ })
161
+ }
162
+ })
163
+
164
+ server.httpServer?.on('close', () => {
165
+ if (watchProcess) {
166
+ watchProcess.kill()
167
+ watchProcess = null
168
+ }
169
+ // Clean up temporary config file
170
+ if (tempConfigPath && fs.existsSync(tempConfigPath)) {
171
+ fs.unlinkSync(tempConfigPath)
172
+ }
173
+ })
174
+ },
175
+
176
+ buildEnd() {
177
+ if (watchProcess) {
178
+ watchProcess.kill()
179
+ watchProcess = null
180
+ }
181
+ },
182
+ }
183
+ }
184
+
185
+ module.exports = { cssUtility }
186
+ module.exports.default = cssUtility
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@gustcss/vite",
3
+ "version": "0.1.0",
4
+ "description": "Vite plugin for Gust CSS Utility Generator",
5
+ "main": "index.mjs",
6
+ "module": "index.mjs",
7
+ "type": "module",
8
+ "files": [
9
+ "index.cjs",
10
+ "index.mjs",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "exports": {
15
+ ".": {
16
+ "import": "./index.mjs",
17
+ "require": "./index.cjs"
18
+ }
19
+ },
20
+ "keywords": ["vite", "vite-plugin", "gustcss", "gust", "css", "utility"],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "dependencies": {
25
+ "gustcss": "^0.1.0"
26
+ },
27
+ "peerDependencies": {
28
+ "vite": "^4.0.0 || ^5.0.0 || ^6.0.0"
29
+ }
30
+ }