pulse-js-framework 1.2.0 → 1.4.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.
package/cli/index.js CHANGED
@@ -1,351 +1,398 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Pulse CLI - Command line interface
5
- */
6
-
7
- import { fileURLToPath } from 'url';
8
- import { dirname, join, resolve } from 'path';
9
- import { existsSync, mkdirSync, writeFileSync, readFileSync, cpSync } from 'fs';
10
-
11
- const __filename = fileURLToPath(import.meta.url);
12
- const __dirname = dirname(__filename);
13
-
14
- const VERSION = '1.2.0';
15
-
16
- // Command handlers
17
- const commands = {
18
- help: showHelp,
19
- version: showVersion,
20
- create: createProject,
21
- dev: runDev,
22
- build: runBuild,
23
- preview: runPreview,
24
- compile: compileFile,
25
- mobile: runMobile
26
- };
27
-
28
- /**
29
- * Main entry point
30
- */
31
- async function main() {
32
- const args = process.argv.slice(2);
33
- const command = args[0] || 'help';
34
-
35
- if (command in commands) {
36
- await commands[command](args.slice(1));
37
- } else {
38
- console.error(`Unknown command: ${command}`);
39
- console.log('Run "pulse help" for usage information.');
40
- process.exit(1);
41
- }
42
- }
43
-
44
- /**
45
- * Show help message
46
- */
47
- function showHelp() {
48
- console.log(`
49
- Pulse Framework CLI v${VERSION}
50
-
51
- Usage: pulse <command> [options]
52
-
53
- Commands:
54
- create <name> Create a new Pulse project
55
- dev [port] Start development server (default: 3000)
56
- build Build for production (minified)
57
- preview [port] Preview production build (default: 4173)
58
- compile <file> Compile a .pulse file to JavaScript
59
- mobile <cmd> Mobile app commands (init, build, run)
60
- version Show version number
61
- help Show this help message
62
-
63
- Examples:
64
- pulse create my-app
65
- pulse dev
66
- pulse dev 8080
67
- pulse build
68
- pulse preview
69
- pulse mobile init
70
- pulse mobile build android
71
- pulse mobile run ios
72
- pulse compile src/App.pulse
73
-
74
- Documentation: https://github.com/vincenthirtz/pulse-js-framework
75
- `);
76
- }
77
-
78
- /**
79
- * Show version
80
- */
81
- function showVersion() {
82
- console.log(`Pulse Framework v${VERSION}`);
83
- }
84
-
85
- /**
86
- * Create a new project
87
- */
88
- async function createProject(args) {
89
- const projectName = args[0];
90
-
91
- if (!projectName) {
92
- console.error('Please provide a project name.');
93
- console.log('Usage: pulse create <project-name>');
94
- process.exit(1);
95
- }
96
-
97
- const projectPath = resolve(process.cwd(), projectName);
98
-
99
- if (existsSync(projectPath)) {
100
- console.error(`Directory "${projectName}" already exists.`);
101
- process.exit(1);
102
- }
103
-
104
- console.log(`Creating new Pulse project: ${projectName}`);
105
-
106
- // Create project structure
107
- mkdirSync(projectPath);
108
- mkdirSync(join(projectPath, 'src'));
109
- mkdirSync(join(projectPath, 'public'));
110
-
111
- // Create package.json
112
- const packageJson = {
113
- name: projectName,
114
- version: '0.1.0',
115
- type: 'module',
116
- scripts: {
117
- dev: 'pulse dev',
118
- build: 'pulse build',
119
- preview: 'vite preview'
120
- },
121
- dependencies: {
122
- 'pulse-js-framework': '^1.0.0'
123
- },
124
- devDependencies: {
125
- vite: '^5.0.0'
126
- }
127
- };
128
-
129
- writeFileSync(
130
- join(projectPath, 'package.json'),
131
- JSON.stringify(packageJson, null, 2)
132
- );
133
-
134
- // Create vite.config.js
135
- const viteConfig = `import { defineConfig } from 'vite';
136
- import pulse from 'pulse-js-framework/vite';
137
-
138
- export default defineConfig({
139
- plugins: [pulse()]
140
- });
141
- `;
142
-
143
- writeFileSync(join(projectPath, 'vite.config.js'), viteConfig);
144
-
145
- // Create index.html
146
- const indexHtml = `<!DOCTYPE html>
147
- <html lang="en">
148
- <head>
149
- <meta charset="UTF-8">
150
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
151
- <title>${projectName}</title>
152
- </head>
153
- <body>
154
- <div id="app"></div>
155
- <script type="module" src="/src/main.js"></script>
156
- </body>
157
- </html>
158
- `;
159
-
160
- writeFileSync(join(projectPath, 'index.html'), indexHtml);
161
-
162
- // Create main.js
163
- const mainJs = `import App from './App.pulse';
164
-
165
- App.mount('#app');
166
- `;
167
-
168
- writeFileSync(join(projectPath, 'src', 'main.js'), mainJs);
169
-
170
- // Create App.pulse
171
- const appPulse = `@page App
172
-
173
- state {
174
- count: 0
175
- name: "Pulse"
176
- }
177
-
178
- view {
179
- #app {
180
- h1.title "Welcome to {name}!"
181
-
182
- .counter {
183
- p "Count: {count}"
184
-
185
- .buttons {
186
- button @click(count--) "-"
187
- button @click(count++) "+"
188
- }
189
- }
190
-
191
- p.info "Edit src/App.pulse and save to hot reload."
192
- }
193
- }
194
-
195
- style {
196
- #app {
197
- font-family: system-ui, -apple-system, sans-serif
198
- max-width: 600px
199
- margin: 0 auto
200
- padding: 40px 20px
201
- text-align: center
202
- }
203
-
204
- .title {
205
- color: #646cff
206
- font-size: 2.5em
207
- margin-bottom: 30px
208
- }
209
-
210
- .counter {
211
- background: #f5f5f5
212
- padding: 30px
213
- border-radius: 12px
214
- margin-bottom: 20px
215
-
216
- p {
217
- font-size: 1.5em
218
- margin-bottom: 20px
219
- }
220
- }
221
-
222
- .buttons {
223
- display: flex
224
- gap: 10px
225
- justify-content: center
226
-
227
- button {
228
- font-size: 1.2em
229
- padding: 10px 24px
230
- border: none
231
- border-radius: 8px
232
- background: #646cff
233
- color: white
234
- cursor: pointer
235
- transition: background 0.2s
236
- }
237
-
238
- button:hover {
239
- background: #535bf2
240
- }
241
- }
242
-
243
- .info {
244
- color: #888
245
- font-size: 0.9em
246
- }
247
- }
248
- `;
249
-
250
- writeFileSync(join(projectPath, 'src', 'App.pulse'), appPulse);
251
-
252
- // Create .gitignore
253
- const gitignore = `node_modules
254
- dist
255
- .DS_Store
256
- *.local
257
- `;
258
-
259
- writeFileSync(join(projectPath, '.gitignore'), gitignore);
260
-
261
- console.log(`
262
- Project created successfully!
263
-
264
- Next steps:
265
- cd ${projectName}
266
- npm install
267
- npm run dev
268
-
269
- Happy coding with Pulse!
270
- `);
271
- }
272
-
273
- /**
274
- * Run development server
275
- */
276
- async function runDev(args) {
277
- console.log('Starting Pulse development server...');
278
-
279
- // Use dynamic import for the dev server module
280
- const { startDevServer } = await import('./dev.js');
281
- await startDevServer(args);
282
- }
283
-
284
- /**
285
- * Build for production
286
- */
287
- async function runBuild(args) {
288
- console.log('Building Pulse project for production...');
289
-
290
- const { buildProject } = await import('./build.js');
291
- await buildProject(args);
292
- }
293
-
294
- /**
295
- * Preview production build
296
- */
297
- async function runPreview(args) {
298
- console.log('Starting Pulse preview server...');
299
-
300
- const { previewBuild } = await import('./build.js');
301
- await previewBuild(args);
302
- }
303
-
304
- /**
305
- * Run mobile commands
306
- */
307
- async function runMobile(args) {
308
- const { handleMobileCommand } = await import('./mobile.js');
309
- await handleMobileCommand(args);
310
- }
311
-
312
- /**
313
- * Compile a single .pulse file
314
- */
315
- async function compileFile(args) {
316
- const inputFile = args[0];
317
-
318
- if (!inputFile) {
319
- console.error('Please provide a file to compile.');
320
- console.log('Usage: pulse compile <file.pulse>');
321
- process.exit(1);
322
- }
323
-
324
- if (!existsSync(inputFile)) {
325
- console.error(`File not found: ${inputFile}`);
326
- process.exit(1);
327
- }
328
-
329
- const { compile } = await import('../compiler/index.js');
330
-
331
- const source = readFileSync(inputFile, 'utf-8');
332
- const result = compile(source);
333
-
334
- if (result.success) {
335
- const outputFile = inputFile.replace(/\.pulse$/, '.js');
336
- writeFileSync(outputFile, result.code);
337
- console.log(`Compiled: ${inputFile} -> ${outputFile}`);
338
- } else {
339
- console.error('Compilation failed:');
340
- for (const error of result.errors) {
341
- console.error(` ${error.message}`);
342
- }
343
- process.exit(1);
344
- }
345
- }
346
-
347
- // Run main
348
- main().catch(error => {
349
- console.error('Error:', error.message);
350
- process.exit(1);
351
- });
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Pulse CLI - Command line interface
5
+ */
6
+
7
+ import { fileURLToPath } from 'url';
8
+ import { dirname, join, resolve } from 'path';
9
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, cpSync } from 'fs';
10
+
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = dirname(__filename);
13
+
14
+ const VERSION = '1.4.1';
15
+
16
+ // Command handlers
17
+ const commands = {
18
+ help: showHelp,
19
+ version: showVersion,
20
+ create: createProject,
21
+ dev: runDev,
22
+ build: runBuild,
23
+ preview: runPreview,
24
+ compile: compileFile,
25
+ mobile: runMobile,
26
+ lint: runLint,
27
+ format: runFormat,
28
+ analyze: runAnalyze
29
+ };
30
+
31
+ /**
32
+ * Main entry point
33
+ */
34
+ async function main() {
35
+ const args = process.argv.slice(2);
36
+ const command = args[0] || 'help';
37
+
38
+ if (command in commands) {
39
+ await commands[command](args.slice(1));
40
+ } else {
41
+ console.error(`Unknown command: ${command}`);
42
+ console.log('Run "pulse help" for usage information.');
43
+ process.exit(1);
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Show help message
49
+ */
50
+ function showHelp() {
51
+ console.log(`
52
+ Pulse Framework CLI v${VERSION}
53
+
54
+ Usage: pulse <command> [options]
55
+
56
+ Commands:
57
+ create <name> Create a new Pulse project
58
+ dev [port] Start development server (default: 3000)
59
+ build Build for production (minified)
60
+ preview [port] Preview production build (default: 4173)
61
+ compile <file> Compile a .pulse file to JavaScript
62
+ mobile <cmd> Mobile app commands (init, build, run)
63
+ lint [files] Validate .pulse files for errors and style
64
+ format [files] Format .pulse files consistently
65
+ analyze Analyze bundle size and dependencies
66
+ version Show version number
67
+ help Show this help message
68
+
69
+ Lint Options:
70
+ --fix Auto-fix fixable issues
71
+
72
+ Format Options:
73
+ --check Check formatting without writing
74
+ --write Write formatted output (default)
75
+
76
+ Analyze Options:
77
+ --json Output analysis as JSON
78
+ --verbose Show detailed metrics
79
+
80
+ Examples:
81
+ pulse create my-app
82
+ pulse dev
83
+ pulse dev 8080
84
+ pulse build
85
+ pulse preview
86
+ pulse mobile init
87
+ pulse mobile build android
88
+ pulse mobile run ios
89
+ pulse compile src/App.pulse
90
+ pulse lint src/
91
+ pulse lint "**/*.pulse" --fix
92
+ pulse format --check
93
+ pulse format src/App.pulse
94
+ pulse analyze
95
+ pulse analyze --json
96
+
97
+ Documentation: https://github.com/vincenthirtz/pulse-js-framework
98
+ `);
99
+ }
100
+
101
+ /**
102
+ * Show version
103
+ */
104
+ function showVersion() {
105
+ console.log(`Pulse Framework v${VERSION}`);
106
+ }
107
+
108
+ /**
109
+ * Create a new project
110
+ */
111
+ async function createProject(args) {
112
+ const projectName = args[0];
113
+
114
+ if (!projectName) {
115
+ console.error('Please provide a project name.');
116
+ console.log('Usage: pulse create <project-name>');
117
+ process.exit(1);
118
+ }
119
+
120
+ const projectPath = resolve(process.cwd(), projectName);
121
+
122
+ if (existsSync(projectPath)) {
123
+ console.error(`Directory "${projectName}" already exists.`);
124
+ process.exit(1);
125
+ }
126
+
127
+ console.log(`Creating new Pulse project: ${projectName}`);
128
+
129
+ // Create project structure
130
+ mkdirSync(projectPath);
131
+ mkdirSync(join(projectPath, 'src'));
132
+ mkdirSync(join(projectPath, 'public'));
133
+
134
+ // Create package.json
135
+ const packageJson = {
136
+ name: projectName,
137
+ version: '0.1.0',
138
+ type: 'module',
139
+ scripts: {
140
+ dev: 'pulse dev',
141
+ build: 'pulse build',
142
+ preview: 'vite preview'
143
+ },
144
+ dependencies: {
145
+ 'pulse-js-framework': '^1.0.0'
146
+ },
147
+ devDependencies: {
148
+ vite: '^5.0.0'
149
+ }
150
+ };
151
+
152
+ writeFileSync(
153
+ join(projectPath, 'package.json'),
154
+ JSON.stringify(packageJson, null, 2)
155
+ );
156
+
157
+ // Create vite.config.js
158
+ const viteConfig = `import { defineConfig } from 'vite';
159
+ import pulse from 'pulse-js-framework/vite';
160
+
161
+ export default defineConfig({
162
+ plugins: [pulse()]
163
+ });
164
+ `;
165
+
166
+ writeFileSync(join(projectPath, 'vite.config.js'), viteConfig);
167
+
168
+ // Create index.html
169
+ const indexHtml = `<!DOCTYPE html>
170
+ <html lang="en">
171
+ <head>
172
+ <meta charset="UTF-8">
173
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
174
+ <title>${projectName}</title>
175
+ </head>
176
+ <body>
177
+ <div id="app"></div>
178
+ <script type="module" src="/src/main.js"></script>
179
+ </body>
180
+ </html>
181
+ `;
182
+
183
+ writeFileSync(join(projectPath, 'index.html'), indexHtml);
184
+
185
+ // Create main.js
186
+ const mainJs = `import App from './App.pulse';
187
+
188
+ App.mount('#app');
189
+ `;
190
+
191
+ writeFileSync(join(projectPath, 'src', 'main.js'), mainJs);
192
+
193
+ // Create App.pulse
194
+ const appPulse = `@page App
195
+
196
+ state {
197
+ count: 0
198
+ name: "Pulse"
199
+ }
200
+
201
+ view {
202
+ #app {
203
+ h1.title "Welcome to {name}!"
204
+
205
+ .counter {
206
+ p "Count: {count}"
207
+
208
+ .buttons {
209
+ button @click(count--) "-"
210
+ button @click(count++) "+"
211
+ }
212
+ }
213
+
214
+ p.info "Edit src/App.pulse and save to hot reload."
215
+ }
216
+ }
217
+
218
+ style {
219
+ #app {
220
+ font-family: system-ui, -apple-system, sans-serif
221
+ max-width: 600px
222
+ margin: 0 auto
223
+ padding: 40px 20px
224
+ text-align: center
225
+ }
226
+
227
+ .title {
228
+ color: #646cff
229
+ font-size: 2.5em
230
+ margin-bottom: 30px
231
+ }
232
+
233
+ .counter {
234
+ background: #f5f5f5
235
+ padding: 30px
236
+ border-radius: 12px
237
+ margin-bottom: 20px
238
+
239
+ p {
240
+ font-size: 1.5em
241
+ margin-bottom: 20px
242
+ }
243
+ }
244
+
245
+ .buttons {
246
+ display: flex
247
+ gap: 10px
248
+ justify-content: center
249
+
250
+ button {
251
+ font-size: 1.2em
252
+ padding: 10px 24px
253
+ border: none
254
+ border-radius: 8px
255
+ background: #646cff
256
+ color: white
257
+ cursor: pointer
258
+ transition: background 0.2s
259
+ }
260
+
261
+ button:hover {
262
+ background: #535bf2
263
+ }
264
+ }
265
+
266
+ .info {
267
+ color: #888
268
+ font-size: 0.9em
269
+ }
270
+ }
271
+ `;
272
+
273
+ writeFileSync(join(projectPath, 'src', 'App.pulse'), appPulse);
274
+
275
+ // Create .gitignore
276
+ const gitignore = `node_modules
277
+ dist
278
+ .DS_Store
279
+ *.local
280
+ `;
281
+
282
+ writeFileSync(join(projectPath, '.gitignore'), gitignore);
283
+
284
+ console.log(`
285
+ Project created successfully!
286
+
287
+ Next steps:
288
+ cd ${projectName}
289
+ npm install
290
+ npm run dev
291
+
292
+ Happy coding with Pulse!
293
+ `);
294
+ }
295
+
296
+ /**
297
+ * Run development server
298
+ */
299
+ async function runDev(args) {
300
+ console.log('Starting Pulse development server...');
301
+
302
+ // Use dynamic import for the dev server module
303
+ const { startDevServer } = await import('./dev.js');
304
+ await startDevServer(args);
305
+ }
306
+
307
+ /**
308
+ * Build for production
309
+ */
310
+ async function runBuild(args) {
311
+ console.log('Building Pulse project for production...');
312
+
313
+ const { buildProject } = await import('./build.js');
314
+ await buildProject(args);
315
+ }
316
+
317
+ /**
318
+ * Preview production build
319
+ */
320
+ async function runPreview(args) {
321
+ console.log('Starting Pulse preview server...');
322
+
323
+ const { previewBuild } = await import('./build.js');
324
+ await previewBuild(args);
325
+ }
326
+
327
+ /**
328
+ * Run mobile commands
329
+ */
330
+ async function runMobile(args) {
331
+ const { handleMobileCommand } = await import('./mobile.js');
332
+ await handleMobileCommand(args);
333
+ }
334
+
335
+ /**
336
+ * Run lint command
337
+ */
338
+ async function runLint(args) {
339
+ const { runLint } = await import('./lint.js');
340
+ await runLint(args);
341
+ }
342
+
343
+ /**
344
+ * Run format command
345
+ */
346
+ async function runFormat(args) {
347
+ const { runFormat } = await import('./format.js');
348
+ await runFormat(args);
349
+ }
350
+
351
+ /**
352
+ * Run analyze command
353
+ */
354
+ async function runAnalyze(args) {
355
+ const { runAnalyze } = await import('./analyze.js');
356
+ await runAnalyze(args);
357
+ }
358
+
359
+ /**
360
+ * Compile a single .pulse file
361
+ */
362
+ async function compileFile(args) {
363
+ const inputFile = args[0];
364
+
365
+ if (!inputFile) {
366
+ console.error('Please provide a file to compile.');
367
+ console.log('Usage: pulse compile <file.pulse>');
368
+ process.exit(1);
369
+ }
370
+
371
+ if (!existsSync(inputFile)) {
372
+ console.error(`File not found: ${inputFile}`);
373
+ process.exit(1);
374
+ }
375
+
376
+ const { compile } = await import('../compiler/index.js');
377
+
378
+ const source = readFileSync(inputFile, 'utf-8');
379
+ const result = compile(source);
380
+
381
+ if (result.success) {
382
+ const outputFile = inputFile.replace(/\.pulse$/, '.js');
383
+ writeFileSync(outputFile, result.code);
384
+ console.log(`Compiled: ${inputFile} -> ${outputFile}`);
385
+ } else {
386
+ console.error('Compilation failed:');
387
+ for (const error of result.errors) {
388
+ console.error(` ${error.message}`);
389
+ }
390
+ process.exit(1);
391
+ }
392
+ }
393
+
394
+ // Run main
395
+ main().catch(error => {
396
+ console.error('Error:', error.message);
397
+ process.exit(1);
398
+ });