@foxframework/core
Version:
A modern, production-ready web framework for TypeScript/Node.js with modular routing, integrated template engine, CLI tools, and enterprise features
248 lines (239 loc) • 7.42 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.DockfileGenerator = void 0;
const path = __importStar(require("path"));
const base_generator_1 = require("./base.generator");
/**
* Dockfile generator - Generate optimized container files
*/
class DockfileGenerator extends base_generator_1.BaseGenerator {
constructor() {
super(...arguments);
this.name = 'dockfile';
this.description = 'Generate optimized container files';
}
async generate(context) {
const { options, projectRoot } = context;
const config = this.getDockConfig(context);
console.log('📦 Generating container configuration...');
try {
// Generate Dockerfile
const containerfile = await this.generateContainerfile(config, options);
const containerfilePath = path.join(projectRoot, 'Dockerfile');
// Generate .dockerignore
const containerignore = await this.generateContainerignore();
const containerignorePath = path.join(projectRoot, '.dockerignore');
const files = [
{
path: containerfilePath,
content: containerfile,
action: 'create'
},
{
path: containerignorePath,
content: containerignore,
action: 'create'
}
];
// Generate multi-stage Dockerfile if requested
if (options.multistage) {
const multistageContainerfile = await this.generateMultistageContainerfile(config, options);
files.push({
path: path.join(projectRoot, 'Dockerfile.multistage'),
content: multistageContainerfile,
action: 'create'
});
}
return files;
}
catch (error) {
console.error('Error in container file generation:', error);
throw error;
}
}
/**
* Generate standard Dockerfile
*/
async generateContainerfile(config, options) {
const templateName = this.getContainerfileTemplate(options);
const variables = {
baseImage: config.baseImage,
nodeVersion: config.nodeVersion,
workdir: config.workdir,
port: config.port,
user: config.user || 'node',
healthCheck: config.healthCheck,
environment: config.environment || {},
volumes: config.volumes || [],
hasTypeScript: this.hasTypeScript(),
hasTests: this.hasTests(),
production: options.production || false
};
return this.renderTemplate(templateName, variables);
}
/**
* Generate multi-stage Dockerfile
*/
async generateMultistageContainerfile(config, options) {
const variables = {
baseImage: config.baseImage,
nodeVersion: config.nodeVersion,
workdir: config.workdir,
port: config.port,
user: config.user || 'node',
healthCheck: config.healthCheck,
environment: config.environment || {},
hasTypeScript: this.hasTypeScript(),
hasTests: this.hasTests()
};
return this.renderTemplate('docker/dockerfile/multistage.hbs', variables);
}
/**
* Generate .dockerignore file
*/
async generateContainerignore() {
return `# Dependencies
node_modules/
npm-debug.log*
# Development files
*.log
.env.local
.env.development.local
.env.test.local
.env.production.local
# Build output
dist/
build/
.next/
# IDE files
.vscode/
.idea/
*.swp
*.swo
# OS files
.DS_Store
Thumbs.db
# Git
.git/
.gitignore
# Container files
Dockerfile*
docker-compose*.yml
.dockerignore
# Tests
coverage/
.nyc_output/
# Misc
README.md
LICENSE
docs/`;
}
/**
* Get appropriate Dockerfile template
*/
getContainerfileTemplate(options) {
if (options.alpine) {
return 'docker/dockerfile/node.alpine.hbs';
}
return 'docker/dockerfile/node.ubuntu.hbs';
}
/**
* Get container configuration from context
*/
getDockConfig(context) {
if (context.dockerConfig?.dockerfile) {
return context.dockerConfig.dockerfile;
}
const packageJson = this.readPackageJson(context.projectRoot);
return {
baseImage: 'node',
nodeVersion: '18-alpine',
workdir: '/app',
port: 3000,
healthCheck: {
test: ['CMD', 'curl', '-f', 'http://localhost:3000/health'],
interval: '30s',
timeout: '10s',
retries: 3,
start_period: '40s'
},
user: 'node',
environment: {
NODE_ENV: 'production'
}
};
}
/**
* Check if project uses TypeScript
*/
hasTypeScript() {
try {
const tsConfigPath = path.join(process.cwd(), 'tsconfig.json');
require('fs').accessSync(tsConfigPath);
return true;
}
catch {
return false;
}
}
/**
* Check if project has tests
*/
hasTests() {
try {
const jestConfigPath = path.join(process.cwd(), 'jest.config.ts');
require('fs').accessSync(jestConfigPath);
return true;
}
catch {
return false;
}
}
/**
* Read package.json
*/
readPackageJson(projectRoot) {
try {
const packagePath = path.join(projectRoot, 'package.json');
const content = require('fs').readFileSync(packagePath, 'utf8');
return JSON.parse(content);
}
catch {
return { name: 'fox-app', version: '1.0.0' };
}
}
}
exports.DockfileGenerator = DockfileGenerator;
;