@kurly-growth/growthman 0.1.17 → 0.1.19

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.
Files changed (2) hide show
  1. package/bin/cli.js +85 -31
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -7,8 +7,9 @@ const os = require('os');
7
7
 
8
8
  const packageDir = path.resolve(__dirname, '..');
9
9
 
10
- // 사용자 홈 디렉토리에 데이터 저장
10
+ // 사용자 홈 디렉토리에 앱 및 데이터 저장
11
11
  const dataDir = path.join(os.homedir(), '.growthman');
12
+ const appDir = path.join(dataDir, 'app');
12
13
  const dbPath = path.join(dataDir, 'data.db');
13
14
 
14
15
  // 데이터 디렉토리 생성
@@ -16,6 +17,53 @@ if (!fs.existsSync(dataDir)) {
16
17
  fs.mkdirSync(dataDir, { recursive: true });
17
18
  }
18
19
 
20
+ // 패키지 버전 확인
21
+ const pkgJson = require(path.join(packageDir, 'package.json'));
22
+ const versionFile = path.join(appDir, '.version');
23
+ const currentVersion = pkgJson.version;
24
+ const installedVersion = fs.existsSync(versionFile)
25
+ ? fs.readFileSync(versionFile, 'utf-8').trim()
26
+ : null;
27
+
28
+ // 앱 파일 복사 (버전이 다르거나 없으면)
29
+ if (installedVersion !== currentVersion) {
30
+ console.log(`Installing growthman v${currentVersion}...`);
31
+
32
+ // 기존 앱 폴더 삭제
33
+ if (fs.existsSync(appDir)) {
34
+ fs.rmSync(appDir, { recursive: true });
35
+ }
36
+ fs.mkdirSync(appDir, { recursive: true });
37
+
38
+ // 제외할 파일/폴더 (나머지는 모두 복사)
39
+ const excludes = [
40
+ 'node_modules',
41
+ '.next',
42
+ '.git',
43
+ '.env',
44
+ '.env.local',
45
+ 'generated',
46
+ '.DS_Store',
47
+ ];
48
+
49
+ for (const file of fs.readdirSync(packageDir)) {
50
+ if (excludes.includes(file)) continue;
51
+ const src = path.join(packageDir, file);
52
+ const dest = path.join(appDir, file);
53
+ copyRecursive(src, dest);
54
+ }
55
+
56
+ // 버전 파일 생성
57
+ fs.writeFileSync(versionFile, currentVersion);
58
+
59
+ // 의존성 설치
60
+ console.log('Installing dependencies...');
61
+ execSync('npm install --legacy-peer-deps', {
62
+ cwd: appDir,
63
+ stdio: 'inherit',
64
+ });
65
+ }
66
+
19
67
  // 환경변수 설정
20
68
  const env = {
21
69
  ...process.env,
@@ -23,48 +71,41 @@ const env = {
23
71
  };
24
72
 
25
73
  // CLI 바이너리 경로 찾기
26
- function getBinPath(packageName, binName) {
74
+ function getBinPath(binName) {
75
+ const binPath = path.join(appDir, 'node_modules', '.bin', binName);
76
+ if (fs.existsSync(binPath)) {
77
+ return binPath;
78
+ }
79
+ // fallback: package.json에서 찾기
27
80
  try {
28
- const pkgJsonPath = require.resolve(`${packageName}/package.json`, {
29
- paths: [packageDir],
30
- });
31
- const pkgDir = path.dirname(pkgJsonPath);
32
- const pkgJson = require(pkgJsonPath);
33
-
34
- let binRelPath;
35
- if (typeof pkgJson.bin === 'string') {
36
- binRelPath = pkgJson.bin;
37
- } else if (pkgJson.bin && pkgJson.bin[binName]) {
38
- binRelPath = pkgJson.bin[binName];
39
- }
40
-
41
- if (binRelPath) {
42
- return path.join(pkgDir, binRelPath);
81
+ const pkgJsonPath = path.join(appDir, 'node_modules', binName, 'package.json');
82
+ const pkg = require(pkgJsonPath);
83
+ if (pkg.bin) {
84
+ const binRelPath = typeof pkg.bin === 'string' ? pkg.bin : pkg.bin[binName];
85
+ return path.join(appDir, 'node_modules', binName, binRelPath);
43
86
  }
44
- } catch (e) {
45
- // fallback to node_modules/.bin
46
- }
47
- return path.join(packageDir, 'node_modules', '.bin', binName);
87
+ } catch (e) {}
88
+ return binPath;
48
89
  }
49
90
 
50
91
  // DB가 없으면 생성
51
92
  if (!fs.existsSync(dbPath)) {
52
93
  console.log('Initializing database...');
53
- const prismaPath = getBinPath('prisma', 'prisma');
94
+ const prismaPath = getBinPath('prisma');
54
95
  execSync(`node "${prismaPath}" db push`, {
55
- cwd: packageDir,
96
+ cwd: appDir,
56
97
  stdio: 'inherit',
57
98
  env,
58
99
  });
59
100
  }
60
101
 
61
- // .next 폴더가 없으면 빌드 (Turbopack은 node_modules 내 TS 파일을 지원하지 않음)
62
- const nextDir = path.join(packageDir, '.next');
102
+ // .next 폴더가 없으면 빌드
103
+ const nextDir = path.join(appDir, '.next');
63
104
  if (!fs.existsSync(nextDir)) {
64
- console.log('Building application (first run)...');
65
- const nextPath = getBinPath('next', 'next');
66
- execSync(`node "${nextPath}" build --webpack`, {
67
- cwd: packageDir,
105
+ console.log('Building application...');
106
+ const nextPath = getBinPath('next');
107
+ execSync(`node "${nextPath}" build`, {
108
+ cwd: appDir,
68
109
  stdio: 'inherit',
69
110
  env,
70
111
  });
@@ -76,9 +117,9 @@ const url = `http://localhost:${port}`;
76
117
  console.log(`Database: ${dbPath}`);
77
118
  console.log(`Starting mock server at ${url}`);
78
119
 
79
- const nextPath = getBinPath('next', 'next');
120
+ const nextPath = getBinPath('next');
80
121
  const server = spawn('node', [nextPath, 'start', '-p', String(port)], {
81
- cwd: packageDir,
122
+ cwd: appDir,
82
123
  stdio: 'inherit',
83
124
  env,
84
125
  });
@@ -97,3 +138,16 @@ setTimeout(() => {
97
138
  server.on('close', (code) => {
98
139
  process.exit(code);
99
140
  });
141
+
142
+ // 재귀적 파일 복사
143
+ function copyRecursive(src, dest) {
144
+ const stat = fs.statSync(src);
145
+ if (stat.isDirectory()) {
146
+ fs.mkdirSync(dest, { recursive: true });
147
+ for (const file of fs.readdirSync(src)) {
148
+ copyRecursive(path.join(src, file), path.join(dest, file));
149
+ }
150
+ } else {
151
+ fs.copyFileSync(src, dest);
152
+ }
153
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurly-growth/growthman",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Local mock API server with UI dashboard",
5
5
  "bin": {
6
6
  "growthman": "./bin/cli.js"