CDK for software projects - synthesizes configuration files from well-typed JavaScript/TypeScript definitions.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Abstract file system for managing configuration files, source code, and generated content. Projen provides a comprehensive file management system that handles different file types with synthesis markers and read-only protection.
Abstract base class for all file types in projen, providing common file operations and synthesis lifecycle.
/**
* Base class for all file types in projen
* Provides common file operations and synthesis lifecycle
*/
abstract class FileBase extends Component {
constructor(scope: IConstruct, filePath: string, options?: FileBaseOptions);
/** Relative file path from project root */
readonly path: string;
/** Absolute file path on disk */
readonly absolutePath: string;
/** Whether the file is read-only (has projen marker) */
readonly readonly: boolean;
/** Whether the file has executable permissions */
readonly executable: boolean;
/** Projen marker text (null if not a generated file) */
readonly marker?: string;
/** Called during synthesis to write file content */
protected abstract synthesizeContent(resolver: IResolver): string | undefined;
}
interface FileBaseOptions {
/** Whether the file is read-only (default: true for generated files) */
readonly?: boolean;
/** Whether the file should be executable */
executable?: boolean;
/** Custom marker text for generated files */
marker?: string;
/** Whether to commit this file to git */
committed?: boolean;
}JSON file management with object manipulation and projen marker support.
/**
* Represents a JSON file with projen marker support
* Provides object-based manipulation of JSON content
*/
class JsonFile extends ObjectFile {
constructor(scope: IConstruct, filePath: string, options?: JsonFileOptions);
/** The JSON object content */
readonly obj: any;
/** Add or update a property in the JSON object */
addOverride(path: string, value: any): void;
/** Add to an array property */
addToArray(path: string, ...values: any[]): void;
/** Remove a property from the JSON object */
removeProperty(path: string): void;
/** Get a property value */
getProperty(path: string): any;
}
interface JsonFileOptions extends ObjectFileOptions {
/** JSON object content */
obj?: any;
/** Custom JSON formatting options */
formatting?: JsonFormattingOptions;
}
interface JsonFormattingOptions {
/** Number of spaces for indentation (default: 2) */
indent?: number;
/** Whether to add trailing newline */
newline?: boolean;
}JSON File Example:
import { Project, JsonFile } from "projen";
const project = new Project({ name: "json-example" });
// Create package.json
const packageJson = new JsonFile(project, "package.json", {
obj: {
name: "my-package",
version: "1.0.0",
main: "index.js",
scripts: {},
dependencies: {},
},
});
// Modify JSON content
packageJson.addOverride("scripts.build", "tsc");
packageJson.addOverride("scripts.test", "jest");
packageJson.addToArray("keywords", "typescript", "projen");
// Add nested properties
packageJson.addOverride("author.name", "Jane Developer");
packageJson.addOverride("author.email", "jane@example.com");
// Remove properties
packageJson.removeProperty("main");YAML file management with object manipulation.
/**
* Represents a YAML file with projen marker support
* Provides object-based manipulation of YAML content
*/
class YamlFile extends ObjectFile {
constructor(scope: IConstruct, filePath: string, options?: YamlFileOptions);
/** The YAML object content */
readonly obj: any;
/** Add or update a property in the YAML object */
addOverride(path: string, value: any): void;
/** Add to an array property */
addToArray(path: string, ...values: any[]): void;
}
interface YamlFileOptions extends ObjectFileOptions {
/** YAML object content */
obj?: any;
/** Line width for YAML formatting */
lineWidth?: number;
/** Whether to use flow style for sequences */
flowSequences?: boolean;
}YAML File Example:
import { Project, YamlFile } from "projen";
const project = new Project({ name: "yaml-example" });
// Create GitHub workflow
const workflow = new YamlFile(project, ".github/workflows/ci.yml", {
obj: {
name: "CI",
on: {
push: { branches: ["main"] },
pull_request: { branches: ["main"] },
},
jobs: {
test: {
"runs-on": "ubuntu-latest",
steps: [],
},
},
},
});
// Add steps to workflow
workflow.addToArray("jobs.test.steps", {
uses: "actions/checkout@v3",
});
workflow.addToArray("jobs.test.steps", {
uses: "actions/setup-node@v3",
with: {
"node-version": "18",
},
});Plain text file management with line-based manipulation.
/**
* Plain text file with line-based manipulation
* Suitable for configuration files, source code, and documentation
*/
class TextFile extends FileBase {
constructor(scope: IConstruct, filePath: string, options?: TextFileOptions);
/** All lines in the file */
readonly lines: string[];
/** Add a line to the file */
addLine(line: string): void;
/** Add multiple lines to the file */
addLines(...lines: string[]): void;
/** Insert a line at specific position */
insertLine(index: number, line: string): void;
/** Remove a line by content */
removeLine(line: string): void;
/** Remove a line by index */
removeLineAt(index: number): void;
/** Check if file contains a line */
hasLine(line: string): boolean;
}
interface TextFileOptions extends FileBaseOptions {
/** Initial lines for the file */
lines?: string[];
/** Line ending style */
lineEnding?: LineEnding;
}
enum LineEnding {
/** Unix line endings (\n) */
LF = "lf",
/** Windows line endings (\r\n) */
CRLF = "crlf",
/** Automatic based on platform */
AUTO = "auto"
}Text File Example:
import { Project, TextFile } from "projen";
const project = new Project({ name: "text-example" });
// Create .gitignore file
const gitignore = new TextFile(project, ".gitignore", {
lines: [
"node_modules/",
"*.log",
".env",
],
});
// Add more patterns
gitignore.addLine("dist/");
gitignore.addLine("coverage/");
gitignore.addLines(
"# IDE files",
".vscode/",
".idea/",
);
// Create README
const readme = new TextFile(project, "README.md", {
lines: [
"# My Project",
"",
"Description of my project.",
],
});
readme.addLines(
"",
"## Installation",
"",
"```bash",
"npm install",
"```",
);Sample code files that are only created if they don't exist.
/**
* Sample code files that are only created if they don't already exist
* Used for generating example code and configuration templates
*/
class SampleFile extends FileBase {
constructor(scope: IConstruct, filePath: string, options?: SampleFileOptions);
/** File content */
readonly content: string;
}
interface SampleFileOptions extends FileBaseOptions {
/** File content */
content: string;
/** Source file to copy from */
sourcePath?: string;
}Sample File Example:
import { TypeScriptProject, SampleFile } from "projen";
const project = new TypeScriptProject({
name: "sample-example",
sampleCode: false, // Disable automatic samples
});
// Create custom sample files
new SampleFile(project, "src/hello.ts", {
content: `export function hello(name: string): string {
return \`Hello, \${name}!\`;
}
`,
});
new SampleFile(project, "test/hello.test.ts", {
content: `import { hello } from '../src/hello';
describe('hello', () => {
test('should greet correctly', () => {
expect(hello('World')).toBe('Hello, World!');
});
});
`,
});
// Sample configuration file
new SampleFile(project, ".env.example", {
content: `# Environment variables
API_KEY=your_api_key_here
DATABASE_URL=postgresql://localhost:5432/mydb
`,
});Manages ignore pattern files like .gitignore, .npmignore.
/**
* Manages ignore pattern files (.gitignore, .npmignore, etc.)
* Provides pattern-based file exclusion functionality
*/
class IgnoreFile extends TextFile {
constructor(scope: IConstruct, filePath: string, options?: IgnoreFileOptions);
/** Add ignore pattern */
addPattern(pattern: string): void;
/** Add multiple ignore patterns */
addPatterns(...patterns: string[]): void;
/** Remove ignore pattern */
removePattern(pattern: string): void;
/** Check if pattern exists */
hasPattern(pattern: string): boolean;
/** Add comment */
addComment(comment: string): void;
}
interface IgnoreFileOptions extends TextFileOptions {
/** Initial ignore patterns */
ignorePatterns?: string[];
}Ignore File Example:
import { Project, IgnoreFile } from "projen";
const project = new Project({ name: "ignore-example" });
// Create custom .gitignore
const gitignore = new IgnoreFile(project, ".gitignore", {
ignorePatterns: [
"node_modules/",
"*.log",
],
});
gitignore.addComment("Build artifacts");
gitignore.addPatterns(
"dist/",
"build/",
"lib/",
);
gitignore.addComment("Environment files");
gitignore.addPattern(".env*");
// Create .dockerignore
const dockerignore = new IgnoreFile(project, ".dockerignore", {
ignorePatterns: [
"node_modules/",
".git/",
"README.md",
"Dockerfile",
".dockerignore",
],
});Base class for files that represent structured objects (JSON, YAML, etc.).
/**
* Base class for files that represent structured objects
* Provides common functionality for JSON, YAML, and other object files
*/
abstract class ObjectFile extends FileBase {
constructor(scope: IConstruct, filePath: string, options?: ObjectFileOptions);
/** The object content */
readonly obj: any;
/** Add or update a property using dot notation */
addOverride(path: string, value: any): void;
/** Remove a property using dot notation */
removeProperty(path: string): void;
/** Get a property value using dot notation */
getProperty(path: string): any;
/** Check if property exists */
hasProperty(path: string): boolean;
/** Add to array property */
addToArray(path: string, ...values: any[]): void;
/** Merge object into property */
mergeObject(path: string, obj: any): void;
}
interface ObjectFileOptions extends FileBaseOptions {
/** Initial object content */
obj?: any;
/** Whether to omit empty values */
omitEmpty?: boolean;
}interface IResolver {
/** Resolve tokens in content */
resolve(obj: any): any;
}
interface FileSystemOptions {
/** Base directory for file operations */
baseDir?: string;
/** Default file permissions */
defaultPermissions?: string;
/** Whether to create directories automatically */
autoCreateDirs?: boolean;
}
enum FileType {
TEXT = "text",
JSON = "json",
YAML = "yaml",
BINARY = "binary"
}