@panoptic-it-solutions/coolify-setup 1.1.15 → 1.1.17

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