@vue-skuilder/cli 0.1.23 → 0.1.25

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.
@@ -26,8 +26,8 @@ async function main() {
26
26
  options: {
27
27
  COUCHDB_SERVER_URL: process.env.COUCHDB_SERVER_URL || `localhost:${port}`,
28
28
  COUCHDB_SERVER_PROTOCOL: process.env.COUCHDB_SERVER_PROTOCOL || 'http',
29
- COUCHDB_USERNAME: 'admin',
30
- COUCHDB_PASSWORD: 'password',
29
+ COUCHDB_USERNAME: process.env.COUCHDB_USERNAME || 'admin',
30
+ COUCHDB_PASSWORD: process.env.COUCHDB_PASSWORD || 'password',
31
31
  COURSE_IDS: [courseId], // Limit to specific course
32
32
  localStoragePrefix: 'mcp-server',
33
33
  },
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.1.23",
6
+ "version": "0.1.25",
7
7
  "type": "module",
8
8
  "main": "./dist-lib/questions.cjs.js",
9
9
  "module": "./dist-lib/questions.mjs",
@@ -58,5 +58,5 @@
58
58
  "vue-tsc": "^1.8.0",
59
59
  "wait-on": "8.0.2"
60
60
  },
61
- "stableVersion": "0.1.23"
61
+ "stableVersion": "0.1.25"
62
62
  }
@@ -5,8 +5,22 @@
5
5
  Register Question Types
6
6
  </v-card-title>
7
7
 
8
+ <!-- Access Denied -->
9
+ <v-alert v-if="!isAuthorized" type="error" variant="tonal" class="ma-4">
10
+ <v-alert-title>Access Denied</v-alert-title>
11
+ <p class="mb-2">
12
+ This admin page requires authentication with an authorized account.
13
+ </p>
14
+ <p v-if="!authStore.isLoggedIn" class="mb-2">
15
+ Please <a href="#" @click.prevent="authStore.setLoginDialog(true)">log in</a> to continue.
16
+ </p>
17
+ <p v-else class="mb-2">
18
+ Your account ({{ currentUsername }}) does not have admin privileges.
19
+ </p>
20
+ </v-alert>
21
+
8
22
  <!-- Static Mode Warning -->
9
- <v-alert v-if="isStaticMode" type="warning" variant="tonal" class="ma-4">
23
+ <v-alert v-else-if="isStaticMode" type="warning" variant="tonal" class="ma-4">
10
24
  <v-alert-title>Static Mode Detected</v-alert-title>
11
25
  <p class="mb-2">
12
26
  Question type registration is not available in static mode.
@@ -21,7 +35,7 @@
21
35
  </v-alert>
22
36
 
23
37
  <!-- Loading State -->
24
- <v-card-text v-else-if="loading">
38
+ <v-card-text v-else-if="isAuthorized && loading">
25
39
  <v-progress-circular indeterminate color="primary" />
26
40
  <span class="ml-4">Loading question type data...</span>
27
41
  </v-card-text>
@@ -37,47 +51,138 @@
37
51
  <!-- Current State -->
38
52
  <div class="mb-6">
39
53
  <h3 class="text-h6 mb-2">Current CourseConfig</h3>
40
- <v-list density="compact">
41
- <v-list-item>
42
- <template #prepend>
43
- <v-icon>mdi-shape</v-icon>
44
- </template>
45
- <v-list-item-title>
54
+ <v-expansion-panels variant="accordion">
55
+ <v-expansion-panel>
56
+ <v-expansion-panel-title>
57
+ <v-icon class="mr-2">mdi-shape</v-icon>
46
58
  {{ currentDataShapeCount }} DataShapes registered
47
- </v-list-item-title>
48
- </v-list-item>
49
- <v-list-item>
50
- <template #prepend>
51
- <v-icon>mdi-help-circle</v-icon>
52
- </template>
53
- <v-list-item-title>
59
+ </v-expansion-panel-title>
60
+ <v-expansion-panel-text>
61
+ <v-list v-if="courseConfig?.dataShapes?.length" density="compact">
62
+ <v-list-item
63
+ v-for="ds in courseConfig.dataShapes"
64
+ :key="ds.name"
65
+ >
66
+ <template #default>
67
+ <v-list-item-title class="font-weight-medium">
68
+ {{ ds.name }}
69
+ </v-list-item-title>
70
+ <v-list-item-subtitle>
71
+ {{ ds.questionTypes?.length || 0 }} question types |
72
+ Schema: {{ ds.serializedZodSchema ? 'Yes' : 'No' }}
73
+ </v-list-item-subtitle>
74
+ </template>
75
+ <template #append>
76
+ <v-btn
77
+ icon="mdi-delete"
78
+ size="small"
79
+ variant="text"
80
+ color="error"
81
+ :loading="removing"
82
+ @click="confirmRemoveDataShape(ds.name)"
83
+ />
84
+ </template>
85
+ </v-list-item>
86
+ </v-list>
87
+ <div v-else class="text-medium-emphasis pa-2">
88
+ No DataShapes registered
89
+ </div>
90
+ </v-expansion-panel-text>
91
+ </v-expansion-panel>
92
+ <v-expansion-panel>
93
+ <v-expansion-panel-title>
94
+ <v-icon class="mr-2">mdi-help-circle</v-icon>
54
95
  {{ currentQuestionTypeCount }} QuestionTypes registered
