@mvp-kit/create 0.0.10 → 0.0.11
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 +49 -16
- package/dist/create.js +754 -571
- package/dist/create.js.map +1 -1
- package/dist/download.js +62 -0
- package/dist/download.js.map +1 -0
- package/dist/index.js +24 -42
- package/dist/index.js.map +1 -1
- package/dist/template.js +59 -158
- package/dist/template.js.map +1 -1
- package/dist/utils.js +0 -88
- package/dist/utils.js.map +1 -1
- package/package.json +21 -24
- package/dist/database.js +0 -105
- package/dist/database.js.map +0 -1
- package/dist/template-downloader.js +0 -248
- package/dist/template-downloader.js.map +0 -1
- package/dist/test.js +0 -359
- package/dist/test.js.map +0 -1
package/dist/utils.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = path.dirname(__filename);
|
|
6
1
|
export function validateProjectName(name) {
|
|
7
2
|
if (!name) {
|
|
8
3
|
throw new Error('Project name is required');
|
|
@@ -12,87 +7,4 @@ export function validateProjectName(name) {
|
|
|
12
7
|
}
|
|
13
8
|
return name;
|
|
14
9
|
}
|
|
15
|
-
export function generateTemplateVariables(projectName, options = {}, packageManager = 'pnpm', packageManagerVersion) {
|
|
16
|
-
const validatedName = validateProjectName(projectName);
|
|
17
|
-
// Generate different case variations
|
|
18
|
-
const kebabCase = validatedName.toLowerCase().replace(/[_\s]+/g, '-');
|
|
19
|
-
const camelCase = kebabCase.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
20
|
-
const displayName = kebabCase.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
21
|
-
// Generate package scope (user can override later)
|
|
22
|
-
const packageScope = `@${kebabCase}`;
|
|
23
|
-
return {
|
|
24
|
-
projectName: validatedName,
|
|
25
|
-
projectDisplayName: options.description || displayName,
|
|
26
|
-
projectDescription: options.description || `A new MVPKit Core application: ${displayName}`,
|
|
27
|
-
projectKebabCase: kebabCase,
|
|
28
|
-
projectCamelCase: camelCase,
|
|
29
|
-
domainName: options.domain,
|
|
30
|
-
packageManager,
|
|
31
|
-
packageManagerVersion,
|
|
32
|
-
packageScope,
|
|
33
|
-
frontendPackageName: `${packageScope}/frontend`,
|
|
34
|
-
backendPackageName: `${packageScope}/backend`,
|
|
35
|
-
apiPackageName: `${packageScope}/api`,
|
|
36
|
-
configPackageName: `${packageScope}/config`,
|
|
37
|
-
workersName: `${kebabCase}-backend`,
|
|
38
|
-
pagesName: `${kebabCase}-frontend`,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
export function getCoreRepositoryPath() {
|
|
42
|
-
// Find the mvpkit root directory
|
|
43
|
-
let currentDir = __dirname;
|
|
44
|
-
// Go up from the built CLI package to find mvpkit root
|
|
45
|
-
// Path: /mvpkit/cli/packages/@mvp-kit-create/dist -> /mvpkit
|
|
46
|
-
while (currentDir && currentDir !== path.parse(currentDir).root) {
|
|
47
|
-
if (path.basename(currentDir) === 'mvpkit') {
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
currentDir = path.dirname(currentDir);
|
|
51
|
-
}
|
|
52
|
-
if (!currentDir || path.basename(currentDir) !== 'mvpkit') {
|
|
53
|
-
// Fallback: try relative from current working directory
|
|
54
|
-
const cwd = process.cwd();
|
|
55
|
-
const possiblePaths = [
|
|
56
|
-
path.resolve(cwd, '../core'), // from cli/test-output
|
|
57
|
-
path.resolve(cwd, '../../core'), // from cli/packages/@mvp-kit-create
|
|
58
|
-
path.resolve(cwd, '../../../core'), // from deeper nesting
|
|
59
|
-
];
|
|
60
|
-
for (const possiblePath of possiblePaths) {
|
|
61
|
-
if (fs.existsSync(possiblePath)) {
|
|
62
|
-
return possiblePath;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const coreDir = path.join(currentDir, 'core');
|
|
67
|
-
return coreDir;
|
|
68
|
-
}
|
|
69
|
-
export function shouldSkipFile(filePath, skipPatterns) {
|
|
70
|
-
const fileName = path.basename(filePath);
|
|
71
|
-
const relativePath = filePath;
|
|
72
|
-
return skipPatterns.some(pattern => {
|
|
73
|
-
if (pattern.startsWith('/')) {
|
|
74
|
-
return relativePath.startsWith(pattern.slice(1));
|
|
75
|
-
}
|
|
76
|
-
if (pattern.endsWith('/')) {
|
|
77
|
-
return relativePath.startsWith(pattern) || relativePath.includes(pattern);
|
|
78
|
-
}
|
|
79
|
-
// Exact filename match
|
|
80
|
-
if (fileName === pattern) {
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
return fileName.includes(pattern) || relativePath.includes(pattern);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
export function transformFileName(fileName, variables) {
|
|
87
|
-
return fileName
|
|
88
|
-
.replace(/mvpkit-core/g, variables.projectKebabCase)
|
|
89
|
-
.replace(/mvpkit/g, variables.projectKebabCase);
|
|
90
|
-
}
|
|
91
|
-
export const DEFAULT_SKIP_PATTERNS = [
|
|
92
|
-
'.git/',
|
|
93
|
-
'.github/',
|
|
94
|
-
'.serena',
|
|
95
|
-
'examples/',
|
|
96
|
-
'cleanup.sh'
|
|
97
|
-
];
|
|
98
10
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;IAC7C,CAAC;IAED,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAA;IACtH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mvp-kit/create",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Create MVPKit applications - Universal CLI for all MVPKit templates",
|
|
3
|
+
"version": "0.0.11",
|
|
4
|
+
"description": "Create MVPKit applications - Universal Create CLI for all MVPKit templates",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mvpkit",
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
"ai"
|
|
14
14
|
],
|
|
15
15
|
"license": "MIT",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/mvp-kit/create.git"
|
|
19
|
+
},
|
|
16
20
|
"bin": {
|
|
17
21
|
"@mvp-kit/create": "dist/index.js"
|
|
18
22
|
},
|
|
@@ -23,35 +27,28 @@
|
|
|
23
27
|
"engines": {
|
|
24
28
|
"node": ">=20.0.0"
|
|
25
29
|
},
|
|
26
|
-
"scripts": {
|
|
27
|
-
"build": "tsc",
|
|
28
|
-
"dev": "tsc --watch",
|
|
29
|
-
"test": "vitest",
|
|
30
|
-
"test:integration": "node dist/test.js",
|
|
31
|
-
"validate": "pnpm build && pnpm test:integration",
|
|
32
|
-
"typecheck": "tsc --noEmit",
|
|
33
|
-
"lint": "echo 'No linting configured for CLI'",
|
|
34
|
-
"clean": "rm -rf dist"
|
|
35
|
-
},
|
|
36
30
|
"dependencies": {
|
|
37
|
-
"
|
|
38
|
-
"inquirer": "^9.0.0",
|
|
39
|
-
"handlebars": "^4.7.8",
|
|
31
|
+
"@types/prompts": "^2.4.9",
|
|
40
32
|
"chalk": "^5.3.0",
|
|
41
|
-
"
|
|
33
|
+
"commander": "^11.0.0",
|
|
42
34
|
"fs-extra": "^11.0.0",
|
|
43
35
|
"glob": "^10.3.0",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
36
|
+
"handlebars": "^4.7.8",
|
|
37
|
+
"inquirer": "^9.0.0",
|
|
38
|
+
"node-fetch": "^3.3.0",
|
|
39
|
+
"ora": "^7.0.1",
|
|
40
|
+
"prompts": "^2.4.2"
|
|
47
41
|
},
|
|
48
42
|
"devDependencies": {
|
|
49
43
|
"@types/fs-extra": "^11.0.4",
|
|
50
44
|
"@types/inquirer": "^9.0.0",
|
|
51
45
|
"@types/node": "^20.0.0",
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
46
|
+
"typescript": "^5.9.2"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc && chmod +x dist/index.js",
|
|
50
|
+
"dev": "tsc --watch",
|
|
51
|
+
"clean": "rm -rf dist",
|
|
52
|
+
"typecheck": "tsc --noEmit"
|
|
56
53
|
}
|
|
57
|
-
}
|
|
54
|
+
}
|
package/dist/database.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import ora from 'ora';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import fs from 'fs-extra';
|
|
6
|
-
function detectPackageManager(dir) {
|
|
7
|
-
// Check how CLI was invoked (highest priority)
|
|
8
|
-
const invocation = detectInvocationMethod();
|
|
9
|
-
if (invocation) {
|
|
10
|
-
return invocation;
|
|
11
|
-
}
|
|
12
|
-
// Check for lock files in priority order
|
|
13
|
-
if (fs.existsSync(path.join(dir, 'bun.lockb')))
|
|
14
|
-
return 'bun';
|
|
15
|
-
if (fs.existsSync(path.join(dir, 'pnpm-lock.yaml')))
|
|
16
|
-
return 'pnpm';
|
|
17
|
-
// Default to pnpm
|
|
18
|
-
return 'pnpm';
|
|
19
|
-
}
|
|
20
|
-
function detectInvocationMethod() {
|
|
21
|
-
// Check process.execArgv and process.argv to see how we were invoked
|
|
22
|
-
const execPath = process.execPath;
|
|
23
|
-
const argv = process.argv;
|
|
24
|
-
const userAgent = process.env.npm_config_user_agent || '';
|
|
25
|
-
// Check if invoked via bunx
|
|
26
|
-
if (execPath.includes('bun') || userAgent.startsWith('bun')) {
|
|
27
|
-
return 'bun';
|
|
28
|
-
}
|
|
29
|
-
// Check argv for package manager indicators
|
|
30
|
-
const commandLine = argv.join(' ');
|
|
31
|
-
if (commandLine.includes('bunx') || commandLine.includes('bun run')) {
|
|
32
|
-
return 'bun';
|
|
33
|
-
}
|
|
34
|
-
if (commandLine.includes('pnpm') || commandLine.includes('pnpx')) {
|
|
35
|
-
return 'pnpm';
|
|
36
|
-
}
|
|
37
|
-
if (commandLine.includes('npx') || commandLine.includes('npm create')) {
|
|
38
|
-
return 'pnpm';
|
|
39
|
-
}
|
|
40
|
-
// Check user agent string
|
|
41
|
-
if (userAgent.startsWith('pnpm'))
|
|
42
|
-
return 'pnpm';
|
|
43
|
-
if (userAgent.startsWith('bun'))
|
|
44
|
-
return 'bun';
|
|
45
|
-
if (userAgent.startsWith('npm'))
|
|
46
|
-
return 'pnpm';
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
function getPackageManagerCommand(pm) {
|
|
50
|
-
const commands = {
|
|
51
|
-
npm: 'npm',
|
|
52
|
-
pnpm: 'pnpm',
|
|
53
|
-
bun: 'bun'
|
|
54
|
-
};
|
|
55
|
-
return commands[pm];
|
|
56
|
-
}
|
|
57
|
-
export async function setupDatabase(projectPath, variables) {
|
|
58
|
-
const spinner = ora('Setting up database...').start();
|
|
59
|
-
const backendPath = path.join(projectPath, 'apps', 'backend');
|
|
60
|
-
const packageManager = detectPackageManager(projectPath);
|
|
61
|
-
const pmCommand = getPackageManagerCommand(packageManager);
|
|
62
|
-
try {
|
|
63
|
-
// Initialize local database directory structure
|
|
64
|
-
spinner.text = 'Initializing local database...';
|
|
65
|
-
execSync(`${pmCommand} run db:init`, { cwd: backendPath, stdio: 'ignore' });
|
|
66
|
-
// Generate fresh migrations
|
|
67
|
-
spinner.text = 'Generating database migrations...';
|
|
68
|
-
execSync(`${pmCommand} run db:generate`, { cwd: backendPath, stdio: 'ignore' });
|
|
69
|
-
// Set up local database by running migrations
|
|
70
|
-
spinner.text = 'Setting up local database...';
|
|
71
|
-
execSync(`${pmCommand} run db:migrate:local`, { cwd: backendPath, stdio: 'ignore' });
|
|
72
|
-
spinner.succeed('Database setup completed!');
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
catch (error) {
|
|
76
|
-
spinner.fail('Database setup failed');
|
|
77
|
-
console.log(chalk.yellow('⚠️ Set up the database manually:'));
|
|
78
|
-
console.log(chalk.gray(' cd apps/backend'));
|
|
79
|
-
console.log(chalk.gray(` ${pmCommand} run db:init`));
|
|
80
|
-
console.log(chalk.gray(` ${pmCommand} run db:generate`));
|
|
81
|
-
console.log(chalk.gray(` ${pmCommand} run db:migrate:local`));
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
export function checkDatabaseRequirements() {
|
|
86
|
-
const errors = [];
|
|
87
|
-
let hasWrangler = false;
|
|
88
|
-
let hasNode = false;
|
|
89
|
-
try {
|
|
90
|
-
execSync('node --version', { stdio: 'ignore' });
|
|
91
|
-
hasNode = true;
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
errors.push('Node.js is required but not found');
|
|
95
|
-
}
|
|
96
|
-
try {
|
|
97
|
-
execSync('wrangler --version', { stdio: 'ignore' });
|
|
98
|
-
hasWrangler = true;
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
errors.push('Wrangler CLI is required for database setup');
|
|
102
|
-
}
|
|
103
|
-
return { hasWrangler, hasNode, errors };
|
|
104
|
-
}
|
|
105
|
-
//# sourceMappingURL=database.js.map
|
package/dist/database.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,MAAM,UAAU,CAAA;AAGzB,SAAS,oBAAoB,CAAC,GAAW;IACvC,+CAA+C;IAC/C,MAAM,UAAU,GAAG,sBAAsB,EAAE,CAAA;IAC3C,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,yCAAyC;IACzC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IAC5D,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAA;IAElE,kBAAkB;IAClB,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,sBAAsB;IAC7B,qEAAqE;IACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IACjC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAA;IAEzD,4BAA4B;IAC5B,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,4CAA4C;IAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAClC,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACpE,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACjE,OAAO,MAAM,CAAA;IACf,CAAC;IACD,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACtE,OAAO,MAAM,CAAA;IACf,CAAC;IAED,0BAA0B;IAC1B,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAA;IAC/C,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAC7C,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAA;IAE9C,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,wBAAwB,CAAC,EAA0B;IAC1D,MAAM,QAAQ,GAAG;QACf,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,KAAK;KACX,CAAA;IACD,OAAO,QAAQ,CAAC,EAAE,CAAC,CAAA;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,WAAmB,EACnB,SAA4B;IAE5B,MAAM,OAAO,GAAG,GAAG,CAAC,wBAAwB,CAAC,CAAC,KAAK,EAAE,CAAA;IAErD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA;IAC7D,MAAM,cAAc,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAA;IACxD,MAAM,SAAS,GAAG,wBAAwB,CAAC,cAAc,CAAC,CAAA;IAE1D,IAAI,CAAC;QAEH,gDAAgD;QAChD,OAAO,CAAC,IAAI,GAAG,gCAAgC,CAAA;QAC/C,QAAQ,CAAC,GAAG,SAAS,cAAc,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;QAE3E,4BAA4B;QAC5B,OAAO,CAAC,IAAI,GAAG,mCAAmC,CAAA;QAClD,QAAQ,CAAC,GAAG,SAAS,kBAAkB,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;QAE/E,8CAA8C;QAC9C,OAAO,CAAC,IAAI,GAAG,8BAA8B,CAAA;QAC7C,QAAQ,CAAC,GAAG,SAAS,uBAAuB,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;QAEpF,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAA;QAC5C,OAAO,IAAI,CAAA;IAEb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;QACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,mCAAmC,CAAC,CAAC,CAAA;QAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,SAAS,cAAc,CAAC,CAAC,CAAA;QACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,SAAS,kBAAkB,CAAC,CAAC,CAAA;QAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,SAAS,uBAAuB,CAAC,CAAC,CAAA;QAE/D,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAGD,MAAM,UAAU,yBAAyB;IAKvC,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,WAAW,GAAG,KAAK,CAAA;IACvB,IAAI,OAAO,GAAG,KAAK,CAAA;IAEnB,IAAI,CAAC;QACH,QAAQ,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC/C,OAAO,GAAG,IAAI,CAAA;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAA;IAClD,CAAC;IAED,IAAI,CAAC;QACH,QAAQ,CAAC,oBAAoB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;QACnD,WAAW,GAAG,IAAI,CAAA;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAA;IAC5D,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAA;AACzC,CAAC"}
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
import fetch from 'node-fetch';
|
|
2
|
-
import fs from 'fs-extra';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import yauzl from 'yauzl';
|
|
5
|
-
import tmp from 'tmp';
|
|
6
|
-
import { pipeline } from 'stream/promises';
|
|
7
|
-
import chalk from 'chalk';
|
|
8
|
-
import ora from 'ora';
|
|
9
|
-
// Template registry for different kits
|
|
10
|
-
export const TEMPLATE_REGISTRY = {
|
|
11
|
-
core: {
|
|
12
|
-
name: 'core',
|
|
13
|
-
displayName: 'MVPKit Core',
|
|
14
|
-
description: 'Free Cloudflare-native starter with React 19, tRPC, and Drizzle ORM',
|
|
15
|
-
source: {
|
|
16
|
-
// Default to GitHub (production), use --dev flag for development
|
|
17
|
-
type: 'github-zip',
|
|
18
|
-
url: 'https://github.com/mvp-kit/core/archive/refs/heads/main.zip',
|
|
19
|
-
cacheable: false
|
|
20
|
-
},
|
|
21
|
-
features: ['React 19', 'Cloudflare Workers', 'tRPC', 'Drizzle ORM', 'Better Auth'],
|
|
22
|
-
license: 'free'
|
|
23
|
-
},
|
|
24
|
-
saas: {
|
|
25
|
-
name: 'saas',
|
|
26
|
-
displayName: 'MVPKit SaaS',
|
|
27
|
-
description: 'Production SaaS kit with payments, subscriptions, and multi-tenancy',
|
|
28
|
-
source: {
|
|
29
|
-
type: 'protected-url',
|
|
30
|
-
url: 'https://api.mvpkit.dev/templates/saas/latest.zip',
|
|
31
|
-
auth: { type: 'jwt' },
|
|
32
|
-
cacheable: false
|
|
33
|
-
},
|
|
34
|
-
features: ['Everything in Core', 'Stripe Integration', 'Multi-tenancy', 'Admin Dashboard'],
|
|
35
|
-
license: 'paid'
|
|
36
|
-
},
|
|
37
|
-
ai: {
|
|
38
|
-
name: 'ai',
|
|
39
|
-
displayName: 'MVPKit AI',
|
|
40
|
-
description: 'AI-powered applications with LLM integrations and vector databases',
|
|
41
|
-
source: {
|
|
42
|
-
type: 'protected-url',
|
|
43
|
-
url: 'https://api.mvpkit.dev/templates/ai/latest.zip',
|
|
44
|
-
auth: { type: 'jwt' },
|
|
45
|
-
cacheable: false
|
|
46
|
-
},
|
|
47
|
-
features: ['Everything in Core', 'OpenAI Integration', 'Vector DB', 'AI Components'],
|
|
48
|
-
license: 'paid'
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
export class TemplateDownloader {
|
|
52
|
-
cacheDir;
|
|
53
|
-
constructor() {
|
|
54
|
-
// Create cache directory in user's home
|
|
55
|
-
this.cacheDir = path.join(process.env.HOME || process.env.USERPROFILE || '/tmp', '.mvpkit', 'cache');
|
|
56
|
-
fs.ensureDirSync(this.cacheDir);
|
|
57
|
-
}
|
|
58
|
-
async downloadTemplate(templateName, licenseKey, useDev = false) {
|
|
59
|
-
const config = TEMPLATE_REGISTRY[templateName];
|
|
60
|
-
if (!config) {
|
|
61
|
-
throw new Error(`Unknown template: ${templateName}. Available templates: ${Object.keys(TEMPLATE_REGISTRY).join(', ')}`);
|
|
62
|
-
}
|
|
63
|
-
// Validate license for paid templates
|
|
64
|
-
if (config.license === 'paid' && !licenseKey) {
|
|
65
|
-
throw new Error(`Template '${templateName}' requires a license key. Use --license YOUR_LICENSE_KEY`);
|
|
66
|
-
}
|
|
67
|
-
const spinner = ora(`Downloading ${config.displayName} template...`).start();
|
|
68
|
-
try {
|
|
69
|
-
// Override source type if --dev flag is used
|
|
70
|
-
const source = useDev && config.name === 'core'
|
|
71
|
-
? { ...config.source, type: 'local' }
|
|
72
|
-
: config.source;
|
|
73
|
-
const templatePath = await this.downloadFromSource(source, licenseKey);
|
|
74
|
-
spinner.succeed(`Template downloaded: ${config.displayName}`);
|
|
75
|
-
return templatePath;
|
|
76
|
-
}
|
|
77
|
-
catch (error) {
|
|
78
|
-
spinner.fail('Failed to download template');
|
|
79
|
-
throw error;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
async downloadFromSource(source, licenseKey) {
|
|
83
|
-
switch (source.type) {
|
|
84
|
-
case 'local':
|
|
85
|
-
return this.getLocalTemplate();
|
|
86
|
-
case 'github-zip':
|
|
87
|
-
return this.downloadZip(source.url, {}, source.cacheable);
|
|
88
|
-
case 'protected-url':
|
|
89
|
-
if (!licenseKey) {
|
|
90
|
-
throw new Error('License key required for protected template');
|
|
91
|
-
}
|
|
92
|
-
// For now, simulate license validation
|
|
93
|
-
// In production, this would validate with mvpkit.dev API
|
|
94
|
-
const token = await this.validateLicense(licenseKey);
|
|
95
|
-
return this.downloadZip(source.url, {
|
|
96
|
-
'Authorization': `Bearer ${token}`
|
|
97
|
-
}, false);
|
|
98
|
-
default:
|
|
99
|
-
throw new Error(`Unsupported template source type: ${source.type}`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
async getLocalTemplate() {
|
|
103
|
-
// Use existing local path resolution for development
|
|
104
|
-
const { getCoreRepositoryPath } = await import('./utils.js');
|
|
105
|
-
return getCoreRepositoryPath();
|
|
106
|
-
}
|
|
107
|
-
async downloadZip(url, headers = {}, cacheable = false) {
|
|
108
|
-
// Check cache first if cacheable
|
|
109
|
-
if (cacheable) {
|
|
110
|
-
const cacheKey = this.getCacheKey(url);
|
|
111
|
-
const cachedPath = path.join(this.cacheDir, cacheKey);
|
|
112
|
-
const cacheInfoPath = path.join(this.cacheDir, `${cacheKey}.info`);
|
|
113
|
-
if (fs.existsSync(cachedPath) && fs.existsSync(cacheInfoPath)) {
|
|
114
|
-
// Check if cache is still fresh (4 hours TTL)
|
|
115
|
-
const cacheInfo = JSON.parse(fs.readFileSync(cacheInfoPath, 'utf8'));
|
|
116
|
-
const cacheAge = Date.now() - cacheInfo.timestamp;
|
|
117
|
-
const fourHours = 4 * 60 * 60 * 1000;
|
|
118
|
-
if (cacheAge < fourHours) {
|
|
119
|
-
console.log('Using cached template...');
|
|
120
|
-
return cachedPath;
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
console.log('Cache expired, downloading fresh template...');
|
|
124
|
-
// Clean up expired cache
|
|
125
|
-
fs.removeSync(cachedPath);
|
|
126
|
-
fs.removeSync(cacheInfoPath);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
// Download ZIP file
|
|
131
|
-
const response = await fetch(url, { headers });
|
|
132
|
-
if (!response.ok) {
|
|
133
|
-
throw new Error(`Failed to download template: ${response.status} ${response.statusText}`);
|
|
134
|
-
}
|
|
135
|
-
// Create temporary file for ZIP
|
|
136
|
-
const tempZip = tmp.fileSync({ postfix: '.zip' });
|
|
137
|
-
try {
|
|
138
|
-
// Download to temporary file
|
|
139
|
-
await pipeline(response.body, fs.createWriteStream(tempZip.name));
|
|
140
|
-
// Extract ZIP to temporary directory
|
|
141
|
-
const extractDir = tmp.dirSync({ unsafeCleanup: true });
|
|
142
|
-
await this.extractZip(tempZip.name, extractDir.name);
|
|
143
|
-
// Find the actual template directory (usually core-main/ from GitHub)
|
|
144
|
-
const extractedContents = fs.readdirSync(extractDir.name);
|
|
145
|
-
const templateDir = extractedContents.find(item => {
|
|
146
|
-
const itemPath = path.join(extractDir.name, item);
|
|
147
|
-
return fs.statSync(itemPath).isDirectory();
|
|
148
|
-
});
|
|
149
|
-
if (!templateDir) {
|
|
150
|
-
throw new Error('No template directory found in downloaded ZIP');
|
|
151
|
-
}
|
|
152
|
-
// GitHub repo root IS the template (no core/ subdirectory)
|
|
153
|
-
const finalTemplatePath = path.join(extractDir.name, templateDir);
|
|
154
|
-
// Cache if requested
|
|
155
|
-
if (cacheable) {
|
|
156
|
-
const cacheKey = this.getCacheKey(url);
|
|
157
|
-
const cachedPath = path.join(this.cacheDir, cacheKey);
|
|
158
|
-
const cacheInfoPath = path.join(this.cacheDir, `${cacheKey}.info`);
|
|
159
|
-
await fs.copy(finalTemplatePath, cachedPath);
|
|
160
|
-
await fs.writeFile(cacheInfoPath, JSON.stringify({
|
|
161
|
-
timestamp: Date.now(),
|
|
162
|
-
url: url
|
|
163
|
-
}));
|
|
164
|
-
return cachedPath;
|
|
165
|
-
}
|
|
166
|
-
return finalTemplatePath;
|
|
167
|
-
}
|
|
168
|
-
finally {
|
|
169
|
-
// Cleanup temporary ZIP file
|
|
170
|
-
tempZip.removeCallback();
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
async extractZip(zipPath, extractTo) {
|
|
174
|
-
return new Promise((resolve, reject) => {
|
|
175
|
-
yauzl.open(zipPath, { lazyEntries: true }, (err, zipfile) => {
|
|
176
|
-
if (err)
|
|
177
|
-
return reject(err);
|
|
178
|
-
zipfile.readEntry();
|
|
179
|
-
zipfile.on('entry', (entry) => {
|
|
180
|
-
if (/\/$/.test(entry.fileName)) {
|
|
181
|
-
// Directory entry
|
|
182
|
-
zipfile.readEntry();
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
// File entry
|
|
186
|
-
const outputPath = path.join(extractTo, entry.fileName);
|
|
187
|
-
fs.ensureDirSync(path.dirname(outputPath));
|
|
188
|
-
zipfile.openReadStream(entry, (err, readStream) => {
|
|
189
|
-
if (err)
|
|
190
|
-
return reject(err);
|
|
191
|
-
const writeStream = fs.createWriteStream(outputPath);
|
|
192
|
-
readStream.pipe(writeStream);
|
|
193
|
-
writeStream.on('close', () => zipfile.readEntry());
|
|
194
|
-
writeStream.on('error', reject);
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
zipfile.on('end', resolve);
|
|
199
|
-
zipfile.on('error', reject);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
getCacheKey(url) {
|
|
204
|
-
// Simple cache key from URL
|
|
205
|
-
return url.replace(/[^a-zA-Z0-9]/g, '_');
|
|
206
|
-
}
|
|
207
|
-
async validateLicense(licenseKey) {
|
|
208
|
-
// TODO: Implement proper license validation with mvpkit.dev API
|
|
209
|
-
// For now, use demo validation until API is ready
|
|
210
|
-
if (licenseKey === 'demo') {
|
|
211
|
-
console.log(chalk.yellow('⚠️ Using demo license for testing'));
|
|
212
|
-
return 'mock-jwt-token';
|
|
213
|
-
}
|
|
214
|
-
// In production, validate with API
|
|
215
|
-
try {
|
|
216
|
-
const response = await fetch('https://api.mvpkit.dev/validate-license', {
|
|
217
|
-
method: 'POST',
|
|
218
|
-
headers: { 'Content-Type': 'application/json' },
|
|
219
|
-
body: JSON.stringify({ licenseKey })
|
|
220
|
-
});
|
|
221
|
-
if (!response.ok) {
|
|
222
|
-
throw new Error(`License validation failed: ${response.status}`);
|
|
223
|
-
}
|
|
224
|
-
const result = await response.json();
|
|
225
|
-
return result.token;
|
|
226
|
-
}
|
|
227
|
-
catch (error) {
|
|
228
|
-
throw new Error(`Invalid or expired license key. Visit https://mvpkit.dev to get a license.`);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
listTemplates() {
|
|
232
|
-
console.log(chalk.yellow('🆓 MVPKit Core Template'));
|
|
233
|
-
console.log(chalk.gray('Production-ready React TypeScript starter with Cloudflare Workers'));
|
|
234
|
-
console.log();
|
|
235
|
-
console.log(chalk.yellow('💡 Usage: ') + chalk.cyan('npx @mvp-kit/create my-app'));
|
|
236
|
-
console.log();
|
|
237
|
-
}
|
|
238
|
-
clearCache() {
|
|
239
|
-
if (fs.existsSync(this.cacheDir)) {
|
|
240
|
-
fs.removeSync(this.cacheDir);
|
|
241
|
-
console.log(chalk.green('✅ Template cache cleared'));
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
console.log(chalk.gray('Cache already empty'));
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
//# sourceMappingURL=template-downloader.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"template-downloader.js","sourceRoot":"","sources":["../src/template-downloader.ts"],"names":[],"mappings":"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"}
|