@panoptic-it-solutions/coolify-setup 1.1.14 → 1.1.16

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.
@@ -4,5 +4,6 @@ export interface ProjectInfo {
4
4
  hasDockerfile: boolean;
5
5
  hasDockerCompose: boolean;
6
6
  name: string;
7
+ dbPath: string | null;
7
8
  }
8
9
  export declare function detectProject(): Promise<ProjectInfo>;
package/dist/detector.js CHANGED
@@ -24,11 +24,27 @@ export async function detectProject() {
24
24
  packageManager = 'pnpm';
25
25
  else if (hasYarnLock)
26
26
  packageManager = 'yarn';
27
+ // Detect where migrations are located (check in order of priority)
28
+ const possibleDbPaths = [
29
+ 'src/lib/db', // Already in src/lib/db
30
+ 'lib/db', // Already in lib/db
31
+ 'src/db', // Common with src/ directory
32
+ 'db', // Common without src/
33
+ 'drizzle', // Alternative location
34
+ ];
35
+ let dbPath = null;
36
+ for (const path of possibleDbPaths) {
37
+ if (exists(`${path}/migrations`)) {
38
+ dbPath = path;
39
+ break;
40
+ }
41
+ }
27
42
  return {
28
43
  type: hasNextConfig ? 'nextjs' : 'node',
29
44
  packageManager,
30
45
  hasDockerfile,
31
46
  hasDockerCompose,
32
47
  name: hasPackageJson ? getProjectName() : 'my-project',
48
+ dbPath,
33
49
  };
34
50
  }
@@ -5,5 +5,6 @@ export interface GenerateOptions {
5
5
  includePostgres: boolean;
6
6
  includeRedis: boolean;
7
7
  includeMinio: boolean;
8
+ dbPath: string | null;
8
9
  }
9
10
  export declare function generateFiles(options: GenerateOptions): Promise<void>;
package/dist/generator.js CHANGED
@@ -13,6 +13,12 @@ function writeFile(relativePath, content) {
13
13
  ensureDir(fullPath);
14
14
  writeFileSync(fullPath, content, 'utf-8');
15
15
  }