55
- </v-list-item-title>
56
- </v-list-item>
57
- </v-list>
96
+ </v-expansion-panel-title>
97
+ <v-expansion-panel-text>
98
+ <v-list v-if="courseConfig?.questionTypes?.length" density="compact">
99
+ <v-list-item
100
+ v-for="qt in courseConfig.questionTypes"
101
+ :key="qt.name"
102
+ >
103
+ <template #default>
104
+ <v-list-item-title class="font-weight-medium">
105
+ {{ qt.name }}
106
+ </v-list-item-title>
107
+ <v-list-item-subtitle>
108
+ Views: {{ qt.viewList?.join(', ') || 'none' }} |
109
+ DataShapes: {{ qt.dataShapeList?.join(', ') || 'none' }}
110
+ </v-list-item-subtitle>
111
+ </template>
112
+ <template #append>
113
+ <v-btn
114
+ icon="mdi-delete"
115
+ size="small"
116
+ variant="text"
117
+ color="error"
118
+ :loading="removing"
119
+ @click="confirmRemoveQuestionType(qt.name)"
120
+ />
121
+ </template>
122
+ </v-list-item>
123
+ </v-list>
124
+ <div v-else class="text-medium-emphasis pa-2">
125
+ No QuestionTypes registered
126
+ </div>
127
+ </v-expansion-panel-text>
128
+ </v-expansion-panel>
129
+ </v-expansion-panels>
58
130
  </div>
59
131
 
60
132
  <!-- Custom Questions -->
61
133
  <div class="mb-6">
62
134
  <h3 class="text-h6 mb-2">From allCustomQuestions()</h3>
63
- <v-list density="compact">
64
- <v-list-item>
65
- <template #prepend>
66
- <v-icon>mdi-shape</v-icon>
67
- </template>
68
- <v-list-item-title>
135
+ <v-expansion-panels variant="accordion">
136
+ <v-expansion-panel>
137
+ <v-expansion-panel-title>
138
+ <v-icon class="mr-2">mdi-shape</v-icon>
69
139
  {{ processedDataShapes.length }} DataShapes found
70
- </v-list-item-title>
71
- </v-list-item>
72
- <v-list-item>
73
- <template #prepend>
74
- <v-icon>mdi-help-circle</v-icon>
75
- </template>
76
- <v-list-item-title>
140
+ </v-expansion-panel-title>
141
+ <v-expansion-panel-text>
142
+ <v-list v-if="processedDataShapes.length" density="compact">
143
+ <v-list-item
144
+ v-for="ds in processedDataShapes"
145
+ :key="`${ds.course}.${ds.name}`"
146
+ >
147
+ <v-list-item-title class="font-weight-medium">
148
+ {{ ds.course }}.{{ ds.name }}
149
+ </v-list-item-title>
150
+ <v-list-item-subtitle>
151
+ Fields: {{ ds.dataShape?.fields?.map(f => f.name).join(', ') || 'none' }}
152
+ </v-list-item-subtitle>
153
+ </v-list-item>
154
+ </v-list>
155
+ <div v-else class="text-medium-emphasis pa-2">
156
+ No DataShapes found in allCustomQuestions()
157
+ </div>
158
+ </v-expansion-panel-text>
159
+ </v-expansion-panel>
160
+ <v-expansion-panel>
161
+ <v-expansion-panel-title>
162
+ <v-icon class="mr-2">mdi-help-circle</v-icon>
77
163
  {{ processedQuestions.length }} QuestionTypes found
