fsdcats 1.0.0 → 1.0.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/README.md CHANGED
@@ -1,63 +1,23 @@
1
- # Fullstack Practical Exam Cheatsheet (fsdcats)
1
+ # fsdcats
2
2
 
3
- This package generates **clean text files (`.txt`)** containing the **step-by-step terminal setup instructions** and the **exact minimal component code** (separated by clean headers and gaps) for your Fullstack practical exam.
3
+ Minimal exam code generator with automatic clipboard copy.
4
4
 
5
- ---
5
+ ## Usage
6
6
 
7
- ## 📚 Scope Covered
8
-
9
- 1. **Practical 1: Vue Directives** (`v-if`, `v-else`, `v-model`, `v-show`, `v-for`, `v-on`) ➔ `practical-1.txt`
10
- 2. **Practical 2: Data Binding (Props and Emits)** (Parent-to-Child & Child-to-Parent) ➔ `practical-2.txt`
11
- 3. **Practical 3: Document Upload & Preview (Vue 3 + Express + Multer)** ➔ `practical-3.txt`
12
- 4. **Practical 4: Localized State Management (Pinia Multi-Step Form)** ➔ `practical-4.txt`
13
- 5. **Practical 5: Routing in Nuxt and Shared Layouts** (`pages/`, `[id].vue`, `layouts/default.vue`) ➔ `practical-5.txt`
14
- 6. **CRUD Operations: Express + Mongoose REST API** (Create, Read, Update, Delete) ➔ `practical-crud.txt`
15
-
16
- ---
17
-
18
- ## ⚡ How to Use fsdcats
19
-
20
- Whenever you run the command for any practical, **a formatted `.txt` file is generated and automatically opened in your text editor**.
21
-
22
- ### 1. Generate via npx (Zero Installation)
23
- ```bash
24
- npx fsdcats 1 # Generates & opens practical-1.txt
25
- npx fsdcats 2 # Generates & opens practical-2.txt
26
- npx fsdcats 3 # Generates & opens practical-3.txt
27
- npx fsdcats 4 # Generates & opens practical-4.txt
28
- npx fsdcats 5 # Generates & opens practical-5.txt
29
- npx fsdcats crud # Generates & opens practical-crud.txt
30
- npx fsdcats all # Generates ALL practical text files at once!
31
- ```
32
-
33
- ### 2. Interactive Menu
34
- Just run:
35
7
  ```bash
36
- npx fsdcats
8
+ npx fsdcats 1 # Vue Directives
9
+ npx fsdcats 2 # Props & Emits
10
+ npx fsdcats 3 # File Upload
11
+ npx fsdcats 4 # Pinia Multi-Step Form
12
+ npx fsdcats 5 # Nuxt Routing & Layouts
13
+ npx fsdcats crud # Mongoose CRUD API
14
+ npx fsdcats all # All practicals
37
15
  ```
38
- And select a number from `1` to `5`, `crud`, or `all`.
39
-
40
- ---
41
16
 
42
- ## 📄 Structure of the Generated Text Files
17
+ Running any command creates the `.txt` file and **automatically copies the entire text directly to your clipboard**.
43
18
 
44
- Each generated `.txt` file contains:
45
- 1. **SECTION 1: STEP-BY-STEP PROJECT SETUP**
46
- - Exact terminal commands (`npm create vue@latest ...`, `cd ...`, `npm install`, `npm run dev`).
47
- - Every single prompt choice (e.g. selecting `No` for TypeScript, ESLint, Prettier to avoid exam errors).
48
- 2. **SECTION 2: COMPONENT CODE FILES**
49
- - Clearly separated by visible spacing/gaps.
50
- - Component Name & target file path (e.g., `COMPONENT NAME: App.vue`, `TARGET PATH: src/App.vue`).
51
- - Clean, minimal code ready to copy-paste.
19
+ ## Publish to npm
52
20
 
53
- ---
54
-
55
- ## 🚀 How to Publish to npm
56
-
57
- In your terminal (inside `/Users/spare/Downloads/fullstack`), run:
58
21
  ```bash
59
- npm publish --access public --otp=YOUR_6_DIGIT_OTP
22
+ npm publish --access public --otp=YOUR_OTP
60
23
  ```
61
- *(Replace `YOUR_6_DIGIT_OTP` with the active code from your authenticator app).*
62
-
63
- Once published, you or your friends can run `npx fsdcats 1` on **any computer in the world**!
@@ -1,25 +1,19 @@
1
- PRACTICAL 1: VUE DIRECTIVES (V-IF/ELSE, V-SHOW, V-FOR, V-ON, V-MODEL)
2
-
3
-
4
-
5
-
6
1
  SETUP:
7
2
 
8
3
  1. Run:
9
4
  npm create vue@latest my-vue-p1
10
5
 
11
- 2. Terminal Prompts:
12
- Select No to all options (TypeScript, Router, Pinia, Vitest, ESLint, Prettier).
6
+ 2. Prompts:
7
+ Select No to all options.
13
8
 
14
9
  3. cd my-vue-p1
15
10
  npm install
16
11
 
17
12
  4. npm run dev