16
+ // Default dbPath if none detected (for projects without existing migrations)
17
+ function getDefaultDbPath() {
18
+ // If project has src/app, use src/lib/db, otherwise use lib/db
19
+ const srcAppPath = join(process.cwd(), 'src/app');
20
+ return existsSync(srcAppPath) ? 'src/lib/db' : 'lib/db';
21
+ }
16
22
  function addEsbuildToPackageJson(packageManager) {
17
23
  const packageJsonPath = join(process.cwd(), 'package.json');
18
24
  if (!existsSync(packageJsonPath)) {
@@ -47,32 +53,44 @@ function addEsbuildToPackageJson(packageManager) {
47
53
  return false;
48
54
  }
49
55
  }
50
- function copyMigrationsToLibDb() {
56
+ function cleanupOldMigrationFiles(currentDbPath) {
51
57
  const cwd = process.cwd();
52
- const destPath = join(cwd, 'lib/db/migrations');
53
- // Skip if destination already exists
54
- if (existsSync(destPath)) {
55
- return false;
56
- }
57
- // Source directories to check (in order of priority)
58
- const sourceRoots = ['db', 'src/db'];
59
- for (const sourceRoot of sourceRoots) {
60
- const sourcePath = join(cwd, sourceRoot, 'migrations');
61
- if (existsSync(sourcePath)) {
62
- // Ensure lib/db directory exists
63
- ensureDir(join(destPath, 'dummy'));
64
- // Copy (not move) to preserve source imports
65
- execSync(`cp -r "${sourcePath}/." "${destPath}"`, { stdio: 'pipe' });
66
- console.log(`Copied ${sourceRoot}/migrations → lib/db/migrations`);
67
- return true;
58
+ const { unlinkSync, readdirSync, rmSync } = require('fs');
59
+ // Possible locations where we might have created files in previous runs
60
+ const possibleOldPaths = [
61
+ 'lib/db',
62
+ 'src/lib/db',
63
+ ];
64
+ for (const oldPath of possibleOldPaths) {
65
+ // Skip if this is the current path
66
+ if (oldPath === currentDbPath)
67
+ continue;
68
+ const oldMigratePath = join(cwd, oldPath, 'migrate.ts');
69
+ const oldMigrationsPath = join(cwd, oldPath, 'migrations');
70
+ // Remove old migrate.ts if it exists
71
+ if (existsSync(oldMigratePath)) {
72
+ unlinkSync(oldMigratePath);
73
+ console.log(`Removed old ${oldPath}/migrate.ts`);
74
+ }
75
+ // Remove old migrations folder if it's a folder we created (check if parent only contains our files)
76
+ if (existsSync(oldMigrationsPath)) {
77
+ const parentPath = join(cwd, oldPath);
78
+ try {
79
+ const contents = readdirSync(parentPath);
80
+ // Only remove if directory only contains migrations and/or migrate.ts (our files)
81
+ const isOurFolder = contents.every((f) => f === 'migrations' || f === 'migrate.ts' || f === 'migrate.bundle.js');
82
+ if (isOurFolder) {
83
+ rmSync(parentPath, { recursive: true, force: true });
84
+ console.log(`Removed old ${oldPath}/ folder`);
85
+ }
86
+ }
87
+ catch {
88
+ // Ignore errors during cleanup
89
+ }
68
90
  }
69
91
  }
70
- // No migrations found - create empty folder so Docker build doesn't fail
71
- ensureDir(join(destPath, 'dummy'));
72
- console.log('Created empty lib/db/migrations (no source migrations found)');
73
- return true;
74
92
  }
75
- function excludeMigrateFromTsConfig(migratePath) {
93
+ function updateTsConfigExcludes(newMigratePath) {
76
94
  const tsconfigPath = join(process.cwd(), 'tsconfig.json');
77
95
  if (!existsSync(tsconfigPath)) {
78
96
  console.log('Warning: tsconfig.json not found, skipping exclusion');
@@ -84,13 +102,26 @@ function excludeMigrateFromTsConfig(migratePath) {
84
102
  if (!tsconfig.exclude) {
85
103
  tsconfig.exclude = ['node_modules'];
86
104
  }
87
- // Add migrate.ts to exclude if not already present
88
- if (!tsconfig.exclude.includes(migratePath)) {
89
- tsconfig.exclude.push(migratePath);
105
+ // Old paths to remove from previous runs
106
+ const oldPaths = ['lib/db/migrate.ts', 'src/lib/db/migrate.ts'];
107
+ let modified = false;
108
+ // Remove old paths that are no longer used
109
+ for (const oldPath of oldPaths) {
110
+ const index = tsconfig.exclude.indexOf(oldPath);
111
+ if (index !== -1 && oldPath !== newMigratePath) {
112
+ tsconfig.exclude.splice(index, 1);
113
+ modified = true;
114
+ }
115
+ }
116
+ // Add new path if not already present
117
+ if (!tsconfig.exclude.includes(newMigratePath)) {
118
+ tsconfig.exclude.push(newMigratePath);
119
+ modified = true;
120
+ }
121
+ if (modified) {
90
122
  writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n', 'utf-8');
91
- return true;
92
123
  }
93
- return false;
124
+ return modified;
94
125
  }
95
126
  catch (error) {
96
127
  console.log('Warning: Failed to update tsconfig.json:', error);
@@ -98,12 +129,15 @@ function excludeMigrateFromTsConfig(migratePath) {
98
129
  }
99
130
  }
100
131
  export async function generateFiles(options) {
101
- const { projectName, projectType, packageManager, includePostgres, includeRedis, includeMinio, } = options;
132
+ const { projectName, projectType, packageManager, includePostgres, includeRedis, includeMinio, dbPath: detectedDbPath, } = options;
133
+ // Use detected dbPath or fall back to default based on project structure
134
+ const dbPath = detectedDbPath ?? getDefaultDbPath();
102
135
  // Generate Dockerfile
103
136
  const dockerfile = generateDockerfile({
104
137
  projectType,
105
138
  packageManager,
106
139
  includePostgres,
140
+ dbPath,
107
141
  });
108
142
  writeFile('Dockerfile', dockerfile);
109
143
  // Generate docker-compose.yml
@@ -128,6 +162,7 @@ export async function generateFiles(options) {
128
162
  const entrypoint = generateEntrypoint({
129
163
  projectType,
130
164
  includePostgres,
165
+ dbPath,
131
166
  });
132
167
  writeFile('entrypoint.sh', entrypoint);
133
168
  // Generate Claude rules
@@ -135,29 +170,33 @@ export async function generateFiles(options) {
135
170
  writeFile('.claude/rules/coolify.md', claudeRules);
136
171
  // Generate migrate.ts if postgres is included
137
172
  if (includePostgres) {
138
- const migrateScript = generateMigrateScript({ projectType });
139
173
  // For Next.js standalone projects, we need esbuild to bundle the migration script
140
174
  if (projectType === 'nextjs') {
141
175
  const added = addEsbuildToPackageJson(packageManager);
142
176
  if (added) {
143
177
  console.log('Added esbuild to devDependencies (required for migration bundling)');
144
178
  }
145
- // Copy migrations to lib/db/ for Docker build (don't move - preserve source imports)
146
- copyMigrationsToLibDb();
147
- // Write migrate.ts to lib/db/ for Next.js projects (will be bundled at build time)
148
- const migratePath = 'lib/db/migrate.ts';
149
- const existingMigratePath = join(process.cwd(), migratePath);
150
- if (!existsSync(existingMigratePath)) {
151
- writeFile(migratePath, migrateScript);
179
+ // Clean up old files from previous runs (if dbPath changed)
180
+ cleanupOldMigrationFiles(dbPath);
181
+ // Create empty migrations folder if none exists
182
+ const migrationsPath = join(process.cwd(), dbPath, 'migrations');
183
+ if (!existsSync(migrationsPath)) {
184
+ ensureDir(join(migrationsPath, 'dummy'));
185
+ console.log(`Created empty ${dbPath}/migrations folder`);
152
186
  }
153
- // Exclude migrate.ts from TypeScript compilation (it's bundled separately by esbuild)
154
- const excluded = excludeMigrateFromTsConfig(migratePath);
155
- if (excluded) {
156
- console.log('Added lib/db/migrate.ts to tsconfig.json exclude (bundled separately)');
187
+ // Always write migrate.ts (overwrites previous version to handle updates)
188
+ const migrateScript = generateMigrateScript({ projectType, dbPath });
189
+ const migratePath = `${dbPath}/migrate.ts`;
190
+ writeFile(migratePath, migrateScript);
191
+ // Update tsconfig.json excludes (removes old paths, adds new)
192
+ const updated = updateTsConfigExcludes(migratePath);
193
+ if (updated) {
194
+ console.log(`Updated tsconfig.json exclude for ${migratePath}`);
157
195
  }
158
196
  }
159
197
  else {
160
198
  // For Node.js projects, write to scripts/ directory
199
+ const migrateScript = generateMigrateScript({ projectType, dbPath });
161
200
  writeFile('scripts/migrate.ts', migrateScript);
162
201
  }
163
202
  }
package/dist/index.js CHANGED
@@ -64,6 +64,7 @@ async function main() {
64
64
  includePostgres: response.includePostgres,
65
65
  includeRedis: response.includeRedis,
66
66
  includeMinio: response.includeMinio,
67
+ dbPath: project.dbPath,
67
68
  });
68
69
  // Track generated files for commit
69
70
  const generatedFiles = [
@@ -85,11 +86,12 @@ async function main() {
85
86
  else {
86
87
  generatedFiles.push('package-lock.json');
87
88
  }
88
- // Add migrate script and db folder if postgres included
89
+ // Add migrate script if postgres included
89
90
  if (response.includePostgres) {
90
91
  if (project.type === 'nextjs') {
91
- generatedFiles.push('lib/db/migrate.ts');
92
- generatedFiles.push('lib/db/migrations/'); // Include copied migrations folder
92
+ // Use detected dbPath, or fall back to default based on project structure
93
+ const dbPath = project.dbPath ?? (project.type === 'nextjs' ? 'lib/db' : 'db');
94
+ generatedFiles.push(`${dbPath}/migrate.ts`);
93
95
  generatedFiles.push('tsconfig.json'); // May be modified with exclude
94
96
  }
95
97
  else {
@@ -104,7 +106,8 @@ async function main() {
104
106
  console.log(chalk.green(' ✓ entrypoint.sh'));
105
107
  if (response.includePostgres) {
106
108
  if (project.type === 'nextjs') {
107
- console.log(chalk.green('lib/db/migrate.ts'));
109
+ const dbPath = project.dbPath ?? 'lib/db';
110
+ console.log(chalk.green(` ✓ ${dbPath}/migrate.ts`));
108
111
  }
109
112
  else {
110
113
  console.log(chalk.green(' ✓ scripts/migrate.ts'));
@@ -2,5 +2,6 @@ export interface DockerfileOptions {
2
2
  projectType: 'nextjs' | 'node';
3
3
  packageManager: 'pnpm' | 'npm' | 'yarn';
4
4
  includePostgres: boolean;
5
+ dbPath: string;
5
6
  }
6
7
  export declare function generateDockerfile(options: DockerfileOptions): string;
@@ -5,7 +5,7 @@ export function generateDockerfile(options) {
5
5
  return generateNodeDockerfile(options);
6
6
  }
7
7
  function generateNextjsDockerfile(options) {
8
- const { packageManager, includePostgres } = options;
8
+ const { packageManager, includePostgres, dbPath } = options;
9
9
  const installCmd = packageManager === 'pnpm'
10
10
  ? 'pnpm install --frozen-lockfile'
11
11
  : packageManager === 'yarn'
@@ -39,12 +39,12 @@ function generateNextjsDockerfile(options) {
39
39
  # Build the migration bundle (single JS file with all deps baked in)
40
40
  # This avoids module resolution issues in the standalone container
41
41
  # postgres is externalized and copied separately due to pnpm symlink resolution issues
42
- RUN ${esbuildCmd} lib/db/migrate.ts --bundle --platform=node --target=node22 --outfile=lib/db/migrate.bundle.js --external:dotenv --external:postgres` : '';
42
+ RUN ${esbuildCmd} ${dbPath}/migrate.ts --bundle --platform=node --target=node22 --outfile=${dbPath}/migrate.bundle.js --external:dotenv --external:postgres` : '';
43
43
  const migrationCopy = includePostgres ? `
44
44
 
45
45
  # Copy database migrations and bundled migration script
46
- COPY --from=builder --chown=nextjs:nodejs /app/lib/db/migrations ./lib/db/migrations
47
- COPY --from=builder --chown=nextjs:nodejs /app/lib/db/migrate.bundle.js ./lib/db/migrate.bundle.js
46
+ COPY --from=builder --chown=nextjs:nodejs /app/${dbPath}/migrations ./${dbPath}/migrations
47
+ COPY --from=builder --chown=nextjs:nodejs /app/${dbPath}/migrate.bundle.js ./${dbPath}/migrate.bundle.js
48
48
 
49
49
  # Copy postgres module for migration script (externalized from bundle due to pnpm symlinks)
50
50
  COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.pnpm/postgres@*/node_modules/postgres ./node_modules/postgres` : '';
@@ -135,7 +135,7 @@ CMD ["./entrypoint.sh"]
135
135
  `;
136
136
  }
137
137
  function generateNodeDockerfile(options) {
138
- const { packageManager, includePostgres } = options;
138
+ const { packageManager, includePostgres, dbPath } = options;
139
139
  const installCmd = packageManager === 'pnpm'
140
140
  ? 'pnpm install --frozen-lockfile --prod'
141
141
  : packageManager === 'yarn'
@@ -153,8 +153,8 @@ function generateNodeDockerfile(options) {
153
153
  : '';
154
154
  const migrationCopy = includePostgres ? `
155
155
  # Copy migration files
156
- COPY --chown=node:node lib/db/migrations ./scripts/migrations
157
- COPY --chown=node:node lib/db/migrate.ts ./scripts/migrate.ts` : '';
156
+ COPY --chown=node:node ${dbPath}/migrations ./scripts/migrations
157
+ COPY --chown=node:node ${dbPath}/migrate.ts ./scripts/migrate.ts` : '';
158
158
  const tsxInstall = includePostgres ? `
159
159
  # Install tsx globally for running TypeScript migration scripts
160
160
  RUN npm install -g tsx` : '';
@@ -1,5 +1,6 @@
1
1
  export interface EntrypointOptions {
2
2
  projectType: 'nextjs' | 'node';
3
3
  includePostgres: boolean;
4
+ dbPath: string;
4
5
  }
5
6
  export declare function generateEntrypoint(options: EntrypointOptions): string;
@@ -1,5 +1,5 @@
1
1
  export function generateEntrypoint(options) {
2
- const { projectType, includePostgres } = options;
2
+ const { projectType, includePostgres, dbPath } = options;
3
3
  // For Next.js standalone, we run the bundled JS file (no tsx needed)
4
4
  // For Node.js, we use tsx since full node_modules is available
5
5
  const migrationStep = includePostgres
@@ -7,7 +7,7 @@ export function generateEntrypoint(options) {
7
7
  ? `
8
8
  # Run database migrations (bundled JS with all deps baked in)
9
9
  echo "⏳ Running database migrations..."
10
- node lib/db/migrate.bundle.js
10
+ node ${dbPath}/migrate.bundle.js
11
11
  `
12
12
  : `
13
13
  # Run database migrations
@@ -1,4 +1,5 @@
1
1
  export interface MigrateScriptOptions {
2
2
  projectType: 'nextjs' | 'node';
3
+ dbPath: string;
3
4
  }
4
- export declare function generateMigrateScript(options?: MigrateScriptOptions): string;
5
+ export declare function generateMigrateScript(options: MigrateScriptOptions): string;
@@ -1,9 +1,9 @@
1
1
  export function generateMigrateScript(options) {
2
- const projectType = options?.projectType ?? 'nextjs';
3
- // For Next.js, migrations are in lib/db/migrations (bundled with esbuild)
4
- // For Node.js, migrations are in scripts/migrations (run with tsx)
2
+ const { projectType, dbPath } = options;
3
+ // For Next.js, migrations are in the detected dbPath (e.g., src/db, lib/db, etc.)
4
+ // For Node.js, migrations are copied to scripts/migrations (run with tsx)
5
5
  const migrationsFolder = projectType === 'nextjs'
6
- ? './lib/db/migrations'
6
+ ? `./${dbPath}/migrations`
7
7
  : './scripts/migrations';
8
8
  return `import { drizzle } from 'drizzle-orm/postgres-js';
9
9
  import { migrate } from 'drizzle-orm/postgres-js/migrator';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoptic-it-solutions/coolify-setup",
3
- "version": "1.1.14",
3
+ "version": "1.1.16",
4
4
  "description": "CLI tool for setting up Coolify deployment on Panoptic projects",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",