78
- </v-list-item-title>
79
- </v-list-item>
80
- </v-list>
164
+ </v-expansion-panel-title>
165
+ <v-expansion-panel-text>
166
+ <v-list v-if="processedQuestions.length" density="compact">
167
+ <v-list-item
168
+ v-for="q in processedQuestions"
169
+ :key="`${q.course}.${q.name}`"
170
+ >
171
+ <v-list-item-title class="font-weight-medium">
172
+ {{ q.course }}.{{ q.name }}
173
+ </v-list-item-title>
174
+ <v-list-item-subtitle>
175
+ DataShapes: {{ q.dataShapes?.map(ds => ds.name).join(', ') || 'none' }} |
176
+ Views: {{ q.views?.length || 0 }}
177
+ </v-list-item-subtitle>
178
+ </v-list-item>
179
+ </v-list>
180
+ <div v-else class="text-medium-emphasis pa-2">
181
+ No QuestionTypes found in allCustomQuestions()
182
+ </div>
183
+ </v-expansion-panel-text>
184
+ </v-expansion-panel>
185
+ </v-expansion-panels>
81
186
  </div>
82
187
 
83
188
  <!-- Changes Preview -->
@@ -114,7 +219,7 @@
114
219
  </v-card-text>
115
220
 
116
221
  <!-- Actions -->
117
- <v-card-actions v-if="!isStaticMode && !loading && !error">
222
+ <v-card-actions v-if="isAuthorized && !isStaticMode && !loading && !error">
118
223
  <v-spacer />
119
224
  <v-btn
120
225
  color="primary"
@@ -134,6 +239,7 @@ import { ref, computed, onMounted } from 'vue';
134
239
  import { getDataLayer } from '@vue-skuilder/db';
135
240
  import {
136
241
  registerCustomQuestionTypes,
242
+ removeCustomQuestionTypes,
137
243
  processCustomQuestionsData,
138
244
  isDataShapeRegistered,
139
245
  isQuestionTypeRegistered,
@@ -142,14 +248,29 @@ import {
142
248
  type ProcessedDataShape,
143
249
  type ProcessedQuestionData,
144
250
  } from '@vue-skuilder/db';
145
- import { useAuthStore } from '@vue-skuilder/common-ui';
251
+ import { useAuthStore, getCurrentUser } from '@vue-skuilder/common-ui';
146
252
  import { allCustomQuestions } from '../questions';
147
253
  import config from '../../skuilder.config.json';
148
254
 
255
+ // Admin usernames that can access this page
256
+ const ADMIN_USERNAMES = ['admin'];
257
+
258
+ // Auth state
259
+ const authStore = useAuthStore();
260
+ const currentUsername = ref<string | null>(null);
261
+
262
+ // Check if user is authorized (logged in + admin username)
263
+ const isAuthorized = computed(() => {
264
+ if (!authStore.isLoggedIn) return false;
265
+ if (!currentUsername.value) return false;
266
+ return ADMIN_USERNAMES.includes(currentUsername.value);
267
+ });
268
+
149
269
  // State
150
270
  const loading = ref(true);
151
271
  const error = ref<string | null>(null);
152
272
  const registering = ref(false);
273
+ const removing = ref(false);
153
274
  const successMessage = ref<string | null>(null);
154
275
 
155
276
  const courseConfig = ref<any>(null);
@@ -284,10 +405,77 @@ async function registerQuestions() {
284
405
  }
285
406
  }
286
407
 
408
+ async function confirmRemoveDataShape(name: string) {
409
+ if (!confirm(`Remove DataShape "${name}"? This cannot be undone.`)) {
410
+ return;
411
+ }
412
+ await removeItems([name], []);
413
+ }
414
+
415
+ async function confirmRemoveQuestionType(name: string) {
416
+ if (!confirm(`Remove QuestionType "${name}"? This cannot be undone.`)) {
417
+ return;
418
+ }
419
+ await removeItems([], [name]);
420
+ }
421
+
422
+ async function removeItems(dataShapeNames: string[], questionTypeNames: string[]) {
423
+ if (!courseConfig.value) {
424
+ error.value = 'Missing course config for removal';
425
+ return;
426
+ }
427
+
428
+ try {
429
+ removing.value = true;
430
+ error.value = null;
431
+ successMessage.value = null;
432
+
433
+ const courseId = config.course;
434
+ if (!courseId) {
435
+ throw new Error('No course ID configured');
436
+ }
437
+
438
+ const courseDB = getDataLayer().getCourseDB(courseId);
439
+
440
+ const result = await removeCustomQuestionTypes(
441
+ dataShapeNames,
442
+ questionTypeNames,
443
+ courseConfig.value,
444
+ courseDB
445
+ );
446
+
447
+ if (result.success) {
448
+ successMessage.value = `Successfully removed ${result.removedCount} items`;
449
+ // Reload data to show updated state
450
+ await loadData();
451
+ } else {
452
+ error.value = result.errorMessage || 'Removal failed';
453
+ }
454
+ } catch (err) {
455
+ error.value = err instanceof Error ? err.message : String(err);
456
+ console.error('[AdminRegisterQuestions] Removal failed:', err);
457
+ } finally {
458
+ removing.value = false;
459
+ }
460
+ }
461
+
287
462
  // Lifecycle