18
- (App runs on http://localhost:5173)
19
13
 
20
- 5. Files to create/update:
14
+ 5. Files:
21
15
  - Create src/users.json
22
- - Replace src/App.vue with the code below.
16
+ - Replace src/App.vue with code below.
23
17
 
24
18
 
25
19
 
@@ -72,7 +66,7 @@ function handleLogout() {
72
66
 
73
67
  <template>
74
68
  <div style="font-family: sans-serif; max-width: 400px; margin: 30px auto; padding: 20px; border: 1px solid #ccc; border-radius: 8px;">
75
- <!-- 1. v-if / v-else: Toggle between Login and Dashboard -->
69
+ <!-- 1. v-if / v-else: Toggle between Login Screen and Dashboard -->
76
70
  <div v-if="!currentUser">
77
71
  <h2>System Login</h2>
78
72
  <!-- 2. v-model: Two-way input binding -->
@@ -114,17 +108,12 @@ function handleLogout() {
114
108
 
115
109
 
116
110
 
117
- PRACTICAL 2: DATA BINDING (PROPS AND EMITS)
118
-
119
-
120
-
121
-
122
111
  SETUP:
123
112
 
124
113
  1. Run:
125
114
  npm create vue@latest my-vue-p2
126
115
 
127
- 2. Terminal Prompts:
116
+ 2. Prompts:
128
117
  Select No to all options.
129
118
 
130
119
  3. cd my-vue-p2
@@ -132,9 +121,9 @@ SETUP:
132
121
 
133
122
  4. npm run dev
134
123
 
135
- 5. Files to create/update:
136
- - Create src/DriverCard.vue (Child component)
137
- - Replace src/App.vue with the code below (Parent component).
124
+ 5. Files:
125
+ - Create src/DriverCard.vue
126
+ - Replace src/App.vue with code below.
138
127
 
139
128
 
140
129
 
@@ -238,29 +227,24 @@ function addDriver() {
238
227
 
239
228
 
240
229
 
241
- PRACTICAL 3: DOCUMENT UPLOAD & PREVIEW SYSTEM (VUE 3 + EXPRESS + MULTER)
242
-
243
-
244
-
245
-
246
230
  SETUP:
247
231
 
248
- Backend Setup:
232
+ Backend:
249
233
  1. mkdir backend && cd backend
250
234
  2. npm init -y
251
235
  3. npm install express multer cors
252
- 4. Create server.js and paste the server.js code below.
236
+ 4. Create server.js and paste code below.
253
237
  5. node server.js
254
238
  (Runs on http://localhost:5000)
255
239
 
256
- Frontend Setup:
257
- 1. In a new terminal:
240
+ Frontend:
241
+ 1. In another terminal:
258
242
  npm create vue@latest frontend
259
243
  (Select No to all options)
260
244
  2. cd frontend && npm install
261
245
  3. npm run dev
262
246
  (Runs on http://localhost:5173)
263
- 4. Replace frontend/src/App.vue with the App.vue code below.
247
+ 4. Replace frontend/src/App.vue with code below.
264
248
 
265
249
 
266
250
 
@@ -269,7 +253,7 @@ Frontend Setup:
269
253
  COMPONENTS:
270
254
 
271
255
 
272
- COMPONENT: server.js (Backend)
256
+ COMPONENT: server.js
273
257
  PATH: backend/server.js
274
258
 
275
259
  const express = require('express');
@@ -337,7 +321,7 @@ app.listen(5000, () => console.log('Backend running on http://localhost:5000'));
337
321
 
338
322
 
339
323
 
340
- COMPONENT: App.vue (Frontend)
324
+ COMPONENT: App.vue
341
325
  PATH: frontend/src/App.vue
342
326
 
343
327
  <script setup>
@@ -418,25 +402,21 @@ onMounted(fetchDocuments)
418
402
 
419
403
 
420
404
 
421
- PRACTICAL 4: LOCALIZED STATE MANAGEMENT (PINIA MULTI-STEP FORM)
422
-
423
-
424
-
425
-
426
405
  SETUP:
427
406
 
428
- Frontend Setup:
407
+ Frontend:
429
408
  1. npm create vue@latest frontend
430
409
  (Select YES to Pinia, No to everything else)
431
410
  2. cd frontend && npm install
432
411
  3. npm run dev
433
- 4. Create src/store.js and replace src/App.vue with the code below.
412
+ 4. Create src/store.js
413
+ Replace src/App.vue with code below.
434
414
 
435
- Backend Setup (MongoDB):
415
+ Backend:
436
416
  1. mkdir backend && cd backend
437
417
  2. npm init -y
438
418
  3. npm install express mongoose cors
439
- 4. Create server.js and paste the server.js code below.
419
+ 4. Create server.js and paste code below.
440
420
  5. node server.js
441
421
 
442
422
 
@@ -446,7 +426,7 @@ Backend Setup (MongoDB):
446
426
  COMPONENTS:
447
427
 
448
428
 
449
- COMPONENT: store.js (Pinia Store)
429
+ COMPONENT: store.js
450
430
  PATH: frontend/src/store.js
451
431
 
452
432
  import { defineStore } from 'pinia'
@@ -493,7 +473,7 @@ export const useApplicationStore = defineStore('application', {
493
473
 
494
474
 
495
475
 
496
- COMPONENT: App.vue (Frontend)
476
+ COMPONENT: App.vue
497
477
  PATH: frontend/src/App.vue
498
478
 
499
479
  <script setup>
@@ -555,7 +535,7 @@ const store = useApplicationStore()
555
535
 
556
536
 
557
537
 
558
- COMPONENT: server.js (Backend)
538
+ COMPONENT: server.js
559
539
  PATH: backend/server.js
560
540
 
561
541
  const express = require('express');
@@ -604,11 +584,6 @@ mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/job_app_db'
604
584
 
605
585
 
606
586
 
607
- PRACTICAL 5: ROUTING IN NUXT AND SHARED LAYOUTS
608
-
609
-
610
-
611
-
612
587
  SETUP:
613
588
 
614
589
  1. Run:
@@ -623,7 +598,7 @@ SETUP:
623
598
  3. cd nuxt-lab && npm run dev
624
599
  (Runs on http://localhost:3000)
625
600
 
626
- 4. Create the following files inside app/ (or root):
601
+ 4. Create files inside app/ (or root):
627
602
  - app/app.vue
628
603
  - app/layouts/default.vue
629
604
  - app/layouts/minimal.vue
@@ -653,7 +628,7 @@ PATH: app/app.vue
653
628
 
654
629
 
655
630
 
656
- COMPONENT: default.vue (Shared Layout)
631
+ COMPONENT: default.vue
657
632
  PATH: app/layouts/default.vue
658
633
 
659
634
  <!-- app/layouts/default.vue: Shared Layout with persistent header & footer -->
@@ -682,7 +657,7 @@ PATH: app/layouts/default.vue
682
657
 
683
658
 
684
659
 
685
- COMPONENT: minimal.vue (Minimal Layout)
660
+ COMPONENT: minimal.vue
686
661
  PATH: app/layouts/minimal.vue
687
662
 
688
663
  <!-- app/layouts/minimal.vue: Custom headerless layout -->
@@ -699,7 +674,7 @@ PATH: app/layouts/minimal.vue
699
674
 
700
675
 
701
676
 
702
- COMPONENT: index.vue (Home Page)
677
+ COMPONENT: index.vue
703
678
  PATH: app/pages/index.vue
704
679
 
705
680
  <!-- app/pages/index.vue: Root landing page (Route: /) -->
@@ -715,7 +690,7 @@ PATH: app/pages/index.vue
715
690
 
716
691
 
717
692
 
718
- COMPONENT: about.vue (About Page)
693
+ COMPONENT: about.vue
719
694
  PATH: app/pages/about.vue
720
695
 
721
696
  <!-- app/pages/about.vue: Route: /about (uses minimal layout) -->
@@ -737,7 +712,7 @@ definePageMeta({
737
712
 
738
713
 
739
714
 
740
- COMPONENT: items/index.vue (List Page)
715
+ COMPONENT: items/index.vue
741
716
  PATH: app/pages/items/index.vue
742
717
 
743
718
  <!-- app/pages/items/index.vue: Route: /items -->
@@ -767,7 +742,7 @@ const books = [
767
742
 
768
743
 
769
744
 
770
- COMPONENT: items/[id].vue (Dynamic Detail Page)
745
+ COMPONENT: items/[id].vue
771
746
  PATH: app/pages/items/[id].vue
772
747
 
773
748
  <!-- app/pages/items/[id].vue: Dynamic Wildcard Route: /items/:id -->
@@ -813,17 +788,12 @@ const book = books.find(b => b.id === bookId)
813
788
 
814
789
 
815
790
 
816
- PRACTICAL CRUD: EXPRESS + MONGOOSE REST API
817
-
818
-
819
-
820
-
821
791
  SETUP:
822
792
 
823
793
  1. mkdir crud-backend && cd crud-backend
824
794
  2. npm init -y
825
795
  3. npm install express mongoose
826
- 4. Create server.js and paste the server.js code below.
796
+ 4. Create server.js and paste code below.
827
797
  5. node server.js
828
798
  (Runs on http://localhost:5000)
829
799
 
package/bin/cli.js CHANGED
@@ -1,14 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const path = require('path');
4
3
  const readline = require('readline');
5
- const { practicalsData, generatePracticalFile, generateAllFiles } = require('../lib/generator');
6
-
7
- function printBanner() {
8
- console.log('\n============================================================');
9
- console.log(' FULLSTACK PRACTICAL EXAM CHEATSHEET GENERATOR (fsdcats) ');
10
- console.log('============================================================\n');
11
- }
4
+ const { generatePracticalFile, generateAllFiles } = require('../lib/generator');
12
5
 
13
6
  const arg = process.argv[2];
14
7
 
@@ -16,66 +9,40 @@ if (arg) {
16
9
  const cleanArg = arg.toLowerCase().replace(/^p/, '');
17
10
 
18
11
  if (cleanArg === 'all') {
19
- printBanner();
20
- console.log('⏳ Generating text files for ALL practicals...');
21
12
  const results = generateAllFiles(process.cwd());
22
- console.log(`\n🎉 Successfully generated ${results.length} files in current directory:\n`);
23
- results.forEach(r => console.log(` 📄 ${r.fileName} -> ${r.outPath}`));
24
- console.log('\nText files are ready and opened for viewing!\n');
13
+ console.log(`Generated & copied to clipboard (${results.length} files).`);
25
14
  process.exit(0);
26
15
  }
27
16
 
28
17
  const result = generatePracticalFile(cleanArg, process.cwd());
29
18
  if (result) {
30
- printBanner();
31
- console.log(`✅ Generated: ${result.fileName}`);
32
- console.log(`📍 Path: ${result.outPath}`);
33
- console.log(`\nText file has been created and opened! You can copy-paste the steps and components.`);
19
+ console.log(`Copied to clipboard: ${result.fileName}`);
34
20
  process.exit(0);
35
21
  } else {
36
- console.log(`\nUnknown practical: "${arg}". Use 1, 2, 3, 4, 5, crud, or all.\n`);
22
+ console.log(`Unknown practical: ${arg} (use 1, 2, 3, 4, 5, crud, or all)`);
23
+ process.exit(1);
37
24
  }
38
25
  }
39
26
 
40
- // Interactive menu if no argument given
41
- printBanner();
42
- console.log('Select a practical to generate its text file (Setup Steps + Component Code):\n');
43
-
44
- const keys = ['1', '2', '3', '4', '5', 'crud'];
45
- keys.forEach(k => {
46
- console.log(` [${k}] ${practicalsData[k].title} -> (${practicalsData[k].fileName})`);
47
- });
48
- console.log(' [all] Generate text files for ALL practicals');
49
- console.log(' [q] Quit\n');
50
-
51
27
  const rl = readline.createInterface({
52
28
  input: process.stdin,
53
29
  output: process.stdout
54
30
  });
55
31
 
56
- rl.question('Enter your choice (1-5, crud, all): ', (answer) => {
32
+ rl.question('Select practical (1, 2, 3, 4, 5, crud, all): ', (answer) => {
57
33
  rl.close();
58
34
  const choice = answer.trim().toLowerCase().replace(/^p/, '');
59
35
 
60
- if (choice === 'q') {
61
- console.log('Goodbye!');
62
- process.exit(0);
63
- }
64
-
65
36
  if (choice === 'all') {
66
37
  const results = generateAllFiles(process.cwd());
67
- console.log(`\n🎉 Successfully generated ${results.length} files:\n`);
68
- results.forEach(r => console.log(` 📄 ${r.fileName}`));
69
- console.log('\nText files created and opened!\n');
38
+ console.log(`Generated & copied to clipboard (${results.length} files).`);
70
39
  return;
71
40
  }
72
41
 
73
42
  const res = generatePracticalFile(choice, process.cwd());
74
43
  if (res) {
75
- console.log(`\n✅ Generated: ${res.fileName}`);
76
- console.log(`📍 Location: ${res.outPath}`);
77
- console.log('\nText file created and opened!\n');
44
+ console.log(`Copied to clipboard: ${res.fileName}`);
78
45
  } else {
79
- console.log('\nInvalid selection. Run command again.\n');
46
+ console.log('Invalid selection.');
80
47
  }
81
48
  });
package/lib/generator.js CHANGED
@@ -1,21 +1,15 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
- const { exec } = require('child_process');
3
+ const { exec, spawn } = require('child_process');
4
4
  const practicalsData = require('./practicalsData');
5
5
 
6
6
  function formatPracticalText(practical) {
7
7
  let output = '';
8
8
 
9
- // Title
10
- output += `${practical.title.toUpperCase()}\n`;
11
- output += `\n\n\n\n`;
12
-
13
- // Setup Section
14
9
  output += `SETUP:\n\n`;
15
10
  output += `${practical.setupSteps.trim()}\n`;
16
11
  output += `\n\n\n\n\n`;
17
12
 
18
- // Components Section
19
13
  output += `COMPONENTS:\n\n\n`;
20
14
 
21
15
  practical.components.forEach((comp) => {
@@ -28,6 +22,27 @@ function formatPracticalText(practical) {
28
22
  return output;
29
23
  }
30
24
 
25
+ function copyToClipboard(text) {
26
+ const platform = process.platform;
27
+ try {
28
+ let proc;
29
+ if (platform === 'darwin') {
30
+ proc = spawn('pbcopy');
31
+ } else if (platform === 'win32') {
32
+ proc = spawn('clip');
33
+ } else {
34
+ proc = spawn('xclip', ['-selection', 'clipboard']);
35
+ }
36
+
37
+ if (proc && proc.stdin) {
38
+ proc.stdin.write(text);
39
+ proc.stdin.end();
40
+ }
41
+ } catch (err) {
42
+ // Ignore clipboard errors if running in non-desktop/CI env
43
+ }
44
+ }
45
+
31
46
  function openFile(filePath) {
32
47
  const platform = process.platform;
33
48
  let cmd = '';
@@ -53,6 +68,8 @@ function generatePracticalFile(idOrKey, targetDir = process.cwd()) {
53
68
  const content = formatPracticalText(practical);
54
69
  const outPath = path.join(targetDir, practical.fileName);
55
70
  fs.writeFileSync(outPath, content, 'utf8');
71
+
72
+ copyToClipboard(content);
56
73
  openFile(outPath);
57
74
 
58
75
  return {
@@ -68,15 +85,25 @@ function generateAllFiles(targetDir = process.cwd()) {
68
85
  let combinedText = '';
69
86
 
70
87
  for (const key of Object.keys(practicalsData)) {
71
- const res = generatePracticalFile(key, targetDir);
72
- if (res) {
73
- generated.push(res);
74
- combinedText += res.content + `\n\n\n\n\n\n`;
75
- }
88
+ const practical = practicalsData[key];
89
+ const content = formatPracticalText(practical);
90
+ const outPath = path.join(targetDir, practical.fileName);
91
+ fs.writeFileSync(outPath, content, 'utf8');
92
+
93
+ generated.push({
94
+ fileName: practical.fileName,
95
+ outPath,
96
+ content,
97
+ title: practical.title
98
+ });
99
+
100
+ combinedText += content + `\n\n\n\n\n\n`;
76
101
  }
77
102
 
78
103
  const combinedPath = path.join(targetDir, 'all-practicals.txt');
79
104
  fs.writeFileSync(combinedPath, combinedText, 'utf8');
105
+
106
+ copyToClipboard(combinedText);
80
107
  openFile(combinedPath);
81
108
 
82
109
  generated.push({
@@ -91,6 +118,7 @@ function generateAllFiles(targetDir = process.cwd()) {
91
118
  module.exports = {
92
119
  practicalsData,
93
120
  formatPracticalText,
121
+ copyToClipboard,
94
122
  generatePracticalFile,
95
123
  generateAllFiles,
96
124
  openFile
@@ -2,22 +2,21 @@ const practicalsData = {
2
2
  '1': {
3
3
  id: '1',
4
4
  fileName: 'practical-1.txt',
5
- title: 'Practical 1: Vue Directives (v-if/else, v-show, v-for, v-on, v-model)',
5
+ title: 'Practical 1',
6
6
  setupSteps: `1. Run:
7
7
  npm create vue@latest my-vue-p1
8
8
 
9
- 2. Terminal Prompts:
10
- Select No to all options (TypeScript, Router, Pinia, Vitest, ESLint, Prettier).
9
+ 2. Prompts:
10
+ Select No to all options.
11
11
 
12
12
  3. cd my-vue-p1
13
13
  npm install
14
14
 
15
15
  4. npm run dev
16
- (App runs on http://localhost:5173)
17
16
 
18
- 5. Files to create/update:
17
+ 5. Files:
19
18
  - Create src/users.json
20
- - Replace src/App.vue with the code below.`,
19
+ - Replace src/App.vue with code below.`,
21
20
  components: [
22
21
  {
23
22
  name: 'users.json',
@@ -59,7 +58,7 @@ function handleLogout() {
59
58
 
60
59
  <template>
61
60
  <div style="font-family: sans-serif; max-width: 400px; margin: 30px auto; padding: 20px; border: 1px solid #ccc; border-radius: 8px;">
62
- <!-- 1. v-if / v-else: Toggle between Login and Dashboard -->
61
+ <!-- 1. v-if / v-else: Toggle between Login Screen and Dashboard -->
63
62
  <div v-if="!currentUser">
64
63
  <h2>System Login</h2>
65
64
  <!-- 2. v-model: Two-way input binding -->
@@ -97,11 +96,11 @@ function handleLogout() {
97
96
  '2': {
98
97
  id: '2',
99
98
  fileName: 'practical-2.txt',
100
- title: 'Practical 2: Data Binding (Props and Emits)',
99
+ title: 'Practical 2',
101
100
  setupSteps: `1. Run:
102
101
  npm create vue@latest my-vue-p2
103
102
 
104
- 2. Terminal Prompts:
103
+ 2. Prompts:
105
104
  Select No to all options.
106
105
 
107
106
  3. cd my-vue-p2
@@ -109,9 +108,9 @@ function handleLogout() {
109
108
 
110
109
  4. npm run dev
111
110
 
112
- 5. Files to create/update:
113
- - Create src/DriverCard.vue (Child component)
114
- - Replace src/App.vue with the code below (Parent component).`,
111
+ 5. Files:
112
+ - Create src/DriverCard.vue
113
+ - Replace src/App.vue with code below.`,
115
114
  components: [
116
115
  {
117
116
  name: 'DriverCard.vue',
@@ -200,26 +199,26 @@ function addDriver() {
200
199
  '3': {
201
200
  id: '3',
202
201
  fileName: 'practical-3.txt',
203
- title: 'Practical 3: Document Upload & Preview System (Vue 3 + Express + Multer)',
204
- setupSteps: `Backend Setup:
202
+ title: 'Practical 3',
203
+ setupSteps: `Backend:
205
204
  1. mkdir backend && cd backend
206
205
  2. npm init -y
207
206
  3. npm install express multer cors
208
- 4. Create server.js and paste the server.js code below.
207
+ 4. Create server.js and paste code below.
209
208
  5. node server.js
210
209
  (Runs on http://localhost:5000)
211
210
 
212
- Frontend Setup:
213
- 1. In a new terminal:
211
+ Frontend:
212
+ 1. In another terminal:
214
213
  npm create vue@latest frontend
215
214
  (Select No to all options)
216
215
  2. cd frontend && npm install
217
216
  3. npm run dev
218
217
  (Runs on http://localhost:5173)
219
- 4. Replace frontend/src/App.vue with the App.vue code below.`,
218
+ 4. Replace frontend/src/App.vue with code below.`,
220
219
  components: [
221
220
  {
222
- name: 'server.js (Backend)',
221
+ name: 'server.js',
223
222
  path: 'backend/server.js',
224
223
  code: `const express = require('express');
225
224
  const multer = require('multer');
@@ -283,7 +282,7 @@ app.delete('/api/documents/:id', (req, res) => {
283
282
  app.listen(5000, () => console.log('Backend running on http://localhost:5000'));`
284
283
  },
285
284
  {
286
- name: 'App.vue (Frontend)',
285
+ name: 'App.vue',
287
286
  path: 'frontend/src/App.vue',
288
287
  code: `<script setup>
289
288
  import { ref, onMounted } from 'vue'
@@ -359,23 +358,24 @@ onMounted(fetchDocuments)
359
358
  '4': {
360
359
  id: '4',
361
360
  fileName: 'practical-4.txt',
362
- title: 'Practical 4: Localized State Management (Pinia Multi-Step Form)',
363
- setupSteps: `Frontend Setup:
361
+ title: 'Practical 4',
362
+ setupSteps: `Frontend:
364
363
  1. npm create vue@latest frontend
365
364
  (Select YES to Pinia, No to everything else)
366
365
  2. cd frontend && npm install
367
366
  3. npm run dev
368
- 4. Create src/store.js and replace src/App.vue with the code below.
367
+ 4. Create src/store.js
368
+ Replace src/App.vue with code below.
369
369
 
370
- Backend Setup (MongoDB):
370
+ Backend:
371
371
  1. mkdir backend && cd backend
372
372
  2. npm init -y
373
373
  3. npm install express mongoose cors
374
- 4. Create server.js and paste the server.js code below.
374
+ 4. Create server.js and paste code below.
375
375
  5. node server.js`,
376
376
  components: [
377
377
  {
378
- name: 'store.js (Pinia Store)',
378
+ name: 'store.js',
379
379
  path: 'frontend/src/store.js',
380
380
  code: `import { defineStore } from 'pinia'
381
381
 
@@ -418,7 +418,7 @@ export const useApplicationStore = defineStore('application', {
418
418
  })`
419
419
  },
420
420
  {
421
- name: 'App.vue (Frontend)',
421
+ name: 'App.vue',
422
422
  path: 'frontend/src/App.vue',
423
423
  code: `<script setup>
424
424
  import { useApplicationStore } from './store.js'
@@ -476,7 +476,7 @@ const store = useApplicationStore()
476
476
  </template>`
477
477
  },
478
478
  {
479
- name: 'server.js (Backend)',
479
+ name: 'server.js',
480
480
  path: 'backend/server.js',
481
481
  code: `const express = require('express');
482
482
  const mongoose = require('mongoose');
@@ -520,7 +520,7 @@ mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/job_app_db'
520
520
  '5': {
521
521
  id: '5',
522
522
  fileName: 'practical-5.txt',
523
- title: 'Practical 5: Routing in Nuxt and Shared Layouts',
523
+ title: 'Practical 5',
524
524
  setupSteps: `1. Run:
525
525
  npx nuxi@latest init nuxt-lab
526
526
 
@@ -533,7 +533,7 @@ mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/job_app_db'
533
533
  3. cd nuxt-lab && npm run dev
534
534
  (Runs on http://localhost:3000)
535
535
 
536
- 4. Create the following files inside app/ (or root):
536
+ 4. Create files inside app/ (or root):
537
537
  - app/app.vue
538
538
  - app/layouts/default.vue
539
539
  - app/layouts/minimal.vue
@@ -553,7 +553,7 @@ mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/job_app_db'
553
553
  </template>`
554
554
  },
555
555
  {
556
- name: 'default.vue (Shared Layout)',
556
+ name: 'default.vue',
557
557
  path: 'app/layouts/default.vue',
558
558
  code: `<!-- app/layouts/default.vue: Shared Layout with persistent header & footer -->
559
559
  <template>
@@ -578,7 +578,7 @@ mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/job_app_db'
578
578
  </template>`
579
579
  },
580
580
  {
581
- name: 'minimal.vue (Minimal Layout)',
581
+ name: 'minimal.vue',
582
582
  path: 'app/layouts/minimal.vue',
583
583
  code: `<!-- app/layouts/minimal.vue: Custom headerless layout -->
584
584
  <template>
@@ -591,7 +591,7 @@ mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/job_app_db'
591
591
  </template>`
592
592
  },
593
593
  {
594
- name: 'index.vue (Home Page)',
594
+ name: 'index.vue',
595
595
  path: 'app/pages/index.vue',
596
596
  code: `<!-- app/pages/index.vue: Root landing page (Route: /) -->
597
597
  <template>
@@ -603,7 +603,7 @@ mongoose.connect(process.env.MONGO_URI || 'mongodb://localhost:27017/job_app_db'
603
603
  </template>`
604
604
  },
605
605
  {
606
- name: 'about.vue (About Page)',
606
+ name: 'about.vue',
607
607
  path: 'app/pages/about.vue',
608
608
  code: `<!-- app/pages/about.vue: Route: /about (uses minimal layout) -->
609
609
  <script setup>
@@ -621,7 +621,7 @@ definePageMeta({
621
621
  </template>`
622
622
  },
623
623
  {
624
- name: 'items/index.vue (List Page)',
624
+ name: 'items/index.vue',
625
625
  path: 'app/pages/items/index.vue',
626
626
  code: `<!-- app/pages/items/index.vue: Route: /items -->
627
627
  <script setup>
@@ -647,7 +647,7 @@ const books = [
647
647
  </template>`
648
648
  },
649
649
  {
650
- name: 'items/[id].vue (Dynamic Detail Page)',
650
+ name: 'items/[id].vue',
651
651
  path: 'app/pages/items/[id].vue',
652
652
  code: `<!-- app/pages/items/[id].vue: Dynamic Wildcard Route: /items/:id -->
653
653
  <script setup>
@@ -688,11 +688,11 @@ const book = books.find(b => b.id === bookId)
688
688
  'crud': {
689
689
  id: 'crud',
690
690
  fileName: 'practical-crud.txt',
691
- title: 'Practical CRUD: Express + Mongoose REST API',
691
+ title: 'Practical CRUD',
692
692
  setupSteps: `1. mkdir crud-backend && cd crud-backend
693
693
  2. npm init -y
694
694
  3. npm install express mongoose
695
- 4. Create server.js and paste the server.js code below.
695
+ 4. Create server.js and paste code below.
696
696
  5. node server.js
697
697
  (Runs on http://localhost:5000)`,
698
698
  components: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fsdcats",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Absolute minimal exam code and setup steps generator for Vue 3, Pinia, Nuxt, and Mongoose CRUD",
5
5
  "main": "index.js",
6
6
  "bin": {
package/practical-1.txt CHANGED
@@ -1,25 +1,19 @@
1
- PRACTICAL 1: VUE DIRECTIVES (V-IF/ELSE, V-SHOW, V-FOR, V-ON, V-MODEL)
2
-
3
-
4
-
5
-
6
1
  SETUP:
7
2
 
8
3
  1. Run:
9
4
  npm create vue@latest my-vue-p1
10
5
 
11
- 2. Terminal Prompts:
12
- Select No to all options (TypeScript, Router, Pinia, Vitest, ESLint, Prettier).
6
+ 2. Prompts:
7
+ Select No to all options.
13
8
 
14
9
  3. cd my-vue-p1
15
10
  npm install
16
11
 
17
12
  4. npm run dev
18
- (App runs on http://localhost:5173)
19
13
 
20
- 5. Files to create/update:
14
+ 5. Files:
21
15
  - Create src/users.json
22
- - Replace src/App.vue with the code below.
16
+ - Replace src/App.vue with code below.
23
17
 
24
18
 
25
19
 
@@ -72,7 +66,7 @@ function handleLogout() {
72
66
 
73
67
  <template>
74
68
  <div style="font-family: sans-serif; max-width: 400px; margin: 30px auto; padding: 20px; border: 1px solid #ccc; border-radius: 8px;">
75
- <!-- 1. v-if / v-else: Toggle between Login and Dashboard -->
69
+ <!-- 1. v-if / v-else: Toggle between Login Screen and Dashboard -->
76
70
  <div v-if="!currentUser">
77
71
  <h2>System Login</h2>
78
72
  <!-- 2. v-model: Two-way input binding -->
package/practical-2.txt CHANGED
@@ -1,14 +1,9 @@
1
- PRACTICAL 2: DATA BINDING (PROPS AND EMITS)
2
-
3
-
4
-
5
-
6
1
  SETUP:
7
2
 
8
3
  1. Run:
9
4
  npm create vue@latest my-vue-p2
10
5
 
11
- 2. Terminal Prompts:
6
+ 2. Prompts:
12
7
  Select No to all options.
13
8
 
14
9
  3. cd my-vue-p2
@@ -16,9 +11,9 @@ SETUP:
16
11
 
17
12
  4. npm run dev
18
13
 
19
- 5. Files to create/update:
20
- - Create src/DriverCard.vue (Child component)
21
- - Replace src/App.vue with the code below (Parent component).
14
+ 5. Files:
15
+ - Create src/DriverCard.vue
16
+ - Replace src/App.vue with code below.
22
17
 
23
18
 
24
19
 
package/practical-3.txt CHANGED
@@ -1,26 +1,21 @@
1
- PRACTICAL 3: DOCUMENT UPLOAD & PREVIEW SYSTEM (VUE 3 + EXPRESS + MULTER)
2
-
3
-
4
-
5
-
6
1
  SETUP:
7
2
 
8
- Backend Setup:
3
+ Backend:
9
4
  1. mkdir backend && cd backend
10
5
  2. npm init -y
11
6
  3. npm install express multer cors
12
- 4. Create server.js and paste the server.js code below.
7
+ 4. Create server.js and paste code below.
13
8
  5. node server.js
14
9
  (Runs on http://localhost:5000)
15
10
 
16
- Frontend Setup:
17
- 1. In a new terminal:
11
+ Frontend:
12
+ 1. In another terminal:
18
13
  npm create vue@latest frontend
19
14
  (Select No to all options)
20
15
  2. cd frontend && npm install
21
16
  3. npm run dev
22
17
  (Runs on http://localhost:5173)
23
- 4. Replace frontend/src/App.vue with the App.vue code below.
18
+ 4. Replace frontend/src/App.vue with code below.
24
19
 
25
20
 
26
21
 
@@ -29,7 +24,7 @@ Frontend Setup:
29
24
  COMPONENTS:
30
25
 
31
26
 
32
- COMPONENT: server.js (Backend)
27
+ COMPONENT: server.js
33
28
  PATH: backend/server.js
34
29
 
35
30
  const express = require('express');
@@ -97,7 +92,7 @@ app.listen(5000, () => console.log('Backend running on http://localhost:5000'));
97
92
 
98
93
 
99
94
 
100
- COMPONENT: App.vue (Frontend)
95
+ COMPONENT: App.vue
101
96
  PATH: frontend/src/App.vue
102
97
 
103
98
  <script setup>
package/practical-4.txt CHANGED
@@ -1,22 +1,18 @@
1
- PRACTICAL 4: LOCALIZED STATE MANAGEMENT (PINIA MULTI-STEP FORM)
2
-
3
-
4
-
5
-
6
1
  SETUP:
7
2
 
8
- Frontend Setup:
3
+ Frontend:
9
4
  1. npm create vue@latest frontend
10
5
  (Select YES to Pinia, No to everything else)
11
6
  2. cd frontend && npm install
12
7
  3. npm run dev
13
- 4. Create src/store.js and replace src/App.vue with the code below.
8
+ 4. Create src/store.js
9
+ Replace src/App.vue with code below.
14
10
 
15
- Backend Setup (MongoDB):
11
+ Backend:
16
12
  1. mkdir backend && cd backend
17
13
  2. npm init -y
18
14
  3. npm install express mongoose cors
19
- 4. Create server.js and paste the server.js code below.
15
+ 4. Create server.js and paste code below.
20
16
  5. node server.js
21
17
 
22
18
 
@@ -26,7 +22,7 @@ Backend Setup (MongoDB):
26
22
  COMPONENTS:
27
23
 
28
24
 
29
- COMPONENT: store.js (Pinia Store)
25
+ COMPONENT: store.js
30
26
  PATH: frontend/src/store.js
31
27
 
32
28
  import { defineStore } from 'pinia'
@@ -73,7 +69,7 @@ export const useApplicationStore = defineStore('application', {
73
69
 
74
70
 
75
71
 
76
- COMPONENT: App.vue (Frontend)
72
+ COMPONENT: App.vue
77
73
  PATH: frontend/src/App.vue
78
74
 
79
75
  <script setup>
@@ -135,7 +131,7 @@ const store = useApplicationStore()
135
131
 
136
132
 
137
133
 
138
- COMPONENT: server.js (Backend)
134
+ COMPONENT: server.js
139
135
  PATH: backend/server.js
140
136
 
141
137
  const express = require('express');
package/practical-5.txt CHANGED
@@ -1,8 +1,3 @@
1
- PRACTICAL 5: ROUTING IN NUXT AND SHARED LAYOUTS
2
-
3
-
4
-
5
-
6
1
  SETUP:
7
2
 
8
3
  1. Run:
@@ -17,7 +12,7 @@ SETUP:
17
12
  3. cd nuxt-lab && npm run dev
18
13
  (Runs on http://localhost:3000)
19
14
 
20
- 4. Create the following files inside app/ (or root):
15
+ 4. Create files inside app/ (or root):
21
16
  - app/app.vue
22
17
  - app/layouts/default.vue
23
18
  - app/layouts/minimal.vue
@@ -47,7 +42,7 @@ PATH: app/app.vue
47
42
 
48
43
 
49
44
 
50
- COMPONENT: default.vue (Shared Layout)
45
+ COMPONENT: default.vue
51
46
  PATH: app/layouts/default.vue
52
47
 
53
48
  <!-- app/layouts/default.vue: Shared Layout with persistent header & footer -->
@@ -76,7 +71,7 @@ PATH: app/layouts/default.vue
76
71
 
77
72
 
78
73
 
79
- COMPONENT: minimal.vue (Minimal Layout)
74
+ COMPONENT: minimal.vue
80
75
  PATH: app/layouts/minimal.vue
81
76
 
82
77
  <!-- app/layouts/minimal.vue: Custom headerless layout -->
@@ -93,7 +88,7 @@ PATH: app/layouts/minimal.vue
93
88
 
94
89
 
95
90
 
96
- COMPONENT: index.vue (Home Page)
91
+ COMPONENT: index.vue
97
92
  PATH: app/pages/index.vue
98
93
 
99
94
  <!-- app/pages/index.vue: Root landing page (Route: /) -->
@@ -109,7 +104,7 @@ PATH: app/pages/index.vue
109
104
 
110
105
 
111
106
 
112
- COMPONENT: about.vue (About Page)
107
+ COMPONENT: about.vue
113
108
  PATH: app/pages/about.vue
114
109
 
115
110
  <!-- app/pages/about.vue: Route: /about (uses minimal layout) -->
@@ -131,7 +126,7 @@ definePageMeta({
131
126
 
132
127
 
133
128
 
134
- COMPONENT: items/index.vue (List Page)
129
+ COMPONENT: items/index.vue
135
130
  PATH: app/pages/items/index.vue
136
131
 
137
132
  <!-- app/pages/items/index.vue: Route: /items -->
@@ -161,7 +156,7 @@ const books = [
161
156
 
162
157
 
163
158
 
164
- COMPONENT: items/[id].vue (Dynamic Detail Page)
159
+ COMPONENT: items/[id].vue
165
160
  PATH: app/pages/items/[id].vue
166
161
 
167
162
  <!-- app/pages/items/[id].vue: Dynamic Wildcard Route: /items/:id -->
@@ -1,14 +1,9 @@
1
- PRACTICAL CRUD: EXPRESS + MONGOOSE REST API
2
-
3
-
4
-
5
-
6
1
  SETUP:
7
2
 
8
3
  1. mkdir crud-backend && cd crud-backend
9
4
  2. npm init -y
10
5
  3. npm install express mongoose
11
- 4. Create server.js and paste the server.js code below.
6
+ 4. Create server.js and paste code below.
12
7
  5. node server.js
13
8
  (Runs on http://localhost:5000)
14
9