skuilder 0.1.2 → 0.1.4
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 +162 -2
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +70 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/prompts.d.ts +5 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +185 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/template.d.ts +36 -0
- package/dist/utils/template.d.ts.map +1 -0
- package/dist/utils/template.js +369 -0
- package/dist/utils/template.js.map +1 -0
- package/eslint.config.mjs +21 -0
- package/package.json +41 -36
- package/src/cli.ts +42 -0
- package/src/commands/init.ts +83 -0
- package/src/types.ts +72 -0
- package/src/utils/prompts.ts +204 -0
- package/src/utils/template.ts +421 -0
- package/tsconfig.json +12 -21
- package/.npmignore +0 -56
- package/android/app/BUCK +0 -65
- package/android/app/build.gradle +0 -139
- package/android/app/proguard-rules.pro +0 -66
- package/android/app/src/main/AndroidManifest.xml +0 -32
- package/android/app/src/main/java/com/rxphelloworld/MainActivity.java +0 -15
- package/android/app/src/main/java/com/rxphelloworld/MainApplication.java +0 -40
- package/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/android/app/src/main/res/values/strings.xml +0 -3
- package/android/app/src/main/res/values/styles.xml +0 -8
- package/android/build.gradle +0 -24
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +0 -6
- package/android/gradle.properties +0 -20
- package/android/gradlew +0 -164
- package/android/gradlew.bat +0 -90
- package/android/keystores/BUCK +0 -8
- package/android/keystores/debug.keystore.properties +0 -4
- package/android/settings.gradle +0 -3
- package/img/fingerCounter/1.PNG +0 -0
- package/img/fingerCounter/10.PNG +0 -0
- package/img/fingerCounter/2.PNG +0 -0
- package/img/fingerCounter/3.PNG +0 -0
- package/img/fingerCounter/4.PNG +0 -0
- package/img/fingerCounter/5.PNG +0 -0
- package/img/fingerCounter/6.PNG +0 -0
- package/img/fingerCounter/7.PNG +0 -0
- package/img/fingerCounter/8.PNG +0 -0
- package/img/fingerCounter/9.PNG +0 -0
- package/index.android.js +0 -1
- package/index.html +0 -30
- package/index.ios.js +0 -1
- package/ios/RXPHelloWorld/AppDelegate.h +0 -16
- package/ios/RXPHelloWorld/AppDelegate.m +0 -37
- package/ios/RXPHelloWorld/Base.lproj/LaunchScreen.xib +0 -42
- package/ios/RXPHelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json +0 -38
- package/ios/RXPHelloWorld/Info.plist +0 -56
- package/ios/RXPHelloWorld/main.m +0 -18
- package/ios/RXPHelloWorld.xcodeproj/project.pbxproj +0 -1251
- package/ios/RXPHelloWorld.xcodeproj/xcshareddata/xcschemes/RXPHelloWorld-tvOS.xcscheme +0 -129
- package/ios/RXPHelloWorld.xcodeproj/xcshareddata/xcschemes/RXPHelloWorld.xcscheme +0 -129
- package/ios/RXPHelloWorldTests/Info.plist +0 -24
- package/ios/RXPHelloWorldTests/RXPHelloWorldTests.m +0 -70
- package/src/App.tsx +0 -206
- package/src/appUtilities/Grader.ts +0 -72
- package/src/appUtilities/Keybinder.ts +0 -28
- package/src/appUtilities/Recorder.ts +0 -73
- package/src/cloudantFiles/_users._design._auth.validate_doc_update.js +0 -136
- package/src/components/ProgressChart.tsx +0 -155
- package/src/components/fingerCounter/fingerCounter.tsx +0 -38
- package/src/components/fingerCounter/resources/hands.svg +0 -512
- package/src/components/numpad.tsx +0 -146
- package/src/components/sessionReport.tsx +0 -87
- package/src/index.tsx +0 -8
- package/src/styles/answerStyles.css +0 -22
- package/src/typings/react.d.ts +0 -964
- package/webpack.config.ts +0 -26
- package/yarn.lock +0 -6208
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { promises as fs, existsSync } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
/**
|
|
8
|
+
* Find the standalone-ui package in node_modules
|
|
9
|
+
*/
|
|
10
|
+
export async function findStandaloneUiPath() {
|
|
11
|
+
// Start from CLI package root and work upward
|
|
12
|
+
let currentDir = path.join(__dirname, '..', '..');
|
|
13
|
+
while (currentDir !== path.dirname(currentDir)) {
|
|
14
|
+
const nodeModulesPath = path.join(currentDir, 'node_modules', '@vue-skuilder', 'standalone-ui');
|
|
15
|
+
if (existsSync(nodeModulesPath)) {
|
|
16
|
+
return nodeModulesPath;
|
|
17
|
+
}
|
|
18
|
+
currentDir = path.dirname(currentDir);
|
|
19
|
+
}
|
|
20
|
+
throw new Error('Could not find @vue-skuilder/standalone-ui package. Please ensure it is installed.');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Copy directory recursively, excluding certain files/directories
|
|
24
|
+
*/
|
|
25
|
+
export async function copyDirectory(source, destination, excludePatterns = ['node_modules', 'dist', '.git', 'cypress']) {
|
|
26
|
+
const entries = await fs.readdir(source, { withFileTypes: true });
|
|
27
|
+
await fs.mkdir(destination, { recursive: true });
|
|
28
|
+
for (const entry of entries) {
|
|
29
|
+
const sourcePath = path.join(source, entry.name);
|
|
30
|
+
const destPath = path.join(destination, entry.name);
|
|
31
|
+
// Skip excluded patterns
|
|
32
|
+
if (excludePatterns.some(pattern => entry.name.includes(pattern))) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (entry.isDirectory()) {
|
|
36
|
+
await copyDirectory(sourcePath, destPath, excludePatterns);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
await fs.copyFile(sourcePath, destPath);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Transform package.json to use published dependencies instead of workspace references
|
|
45
|
+
*/
|
|
46
|
+
export async function transformPackageJson(packageJsonPath, projectName, cliVersion) {
|
|
47
|
+
const content = await fs.readFile(packageJsonPath, 'utf-8');
|
|
48
|
+
const packageJson = JSON.parse(content);
|
|
49
|
+
// Update basic project info
|
|
50
|
+
packageJson.name = projectName;
|
|
51
|
+
packageJson.description = `Skuilder course application: ${projectName}`;
|
|
52
|
+
packageJson.version = '1.0.0';
|
|
53
|
+
// Transform workspace dependencies to published versions
|
|
54
|
+
if (packageJson.dependencies) {
|
|
55
|
+
for (const [depName, version] of Object.entries(packageJson.dependencies)) {
|
|
56
|
+
if (typeof version === 'string' && version.startsWith('workspace:')) {
|
|
57
|
+
// Replace workspace references with CLI's version
|
|
58
|
+
packageJson.dependencies[depName] = `^${cliVersion}`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Add missing terser devDependency for build minification
|
|
63
|
+
if (packageJson.devDependencies && !packageJson.devDependencies['terser']) {
|
|
64
|
+
packageJson.devDependencies['terser'] = '^5.39.0';
|
|
65
|
+
}
|
|
66
|
+
// Remove CLI-specific fields that don't belong in generated projects
|
|
67
|
+
delete packageJson.publishConfig;
|
|
68
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Create a vite.config.ts to work with published packages instead of workspace sources
|
|
72
|
+
*
|
|
73
|
+
* // [ ] This should be revised so that it works from the existing vite.config.ts in standalone-ui. As is, it recreates 95% of the same config.
|
|
74
|
+
*/
|
|
75
|
+
export async function createViteConfig(viteConfigPath) {
|
|
76
|
+
// Create a clean vite config for standalone projects
|
|
77
|
+
const transformedContent = `// packages/standalone-ui/vite.config.ts
|
|
78
|
+
import { defineConfig } from 'vite';
|
|
79
|
+
import vue from '@vitejs/plugin-vue';
|
|
80
|
+
import { fileURLToPath, URL } from 'node:url';
|
|
81
|
+
|
|
82
|
+
export default defineConfig({
|
|
83
|
+
plugins: [vue()],
|
|
84
|
+
resolve: {
|
|
85
|
+
alias: {
|
|
86
|
+
// Alias for internal src paths
|
|
87
|
+
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
|
88
|
+
|
|
89
|
+
// Add events alias if needed (often required by dependencies)
|
|
90
|
+
events: 'events',
|
|
91
|
+
},
|
|
92
|
+
extensions: ['.js', '.ts', '.json', '.vue'],
|
|
93
|
+
dedupe: [
|
|
94
|
+
// Ensure single instances of core libs and published packages
|
|
95
|
+
'vue',
|
|
96
|
+
'vuetify',
|
|
97
|
+
'pinia',
|
|
98
|
+
'vue-router',
|
|
99
|
+
'@vue-skuilder/db',
|
|
100
|
+
'@vue-skuilder/common',
|
|
101
|
+
'@vue-skuilder/common-ui',
|
|
102
|
+
'@vue-skuilder/courses',
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
// --- Dependencies optimization ---
|
|
106
|
+
optimizeDeps: {
|
|
107
|
+
// Help Vite pre-bundle dependencies from published packages
|
|
108
|
+
include: [
|
|
109
|
+
'@vue-skuilder/common-ui',
|
|
110
|
+
'@vue-skuilder/db',
|
|
111
|
+
'@vue-skuilder/common',
|
|
112
|
+
'@vue-skuilder/courses',
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
server: {
|
|
116
|
+
port: 5173, // Use standard Vite port for standalone projects
|
|
117
|
+
},
|
|
118
|
+
build: {
|
|
119
|
+
sourcemap: true,
|
|
120
|
+
target: 'es2020',
|
|
121
|
+
minify: 'terser',
|
|
122
|
+
terserOptions: {
|
|
123
|
+
keep_classnames: true,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
// Add define block for process polyfills
|
|
127
|
+
define: {
|
|
128
|
+
global: 'window',
|
|
129
|
+
'process.env': process.env,
|
|
130
|
+
'process.browser': true,
|
|
131
|
+
'process.version': JSON.stringify(process.version),
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
`;
|
|
135
|
+
await fs.writeFile(viteConfigPath, transformedContent);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Generate skuilder.config.json based on project configuration
|
|
139
|
+
*/
|
|
140
|
+
export async function generateSkuilderConfig(configPath, config) {
|
|
141
|
+
const skuilderConfig = {
|
|
142
|
+
title: config.title,
|
|
143
|
+
dataLayerType: config.dataLayerType
|
|
144
|
+
};
|
|
145
|
+
if (config.course) {
|
|
146
|
+
skuilderConfig.course = config.course;
|
|
147
|
+
}
|
|
148
|
+
if (config.couchdbUrl) {
|
|
149
|
+
skuilderConfig.couchdbUrl = config.couchdbUrl;
|
|
150
|
+
}
|
|
151
|
+
if (config.theme) {
|
|
152
|
+
skuilderConfig.theme = config.theme;
|
|
153
|
+
}
|
|
154
|
+
await fs.writeFile(configPath, JSON.stringify(skuilderConfig, null, 2));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Generate .gitignore file for the project
|
|
158
|
+
*/
|
|
159
|
+
export async function generateGitignore(gitignorePath) {
|
|
160
|
+
const gitignoreContent = `# Dependencies
|
|
161
|
+
node_modules/
|
|
162
|
+
/.pnp
|
|
163
|
+
.pnp.js
|
|
164
|
+
|
|
165
|
+
# Production builds
|
|
166
|
+
/dist
|
|
167
|
+
/build
|
|
168
|
+
|
|
169
|
+
# Local env files
|
|
170
|
+
.env
|
|
171
|
+
.env.local
|
|
172
|
+
.env.development.local
|
|
173
|
+
.env.test.local
|
|
174
|
+
.env.production.local
|
|
175
|
+
|
|
176
|
+
# Log files
|
|
177
|
+
npm-debug.log*
|
|
178
|
+
yarn-debug.log*
|
|
179
|
+
yarn-error.log*
|
|
180
|
+
pnpm-debug.log*
|
|
181
|
+
lerna-debug.log*
|
|
182
|
+
|
|
183
|
+
# Runtime data
|
|
184
|
+
pids
|
|
185
|
+
*.pid
|
|
186
|
+
*.seed
|
|
187
|
+
*.pid.lock
|
|
188
|
+
|
|
189
|
+
# Coverage directory used by tools like istanbul
|
|
190
|
+
coverage/
|
|
191
|
+
*.lcov
|
|
192
|
+
|
|
193
|
+
# nyc test coverage
|
|
194
|
+
.nyc_output
|
|
195
|
+
|
|
196
|
+
# Dependency directories
|
|
197
|
+
jspm_packages/
|
|
198
|
+
|
|
199
|
+
# TypeScript cache
|
|
200
|
+
*.tsbuildinfo
|
|
201
|
+
|
|
202
|
+
# Optional npm cache directory
|
|
203
|
+
.npm
|
|
204
|
+
|
|
205
|
+
# Optional eslint cache
|
|
206
|
+
.eslintcache
|
|
207
|
+
|
|
208
|
+
# Microbundle cache
|
|
209
|
+
.rpt2_cache/
|
|
210
|
+
.rts2_cache_cjs/
|
|
211
|
+
.rts2_cache_es/
|
|
212
|
+
.rts2_cache_umd/
|
|
213
|
+
|
|
214
|
+
# Optional REPL history
|
|
215
|
+
.node_repl_history
|
|
216
|
+
|
|
217
|
+
# Output of 'npm pack'
|
|
218
|
+
*.tgz
|
|
219
|
+
|
|
220
|
+
# Yarn Integrity file
|
|
221
|
+
.yarn-integrity
|
|
222
|
+
|
|
223
|
+
# parcel-bundler cache (https://parceljs.org/)
|
|
224
|
+
.cache
|
|
225
|
+
.parcel-cache
|
|
226
|
+
|
|
227
|
+
# Next.js build output
|
|
228
|
+
.next
|
|
229
|
+
|
|
230
|
+
# Nuxt.js build / generate output
|
|
231
|
+
.nuxt
|
|
232
|
+
dist
|
|
233
|
+
|
|
234
|
+
# Gatsby files
|
|
235
|
+
.cache/
|
|
236
|
+
public
|
|
237
|
+
|
|
238
|
+
# Storybook build outputs
|
|
239
|
+
.out
|
|
240
|
+
.storybook-out
|
|
241
|
+
|
|
242
|
+
# Temporary folders
|
|
243
|
+
tmp/
|
|
244
|
+
temp/
|
|
245
|
+
|
|
246
|
+
# Editor directories and files
|
|
247
|
+
.vscode/
|
|
248
|
+
.idea
|
|
249
|
+
.DS_Store
|
|
250
|
+
*.suo
|
|
251
|
+
*.ntvs*
|
|
252
|
+
*.njsproj
|
|
253
|
+
*.sln
|
|
254
|
+
*.sw?
|
|
255
|
+
|
|
256
|
+
# OS generated files
|
|
257
|
+
Thumbs.db
|
|
258
|
+
|
|
259
|
+
# Cypress
|
|
260
|
+
/cypress/videos/
|
|
261
|
+
/cypress/screenshots/
|
|
262
|
+
|
|
263
|
+
# Local development
|
|
264
|
+
.env.development
|
|
265
|
+
.env.production
|
|
266
|
+
|
|
267
|
+
# Package manager lockfiles (uncomment if you want to ignore them)
|
|
268
|
+
# package-lock.json
|
|
269
|
+
# yarn.lock
|
|
270
|
+
# pnpm-lock.yaml
|
|
271
|
+
|
|
272
|
+
# Skuilder specific
|
|
273
|
+
/src/data/local-*.json
|
|
274
|
+
`;
|
|
275
|
+
await fs.writeFile(gitignorePath, gitignoreContent);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Generate project README.md
|
|
279
|
+
*/
|
|
280
|
+
export async function generateReadme(readmePath, config) {
|
|
281
|
+
const dataLayerInfo = config.dataLayerType === 'static'
|
|
282
|
+
? 'This project uses a static data layer with JSON files.'
|
|
283
|
+
: `This project connects to CouchDB at: ${config.couchdbUrl || '[URL not specified]'}`;
|
|
284
|
+
const readme = `# ${config.title}
|
|
285
|
+
|
|
286
|
+
A Skuilder course application built with Vue 3, Vuetify, and Pinia.
|
|
287
|
+
|
|
288
|
+
## Data Layer
|
|
289
|
+
|
|
290
|
+
${dataLayerInfo}
|
|
291
|
+
|
|
292
|
+
## Development
|
|
293
|
+
|
|
294
|
+
Install dependencies:
|
|
295
|
+
\`\`\`bash
|
|
296
|
+
npm install
|
|
297
|
+
\`\`\`
|
|
298
|
+
|
|
299
|
+
Start the development server:
|
|
300
|
+
\`\`\`bash
|
|
301
|
+
npm run dev
|
|
302
|
+
\`\`\`
|
|
303
|
+
|
|
304
|
+
Build for production:
|
|
305
|
+
\`\`\`bash
|
|
306
|
+
npm run build
|
|
307
|
+
\`\`\`
|
|
308
|
+
|
|
309
|
+
## Configuration
|
|
310
|
+
|
|
311
|
+
Course configuration is managed in \`skuilder.config.json\`. You can modify:
|
|
312
|
+
- Course title
|
|
313
|
+
- Data layer settings
|
|
314
|
+
- Theme customization
|
|
315
|
+
- Database connection details (for dynamic data layer)
|
|
316
|
+
|
|
317
|
+
## Theme
|
|
318
|
+
|
|
319
|
+
Current theme: **${config.theme.name}**
|
|
320
|
+
- Primary: ${config.theme.colors.primary}
|
|
321
|
+
- Secondary: ${config.theme.colors.secondary}
|
|
322
|
+
- Accent: ${config.theme.colors.accent}
|
|
323
|
+
|
|
324
|
+
## Testing
|
|
325
|
+
|
|
326
|
+
Run end-to-end tests:
|
|
327
|
+
\`\`\`bash
|
|
328
|
+
npm run test:e2e
|
|
329
|
+
\`\`\`
|
|
330
|
+
|
|
331
|
+
Run tests in headless mode:
|
|
332
|
+
\`\`\`bash
|
|
333
|
+
npm run test:e2e:headless
|
|
334
|
+
\`\`\`
|
|
335
|
+
|
|
336
|
+
## Learn More
|
|
337
|
+
|
|
338
|
+
Visit the [Skuilder documentation](https://github.com/NiloCK/vue-skuilder) for more information about building course applications.
|
|
339
|
+
`;
|
|
340
|
+
await fs.writeFile(readmePath, readme);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Copy and transform the standalone-ui template to create a new project
|
|
344
|
+
*/
|
|
345
|
+
export async function processTemplate(projectPath, config, cliVersion) {
|
|
346
|
+
console.log(chalk.blue('📦 Locating standalone-ui template...'));
|
|
347
|
+
const templatePath = await findStandaloneUiPath();
|
|
348
|
+
console.log(chalk.blue('📂 Copying project files...'));
|
|
349
|
+
await copyDirectory(templatePath, projectPath);
|
|
350
|
+
console.log(chalk.blue('⚙️ Configuring package.json...'));
|
|
351
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
352
|
+
await transformPackageJson(packageJsonPath, config.projectName, cliVersion);
|
|
353
|
+
console.log(chalk.blue('🔧 Creating vite.config.ts...'));
|
|
354
|
+
const viteConfigPath = path.join(projectPath, 'vite.config.ts');
|
|
355
|
+
if (existsSync(viteConfigPath)) {
|
|
356
|
+
await createViteConfig(viteConfigPath);
|
|
357
|
+
}
|
|
358
|
+
console.log(chalk.blue('🔧 Generating configuration...'));
|
|
359
|
+
const configPath = path.join(projectPath, 'skuilder.config.json');
|
|
360
|
+
await generateSkuilderConfig(configPath, config);
|
|
361
|
+
console.log(chalk.blue('📝 Creating README...'));
|
|
362
|
+
const readmePath = path.join(projectPath, 'README.md');
|
|
363
|
+
await generateReadme(readmePath, config);
|
|
364
|
+
console.log(chalk.blue('📄 Generating .gitignore...'));
|
|
365
|
+
const gitignorePath = path.join(projectPath, '.gitignore');
|
|
366
|
+
await generateGitignore(gitignorePath);
|
|
367
|
+
console.log(chalk.green('✅ Template processing complete!'));
|
|
368
|
+
}
|
|
369
|
+
//# sourceMappingURL=template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/utils/template.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import backendConfig from '../../eslint.config.backend.mjs';
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
...backendConfig,
|
|
5
|
+
{
|
|
6
|
+
ignores: ['node_modules/**', 'dist/**', 'eslint.config.mjs', 'tsconfig.json'],
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
languageOptions: {
|
|
10
|
+
parserOptions: {
|
|
11
|
+
project: './tsconfig.json',
|
|
12
|
+
tsconfigRootDir: import.meta.dirname,
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
rules: {
|
|
16
|
+
// CLI-specific rules - CLI tools need console output
|
|
17
|
+
'no-console': 'off',
|
|
18
|
+
'@typescript-eslint/no-console': 'off',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
];
|
package/package.json
CHANGED
|
@@ -1,44 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skuilder",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
"
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "CLI tool for scaffolding Skuilder course applications",
|
|
6
|
+
"bin": {
|
|
7
|
+
"skuilder": "./dist/cli.js"
|
|
8
8
|
},
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
9
|
+
"main": "dist/cli.js",
|
|
10
|
+
"types": "dist/cli.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/cli.d.ts",
|
|
14
|
+
"import": "./dist/cli.js"
|
|
15
|
+
}
|
|
13
16
|
},
|
|
14
17
|
"scripts": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
+
"build": "rm -rf dist && tsc",
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"lint": "npx eslint .",
|
|
21
|
+
"lint:fix": "npx eslint . --fix",
|
|
22
|
+
"lint:check": "npx eslint . --max-warnings 0"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"cli",
|
|
26
|
+
"scaffolding",
|
|
27
|
+
"vue",
|
|
28
|
+
"skuilder",
|
|
29
|
+
"education",
|
|
30
|
+
"course"
|
|
31
|
+
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@vue-skuilder/standalone-ui": "^0.1.4",
|
|
34
|
+
"chalk": "^5.3.0",
|
|
35
|
+
"commander": "^11.0.0",
|
|
36
|
+
"fs-extra": "^11.2.0",
|
|
37
|
+
"inquirer": "^9.2.0"
|
|
18
38
|
},
|
|
19
39
|
"devDependencies": {
|
|
20
|
-
"@types/
|
|
21
|
-
"@types/
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"source-map-loader": "^0.1.6",
|
|
25
|
-
"ts-node": "^3.0.2",
|
|
26
|
-
"typescript": "2.1.6",
|
|
27
|
-
"webpack": "2.2.1"
|
|
40
|
+
"@types/fs-extra": "^11.0.0",
|
|
41
|
+
"@types/inquirer": "^9.0.0",
|
|
42
|
+
"@types/node": "^20.0.0",
|
|
43
|
+
"typescript": "~5.7.2"
|
|
28
44
|
},
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"react": "^15.4.1",
|
|
35
|
-
"react-addons-perf": "^15.4.1",
|
|
36
|
-
"react-addons-test-utils": "^15.4.1",
|
|
37
|
-
"react-dom": "^15.4.1",
|
|
38
|
-
"react-native": "^0.42.0",
|
|
39
|
-
"react-native-windows": "^0.33.0",
|
|
40
|
-
"reactxp": "^0.42.0-rc.12",
|
|
41
|
-
"skldr-course-base": "^0.1.2",
|
|
42
|
-
"skldr-crs-math": "^0.1.2"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
47
|
+
},
|
|
48
|
+
"packageManager": "yarn@4.6.0"
|
|
49
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { readFileSync } from 'fs';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { dirname, join } from 'path';
|
|
7
|
+
import { initCommand } from './commands/init.js';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
|
|
12
|
+
// Read package.json to get version
|
|
13
|
+
const packagePath = join(__dirname, '..', 'package.json');
|
|
14
|
+
const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
15
|
+
|
|
16
|
+
const program = new Command();
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.name('skuilder')
|
|
20
|
+
.description('CLI tool for scaffolding Skuilder course applications')
|
|
21
|
+
.version(packageJson.version);
|
|
22
|
+
|
|
23
|
+
program
|
|
24
|
+
.command('init')
|
|
25
|
+
.argument('<project-name>', 'name of the project to create')
|
|
26
|
+
.description('create a new Skuilder course application')
|
|
27
|
+
.option('--data-layer <type>', 'data layer type (static|dynamic)', 'dynamic')
|
|
28
|
+
.option('--theme <name>', 'theme name (default|medical|educational|corporate)', 'default')
|
|
29
|
+
.option('--no-interactive', 'skip interactive prompts')
|
|
30
|
+
.option('--couchdb-url <url>', 'CouchDB server URL (for dynamic data layer)')
|
|
31
|
+
.option('--course-id <id>', 'course ID to import (for dynamic data layer)')
|
|
32
|
+
.action(initCommand);
|
|
33
|
+
|
|
34
|
+
program.on('--help', () => {
|
|
35
|
+
console.log('');
|
|
36
|
+
console.log('Examples:');
|
|
37
|
+
console.log(' $ skuilder init my-anatomy-course');
|
|
38
|
+
console.log(' $ skuilder init biology-101 --data-layer=static --theme=medical');
|
|
39
|
+
console.log(' $ skuilder init physics --no-interactive --data-layer=dynamic');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
program.parse();
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { CliOptions } from '../types.js';
|
|
5
|
+
import { gatherProjectConfig, confirmProjectCreation } from '../utils/prompts.js';
|
|
6
|
+
import { processTemplate } from '../utils/template.js';
|
|
7
|
+
import { readFileSync } from 'fs';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
import { dirname, join } from 'path';
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
|
|
14
|
+
export async function initCommand(
|
|
15
|
+
projectName: string,
|
|
16
|
+
options: CliOptions
|
|
17
|
+
): Promise<void> {
|
|
18
|
+
try {
|
|
19
|
+
// Validate project name
|
|
20
|
+
if (!isValidProjectName(projectName)) {
|
|
21
|
+
console.error(chalk.red('❌ Invalid project name. Use only letters, numbers, hyphens, and underscores.'));
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Check if directory already exists
|
|
26
|
+
const projectPath = path.resolve(process.cwd(), projectName);
|
|
27
|
+
if (existsSync(projectPath)) {
|
|
28
|
+
console.error(chalk.red(`❌ Directory "${projectName}" already exists.`));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Get CLI version for dependency transformation
|
|
33
|
+
const packagePath = join(__dirname, '..', '..', 'package.json');
|
|
34
|
+
const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
35
|
+
const cliVersion = packageJson.version;
|
|
36
|
+
|
|
37
|
+
// Gather project configuration
|
|
38
|
+
const config = await gatherProjectConfig(projectName, options);
|
|
39
|
+
|
|
40
|
+
// Confirm project creation (only in interactive mode)
|
|
41
|
+
if (options.interactive) {
|
|
42
|
+
const confirmed = await confirmProjectCreation(config, projectPath);
|
|
43
|
+
if (!confirmed) {
|
|
44
|
+
console.log(chalk.yellow('Project creation cancelled.'));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
console.log(chalk.cyan(`\n🛠️ Creating project "${projectName}"...\n`));
|
|
50
|
+
|
|
51
|
+
// Process template and create project
|
|
52
|
+
await processTemplate(projectPath, config, cliVersion);
|
|
53
|
+
|
|
54
|
+
// Success message
|
|
55
|
+
console.log(chalk.green('\n🎉 Project created successfully!\n'));
|
|
56
|
+
console.log(chalk.cyan('Next steps:'));
|
|
57
|
+
console.log(` ${chalk.white('cd')} ${projectName}`);
|
|
58
|
+
console.log(` ${chalk.white('npm install')}`);
|
|
59
|
+
console.log(` ${chalk.white('npm run dev')}`);
|
|
60
|
+
console.log('');
|
|
61
|
+
|
|
62
|
+
if (config.dataLayerType === 'couch') {
|
|
63
|
+
console.log(chalk.yellow('📝 Note: Make sure your CouchDB server is running and accessible.'));
|
|
64
|
+
if (config.course) {
|
|
65
|
+
console.log(chalk.yellow(`📚 Course ID "${config.course}" will be loaded from the database.`));
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
console.log(chalk.yellow('📝 Note: This project uses static data. Sample course data has been included.'));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error(chalk.red('\n❌ Failed to create project:'));
|
|
73
|
+
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function isValidProjectName(name: string): boolean {
|
|
79
|
+
// Allow letters, numbers, hyphens, and underscores
|
|
80
|
+
// Must start with a letter or number
|
|
81
|
+
const validNameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-_]*$/;
|
|
82
|
+
return validNameRegex.test(name) && name.length > 0 && name.length <= 214;
|
|
83
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export interface CliOptions {
|
|
2
|
+
dataLayer: 'static' | 'dynamic';
|
|
3
|
+
theme: 'default' | 'medical' | 'educational' | 'corporate';
|
|
4
|
+
interactive: boolean;
|
|
5
|
+
couchdbUrl?: string;
|
|
6
|
+
courseId?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ProjectConfig {
|
|
10
|
+
projectName: string;
|
|
11
|
+
title: string;
|
|
12
|
+
dataLayerType: 'static' | 'couch';
|
|
13
|
+
course?: string;
|
|
14
|
+
couchdbUrl?: string;
|
|
15
|
+
theme: ThemeConfig;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ThemeConfig {
|
|
19
|
+
name: string;
|
|
20
|
+
colors: {
|
|
21
|
+
primary: string;
|
|
22
|
+
secondary: string;
|
|
23
|
+
accent: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SkuilderConfig {
|
|
28
|
+
title: string;
|
|
29
|
+
course?: string;
|
|
30
|
+
dataLayerType: 'static' | 'couch';
|
|
31
|
+
couchdbUrl?: string;
|
|
32
|
+
theme?: ThemeConfig;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface InitCommandOptions extends CliOptions {
|
|
36
|
+
projectName: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const PREDEFINED_THEMES: Record<string, ThemeConfig> = {
|
|
40
|
+
default: {
|
|
41
|
+
name: 'default',
|
|
42
|
+
colors: {
|
|
43
|
+
primary: '#1976D2',
|
|
44
|
+
secondary: '#424242',
|
|
45
|
+
accent: '#82B1FF'
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
medical: {
|
|
49
|
+
name: 'medical',
|
|
50
|
+
colors: {
|
|
51
|
+
primary: '#2E7D32',
|
|
52
|
+
secondary: '#558B2F',
|
|
53
|
+
accent: '#66BB6A'
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
educational: {
|
|
57
|
+
name: 'educational',
|
|
58
|
+
colors: {
|
|
59
|
+
primary: '#F57C00',
|
|
60
|
+
secondary: '#FF9800',
|
|
61
|
+
accent: '#FFB74D'
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
corporate: {
|
|
65
|
+
name: 'corporate',
|
|
66
|
+
colors: {
|
|
67
|
+
primary: '#37474F',
|
|
68
|
+
secondary: '#546E7A',
|
|
69
|
+
accent: '#78909C'
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|