288
- onMounted(() => {
289
- if (!isStaticMode.value) {
463
+ onMounted(async () => {
464
+ // Check authorization first
465
+ try {
466
+ const user = await getCurrentUser();
467
+ if (user) {
468
+ currentUsername.value = user.getUsername();
469
+ }
470
+ } catch (err) {
471
+ console.error('[AdminRegisterQuestions] Failed to get current user:', err);
472
+ }
473
+
474
+ // Only load data if authorized and not in static mode
475
+ if (isAuthorized.value && !isStaticMode.value) {
290
476
  loadData();
477
+ } else {
478
+ loading.value = false;
291
479
  }
292
480
  });
293
481
  </script>
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.1.23",
6
+ "version": "0.1.25",
7
7
  "type": "module",
8
8
  "scripts": {
9
9
  "dev": "vite",
@@ -32,5 +32,5 @@
32
32
  "vite": "^7.0.0",
33
33
  "vue-tsc": "^1.8.0"
34
34
  },
35
- "stableVersion": "0.1.23"
35
+ "stableVersion": "0.1.25"
36
36
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.1.23",
6
+ "version": "0.1.25",
7
7
  "type": "module",
8
8
  "description": "CLI scaffolding tool for vue-skuilder projects",
9
9
  "bin": {
@@ -45,13 +45,13 @@
45
45
  ],
46
46
  "dependencies": {
47
47
  "@mdi/font": "^7.3.67",
48
- "@vue-skuilder/common": "0.1.23",
49
- "@vue-skuilder/common-ui": "0.1.23",
50
- "@vue-skuilder/courseware": "0.1.23",
51
- "@vue-skuilder/db": "0.1.23",
52
- "@vue-skuilder/edit-ui": "0.1.23",
53
- "@vue-skuilder/express": "0.1.23",
54
- "@vue-skuilder/mcp": "0.1.23",
48
+ "@vue-skuilder/common": "0.1.25",
49
+ "@vue-skuilder/common-ui": "0.1.25",
50
+ "@vue-skuilder/courseware": "0.1.25",
51
+ "@vue-skuilder/db": "0.1.25",
52
+ "@vue-skuilder/edit-ui": "0.1.25",
53
+ "@vue-skuilder/express": "0.1.25",
54
+ "@vue-skuilder/mcp": "0.1.25",
55
55
  "chalk": "^5.3.0",
56
56
  "commander": "^11.0.0",
57
57
  "fs-extra": "^11.2.0",
@@ -70,7 +70,7 @@
70
70
  "@types/node": "^22",
71
71
  "@types/serve-static": "^1.15.0",
72
72
  "@vitejs/plugin-vue": "^6.0.0",
73
- "@vue-skuilder/studio-ui": "0.1.23",
73
+ "@vue-skuilder/studio-ui": "0.1.25",
74
74
  "cypress": "^15.6.0",
75
75
  "typescript": "~5.9.3",
76
76
  "vite": "^7.0.0",
@@ -81,5 +81,5 @@
81
81
  "node": ">=18.0.0"
82
82
  },
83
83
  "packageManager": "yarn@4.12.0",
84
- "stableVersion": "0.1.23"
84
+ "stableVersion": "0.1.25"
85
85
  }
package/src/mcp-server.ts CHANGED
@@ -31,8 +31,8 @@ async function main() {
31
31
  options: {
32
32
  COUCHDB_SERVER_URL: process.env.COUCHDB_SERVER_URL || `localhost:${port}`,
33
33
  COUCHDB_SERVER_PROTOCOL: process.env.COUCHDB_SERVER_PROTOCOL || 'http',
34
- COUCHDB_USERNAME: 'admin',
35
- COUCHDB_PASSWORD: 'password',
34
+ COUCHDB_USERNAME: process.env.COUCHDB_USERNAME || 'admin',
35
+ COUCHDB_PASSWORD: process.env.COUCHDB_PASSWORD || 'password',
36
36
  COURSE_IDS: [courseId], // Limit to specific course
37
37
  localStoragePrefix: 'mcp-server',
38
38
  },
package/tsconfig.json CHANGED
@@ -13,6 +13,7 @@
13
13
  ],
14
14
  "exclude": [
15
15
  "node_modules",
16
- "dist"
16
+ "dist",
17
+ "testproject"
17
18
  ]
18
19
  }