Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

print-project

Package Overview
Dependencies
Maintainers
0
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

print-project - npm Package Compare versions

Comparing version 1.0.8 to 1.0.10

43

dist/constants.js

@@ -5,6 +5,41 @@ "use strict";

exports.defaultIgnorePatterns = [
"node_modules", "*.log", "dist", "coverage", "documentation", ".prettierrc", ".gitignore", "dist",
"scripts", ".serverless", ".idea", ".git", ".DS_Store", ".husky", "package-lock.json", ".vscode",
"*.env", "*.bak", "*.tmp", "*.swp", ".eslintcache", ".yarn", ".yarnrc", ".yarn.lock",
".editorconfig", ".npmrc", ".babelrc", ".nyc_output", ".cache, project-print.txt",
"node_modules",
"*.log",
"dist",
"coverage",
"documentation",
".prettierrc",
".gitignore",
"scripts",
".serverless",
".idea",
".git",
".DS_Store",
".husky",
"package-lock.json",
".vscode",
"*.env",
"*.bak",
"*.tmp",
"*.swp",
".eslintcache",
".yarn",
".yarnrc",
".yarn.lock",
".editorconfig",
".npmrc",
".babelrc",
".nyc_output",
".cache",
"project-print.txt",
".eslintrc",
".eslintrc.js",
".eslintrc.json",
".eslintrc.yml",
".eslintrc.yaml",
".npmignore",
".babelrc.js",
".babelrc.json",
".babelrc.yml",
".babelrc.yaml",
];

54

dist/index.js

@@ -35,24 +35,29 @@ #!/usr/bin/env node

const program = new commander_1.Command();
program.argument("<startPath>", "Starting directory path").argument("[ignorePatterns]", "Comma-separated list of patterns to ignore").option("--ignore-default", "Use default ignore patterns").parse(process.argv);
program
.argument("<startPath>", "Starting directory path")
.option("--ignore <patterns>", "Comma-separated list of patterns to ignore")
.option("--include <patterns>", "Comma-separated list of patterns to include")
.option("--ignore-default", "Use default ignore patterns")
.parse(process.argv);
const startPath = program.args[0] && path.resolve(program.args[0]);
const userPatterns = program.args[1] ? program.args[1].split(",").filter(Boolean).map(pattern => pattern.trim()) : [];
const useDefaultIgnore = program.opts().ignoreDefault;
let patterns = useDefaultIgnore ? [...constants_1.defaultIgnorePatterns, ...userPatterns] : userPatterns;
patterns.push("project-print.txt");
const options = program.opts();
const userIgnorePatterns = options.ignore ? options.ignore.split(",").filter(Boolean).map((pattern) => pattern.trim()) : [];
const includePatterns = options.include ? options.include.split(",").filter(Boolean).map((pattern) => pattern.trim()) : [];
const useDefaultIgnore = options.ignoreDefault;
let ignorePatterns = useDefaultIgnore ? [...constants_1.defaultIgnorePatterns, ...userIgnorePatterns] : userIgnorePatterns;
ignorePatterns.push("project-print.txt");
console.log("Start Path:", startPath);
console.log("Patterns:", patterns);
function isIgnored(filePath, patterns) {
try {
return patterns.some(pattern => {
const parsedPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
const regex = new RegExp(parsedPattern);
return regex.test(filePath);
});
}
catch (e) {
console.error(`Failed to check if ignored: ${filePath}`, e);
return false;
}
console.log("Ignore Patterns:", ignorePatterns);
console.log("Include Patterns:", includePatterns);
function matchesPattern(filePath, patterns) {
return patterns.some(pattern => {
const parsedPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
const regex = new RegExp(parsedPattern);
return regex.test(filePath);
});
}
function readDirectory(dirPath, patterns = [], treeStructure = {}, currentPath = "") {
function shouldIncludeFile(filePath, ignorePatterns, includePatterns) {
return !matchesPattern(filePath, ignorePatterns) || matchesPattern(filePath, includePatterns);
}
function readDirectory(dirPath, ignorePatterns, includePatterns, treeStructure = {}, currentPath = "") {
try {

@@ -62,3 +67,3 @@ const dirents = fs.readdirSync(dirPath, { withFileTypes: true });

const fullPath = path.relative(process.cwd(), path.join(dirPath, dirent.name)).replace(/\\/g, "/");
if (isIgnored(fullPath, patterns)) {
if (!shouldIncludeFile(fullPath, ignorePatterns, includePatterns)) {
return;

@@ -69,3 +74,3 @@ }

treeStructure[relativePath] = {};
readDirectory(path.join(dirPath, dirent.name), patterns, treeStructure[relativePath], relativePath);
readDirectory(path.join(dirPath, dirent.name), ignorePatterns, includePatterns, treeStructure[relativePath], relativePath);
}

@@ -99,6 +104,7 @@ else if (dirent.isFile()) {

console.log(`Starting directory read from ${startPath}`);
console.log(`Ignoring: ${patterns.join(", ")}`);
console.log(`Ignoring: ${ignorePatterns.join(", ")}`);
console.log(`Including: ${includePatterns.length > 0 ? includePatterns.join(", ") : "All files (except ignored)"}`);
console.log(`Using default ignore: ${useDefaultIgnore}`);
readDirectory(startPath, patterns, treeStructure);
console.log("\nNon-ignored file structure:\n");
readDirectory(startPath, ignorePatterns, includePatterns, treeStructure);
console.log("\nProcessed file structure:\n");
buildTreeStructure(treeStructure);

@@ -105,0 +111,0 @@ console.log(treeStructureString);

{
"name": "print-project",
"version": "1.0.8",
"version": "1.0.10",
"description": "A simple CLI tool to print the project tree structure and file contents",

@@ -18,3 +18,3 @@ "main": "dist/index.js",

"build": "tsc",
"start": "ts-node src/index.ts",
"start": "ts-node src/index.ts . --ignore-default --include dist,src",
"bump": "npm version patch",

@@ -21,0 +21,0 @@ "package": "npm run build && npm run bump && npm publish"

@@ -6,5 +6,9 @@ File structure:

README.md
dist
dist/constants.d.ts
dist/constants.js
dist/index.d.ts
dist/index.js
jest.config.js
package.json
project-print.txt
src

@@ -354,396 +358,143 @@ src/constants.ts

jest.config.js:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
dist/constants.d.ts:
export declare const defaultIgnorePatterns: string[];
package.json:
{
"name": "print-project",
"version": "1.0.7",
"description": "A simple CLI tool to print the project tree structure and file contents",
"main": "dist/index.js",
"bin": {
"print-project": "./dist/index.js",
"pprint": "./dist/index.js"
},
"types": "dist/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/nitaiaharoni1/print-project.git"
},
"keywords": [],
"scripts": {
"build": "tsc",
"start": "ts-node src/index.ts",
"bump": "npm version patch",
"package": "npm run build && npm run bump && npm publish"
},
"author": "Nitai Aharoni",
"license": "MIT",
"dependencies": {
"commander": "^12.1.0"
},
"devDependencies": {
"ts-node": "^10.9.2",
"typescript": "^5.0.4"
}
}
dist/constants.js:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultIgnorePatterns = void 0;
exports.defaultIgnorePatterns = [
"node_modules", "*.log", "coverage", "documentation", ".prettierrc", ".gitignore",
"scripts", ".serverless", ".idea", ".git", ".DS_Store", ".husky", "package-lock.json", ".vscode",
"*.env", "*.bak", "*.tmp", "*.swp", ".eslintcache", ".yarn", ".yarnrc", ".yarn.lock",
".editorconfig", ".npmrc", ".babelrc", ".nyc_output", ".cache, project-print.txt",
];
project-print.txt:
File structure:
.eslintrc.json
.npmignore
LICENSE
README.md
jest.config.js
package.json
project-print.txt
src
src/constants.ts
src/index.ts
tsconfig.json
dist/index.d.ts:
#!/usr/bin/env node
export {};
Project print:
.eslintrc.json:
{
"root": true,
"env": {
"browser": true,
"es2021": true,
"node": true
},
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"project": "./tsconfig.json"
},
"ignorePatterns": [
"node_modules/",
"dist/",
"build/",
"coverage/",
"public/"
],
"extends": [
"standard-with-typescript",
"eslint:all",
"prettier",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript"
],
"plugins": [
"prettier",
"sort-keys-fix",
"sort-imports-es6-autofix"
],
"rules": {
"line-comment-position": "off",
"import/no-unresolved": "off",
"no-return-await": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"no-continue": "off",
"max-params": [
"error",
4
],
"no-underscore-dangle": "off",
"init-declarations": "off",
"sort-keys-fix/sort-keys-fix": "error",
"no-inline-comments": "off",
"no-console": [
"error",
{
"allow": [
"debug",
"warn",
"error"
]
}
],
"no-undefined": "off",
"no-undef": "off",
"@typescript-eslint/no-this-alias": "off",
"func-names": "off",
"consistent-this": "off",
"no-invalid-this": "off",
"prefer-named-capture-group": "off",
"@typescript-eslint/no-confusing-void-expression": "off",
"@typescript-eslint/await-thenable": "off",
"@typescript-eslint/no-misused-promises": "off",
"sort-imports": "off",
"no-magic-numbers": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"no-ternary": "off",
"max-statements": [
"error",
50
],
"id-length": "off",
"sort-imports-es6-autofix/sort-imports-es6": [
2,
{
"ignoreCase": false,
"ignoreMemberSort": false,
"memberSyntaxSortOrder": [
"none",
"all",
"multiple",
"single"
]
}
],
"no-shadow": "off",
"no-param-reassign": "off",
"no-nested-ternary": "off",
"guard-for-in": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/consistent-type-imports": "off",
"class-methods-use-this": "off",
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"@typescript-eslint/restrict-plus-operands": "off",
"multiline-comment-style": "off",
"require-jsdoc": "off",
"no-warning-comments": "off",
"capitalized-comments": "off",
"func-style": "off",
"max-lines-per-function": [
"error",
{
"max": 100,
"skipBlankLines": true,
"skipComments": true
}
],
"prettier/prettier": [
"error",
{
"singleQuote": true,
"printWidth": 180,
"trailingComma": "all",
"bracketSpacing": true,
"bracketSameLine": true,
"quoteProps": "as-needed",
"jsxSingleQuote": true,
"jsxBracketSameLine": false,
"jsxBracketSpacing": true
}
],
"no-use-before-define": "off"
}
dist/index.js:
#!/usr/bin/env node
"use strict";
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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const commander_1 = require("commander");
const constants_1 = require("./constants");
let projectPrint = "";
let treeStructure = {};
let treeStructureString = "";
const program = new commander_1.Command();
program
.argument("<startPath>", "Starting directory path")
.option("--ignore <patterns>", "Comma-separated list of patterns to ignore")
.option("--include <patterns>", "Comma-separated list of patterns to include")
.option("--ignore-default", "Use default ignore patterns")
.parse(process.argv);
const startPath = program.args[0] && path.resolve(program.args[0]);
const options = program.opts();
const userIgnorePatterns = options.ignore ? options.ignore.split(",").filter(Boolean).map((pattern) => pattern.trim()) : [];
const includePatterns = options.include ? options.include.split(",").filter(Boolean).map((pattern) => pattern.trim()) : [];
const useDefaultIgnore = options.ignoreDefault;
let ignorePatterns = useDefaultIgnore ? [...constants_1.defaultIgnorePatterns, ...userIgnorePatterns] : userIgnorePatterns;
ignorePatterns.push("project-print.txt");
console.log("Start Path:", startPath);
console.log("Ignore Patterns:", ignorePatterns);
console.log("Include Patterns:", includePatterns);
function matchesPattern(filePath, patterns) {
return patterns.some(pattern => {
const parsedPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
const regex = new RegExp(parsedPattern);
return regex.test(filePath);
});
}
function shouldIncludeFile(filePath, ignorePatterns, includePatterns) {
// If include patterns are specified, they take precedence
if (includePatterns.length > 0) {
return matchesPattern(filePath, includePatterns);
}
// If no include patterns, include the file unless it matches an ignore pattern
return !matchesPattern(filePath, ignorePatterns);
}
function readDirectory(dirPath, ignorePatterns, includePatterns, treeStructure = {}, currentPath = "") {
try {
const dirents = fs.readdirSync(dirPath, { withFileTypes: true });
dirents.forEach((dirent) => {
const fullPath = path.relative(process.cwd(), path.join(dirPath, dirent.name)).replace(/\\/g, "/");
if (!shouldIncludeFile(fullPath, ignorePatterns, includePatterns)) {
return;
}
const relativePath = path.join(currentPath, dirent.name).replace(/\\/g, "/");
if (dirent.isDirectory()) {
treeStructure[relativePath] = {};
readDirectory(path.join(dirPath, dirent.name), ignorePatterns, includePatterns, treeStructure[relativePath], relativePath);
}
else if (dirent.isFile()) {
treeStructure[relativePath] = {};
const content = fs.readFileSync(path.join(dirPath, dirent.name), "utf8");
if (content.length > 0) {
projectPrint += `${fullPath}:\n${content}\n\n`;
}
}
});
}
catch (e) {
console.error(`Failed to read directory: ${dirPath}`, e);
}
}
function buildTreeStructure(tree, indent = "") {
for (const key in tree) {
treeStructureString += indent + key + "\n";
if (typeof tree[key] === "object" && Object.keys(tree[key]).length > 0) {
buildTreeStructure(tree[key], indent + " ");
}
}
}
function main() {
if (!startPath) {
console.error("Starting directory path is required.");
process.exit(1);
}
console.log(`Starting directory read from ${startPath}`);
console.log(`Ignoring: ${ignorePatterns.join(", ")}`);
console.log(`Including: ${includePatterns.length > 0 ? includePatterns.join(", ") : "All files (except ignored)"}`);
console.log(`Using default ignore: ${useDefaultIgnore}`);
readDirectory(startPath, ignorePatterns, includePatterns, treeStructure);
console.log("\nProcessed file structure:\n");
buildTreeStructure(treeStructure);
console.log(treeStructureString);
const finalContents = `File structure:\n${treeStructureString}\n\nProject print:\n${projectPrint}`;
fs.writeFileSync("project-print.txt", finalContents);
console.log(`\nProject print size: ${(projectPrint.length / 1024).toFixed(2)}KB`);
}
main();
.npmignore:
# .npmignore
# Ignore the node_modules directory
node_modules/
# Ignore the build and dist directories
build/
dist/
# Ignore any .log files
*.log
# Ignore any .env files
*.env
# Ignore any .DS_Store files (macOS metadata)
.DS_Store
# Ignore the .git directory
.git/
# Ignore the .gitignore file
.gitignore
# Ignore any editor configuration files
.editorconfig
.vscode/
# Ignore any test files and directories
test/
__tests__/
# Ignore any documentation files
docs/
README.md
LICENSE
LICENSE:
The MIT License (MIT)
Copyright (c) 2023 Nitai Aharoni
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
README.md:
# Print-Project
The `print-project` command-line tool scans a specified directory and generates a report including the tree structure
and content of files that do not match given ignore patterns. It is useful for documenting or analyzing the file layout
of projects, especially in development environments.
## Installation
You can install `print-project` using npm:
```bash
npm install -g print-project
```
Ensure you have Node.js installed on your machine to use this package.
## Usage
After installation, the `print-project` tool can be run from the command line.
### Basic Command
```bash
print-project <startPath> [ignorePatterns]
```
- `<startPath>`: Required. The path to the directory you want to scan.
e.g., `/path/to/project`
- `[ignorePatterns]`: Optional. A comma-separated list of glob patterns to ignore files and directories.
e.g., `"node_modules,*.log,dist,coverage"`
### Command Aliases
You can use either `print-project` or `pp` to run the tool:
```bash
print-project <startPath> [ignorePatterns]
```
or
```bash
pp <startPath> [ignorePatterns]
```
### Using Default Ignore Patterns
To use the default ignore patterns, add the `--ignore-default` flag:
```bash
print-project <startPath> --ignore-default
```
You can also combine default patterns with your own:
```bash
print-project <startPath> "your,custom,patterns" --ignore-default
```
### Default Ignore Patterns
The following patterns are ignored by default when using the `--ignore-default` flag:
```
node_modules,*.log,dist,coverage,documentation,.prettierrc,.gitignore,dist,scripts,.serverless,.idea,.git,.DS_Store,.husky,package-lock.json
```
### Examples
- **Print all files and directories**:
```bash
print-project ./src
```
or
```bash
pp ./src
```
- **Ignore specific patterns**:
```bash
print-project ./src "node_modules,*.log,dist,coverage"
```
or
```bash
pp ./src "node_modules,*.log,dist,coverage"
```
- **Use default ignore patterns**:
```bash
print-project ./src --ignore-default
```
or
```bash
pp ./src --ignore-default
```
- **Use default ignore patterns and add custom ones**:
```bash
print-project ./src "*.tmp,*.bak" --ignore-default
```
or
```bash
pp ./src "*.tmp,*.bak" --ignore-default
```
## Features
- **Directory Scanning**: Recursively scans the provided directory path.
- **Ignore Patterns**: Supports glob patterns to exclude specific files or directories from the output.
- **Default Ignore Patterns**: Provides a set of commonly ignored patterns for convenience.
- **Output Generation**: Creates a text file `project-print.txt` in the current working directory containing:
- The structured list of non-ignored files and directories.
- The content of non-empty files.
- **Command Alias**: Can be run using either `print-project` or `pp` for convenience.
## How It Works
1. Parses the command line arguments for the starting directory path and ignore patterns.
2. Scans the specified directory, applying the ignore patterns to filter out unwanted files or directories.
3. Builds a tree structure of the directory and captures file content.
4. Outputs the directory structure and file content into `project-print.txt`.
## Output File Format
The output `project-print.txt` includes:
- **File Structure**: A tree showing the organization of files and directories.
- **Project Print**: Actual content of non-empty files within the project directory.
## License
This project is licensed under the MIT License - see the LICENSE file for details.
## Contributing
Contributions are welcome. Please open an issue first to discuss what you would like to change, or directly submit a
pull request.
jest.config.js:

@@ -759,3 +510,3 @@ module.exports = {

"name": "print-project",
"version": "1.0.6",
"version": "1.0.7",
"description": "A simple CLI tool to print the project tree structure and file contents",

@@ -765,3 +516,3 @@ "main": "dist/index.js",

"print-project": "./dist/index.js",
"pp": "./dist/index.js"
"pprint": "./dist/index.js"
},

@@ -776,3 +527,3 @@ "types": "dist/index.d.ts",

"build": "tsc",
"start": "ts-node src/index.ts",
"start": "ts-node src/index.ts . --ignore-default --include dist,src",
"bump": "npm version patch",

@@ -793,6 +544,2 @@ "package": "npm run build && npm run bump && npm publish"

project-print.txt:
asdasd
src/constants.ts:

@@ -803,3 +550,3 @@ export const defaultIgnorePatterns: string[] = [

"*.env", "*.bak", "*.tmp", "*.swp", ".eslintcache", ".yarn", ".yarnrc", ".yarn.lock",
".editorconfig", ".npmrc", ".babelrc", ".nyc_output", ".cache",
".editorconfig", ".npmrc", ".babelrc", ".nyc_output", ".cache, project-print.txt",
];

@@ -820,160 +567,40 @@

const program = new Command();
program.argument("<startPath>", "Starting directory path").argument("[ignorePatterns]", "Comma-separated list of patterns to ignore").option("--ignore-default", "Use default ignore patterns").parse(process.argv);
program
.argument("<startPath>", "Starting directory path")
.option("--ignore <patterns>", "Comma-separated list of patterns to ignore")
.option("--include <patterns>", "Comma-separated list of patterns to include")
.option("--ignore-default", "Use default ignore patterns")
.parse(process.argv);
const startPath: string | undefined = program.args[0] && path.resolve(program.args[0]);
const userPatterns: string[] = program.args[1] ? program.args[1].split(",").filter(Boolean).map(pattern => pattern.trim()) : [];
const useDefaultIgnore: boolean = program.opts().ignoreDefault;
const options = program.opts();
const userIgnorePatterns: string[] = options.ignore ? options.ignore.split(",").filter(Boolean).map((pattern: string) => pattern.trim()) : [];
const includePatterns: string[] = options.include ? options.include.split(",").filter(Boolean).map((pattern: string) => pattern.trim()) : [];
const useDefaultIgnore: boolean = options.ignoreDefault;
let ignorePatterns: string[] = useDefaultIgnore ? [...defaultIgnorePatterns, ...userIgnorePatterns] : userIgnorePatterns;
ignorePatterns.push("project-print.txt");
const patterns: string[] = useDefaultIgnore ? [...defaultIgnorePatterns, ...userPatterns] : userPatterns;
console.log("Start Path:", startPath);
console.log("Patterns:", patterns);
console.log("Ignore Patterns:", ignorePatterns);
console.log("Include Patterns:", includePatterns);
function isIgnored(filePath: string, patterns: string[]): boolean {
try {
return patterns.some(pattern => {
const parsedPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
const regex = new RegExp(parsedPattern);
return regex.test(filePath);
});
} catch (e) {
console.error(`Failed to check if ignored: ${filePath}`, e);
return false;
}
function matchesPattern(filePath: string, patterns: string[]): boolean {
return patterns.some(pattern => {
const parsedPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
const regex = new RegExp(parsedPattern);
return regex.test(filePath);
});
}
function readDirectory(dirPath: string, patterns: string[] = [], treeStructure: Record<string, any> = {}, currentPath: string = ""): void {
try {
const dirents = fs.readdirSync(dirPath, { withFileTypes: true });
dirents.forEach((dirent) => {
const fullPath = path.relative(process.cwd(), path.join(dirPath, dirent.name)).replace(/\\/g, "/");
if (isIgnored(fullPath, patterns)) {
return;
}
const relativePath = path.join(currentPath, dirent.name).replace(/\\/g, "/");
if (dirent.isDirectory()) {
treeStructure[relativePath] = {};
readDirectory(path.join(dirPath, dirent.name), patterns, treeStructure[relativePath], relativePath);
} else if (dirent.isFile()) {
treeStructure[relativePath] = {};
const content = fs.readFileSync(path.join(dirPath, dirent.name), "utf8");
if (content.length > 0) {
projectPrint += `${fullPath}:\n${content}\n\n`;
}
}
});
} catch (e) {
console.error(`Failed to read directory: ${dirPath}`, e);
}
function shouldIncludeFile(filePath: string, ignorePatterns: string[], includePatterns: string[]): boolean {
return !matchesPattern(filePath, ignorePatterns) || matchesPattern(filePath, includePatterns);
}
function buildTreeStructure(tree: Record<string, any>, indent: string = ""): void {
for (const key in tree) {
treeStructureString += indent + key + "\n";
if (typeof tree[key] === "object" && Object.keys(tree[key]).length > 0) {
buildTreeStructure(tree[key], indent + " ");
}
}
}
function main(): void {
if (!startPath) {
console.error("Starting directory path is required.");
process.exit(1);
}
console.log(`Starting directory read from ${startPath}`);
console.log(`Ignoring: ${patterns.join(", ")}`);
console.log(`Using default ignore: ${useDefaultIgnore}`);
readDirectory(startPath, patterns, treeStructure);
console.log("\nNon-ignored file structure:\n");
buildTreeStructure(treeStructure);
console.log(treeStructureString);
const finalContents = `File structure:\n${treeStructureString}\n\nProject print:\n${projectPrint}`;
fs.writeFileSync("project-print.txt", finalContents);
console.log(`\nProject print size: ${(projectPrint.length / 1024).toFixed(2)}KB`);
}
main();
tsconfig.json:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"declaration": true,
"outDir": "dist",
"strict": true,
"esModuleInterop": true,
"lib": [
"ES2016",
"DOM"
]
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}
src/constants.ts:
export const defaultIgnorePatterns: string[] = [
"node_modules", "*.log", "dist", "coverage", "documentation", ".prettierrc", ".gitignore", "dist",
"scripts", ".serverless", ".idea", ".git", ".DS_Store", ".husky", "package-lock.json", ".vscode",
"*.env", "*.bak", "*.tmp", "*.swp", ".eslintcache", ".yarn", ".yarnrc", ".yarn.lock",
".editorconfig", ".npmrc", ".babelrc", ".nyc_output", ".cache",
];
src/index.ts:
#!/usr/bin/env node
import * as fs from "fs";
import * as path from "path";
import { Command } from "commander";
import { defaultIgnorePatterns } from "./constants";
let projectPrint: string = "";
let treeStructure: Record<string, any> = {};
let treeStructureString: string = "";
const program = new Command();
program.argument("<startPath>", "Starting directory path").argument("[ignorePatterns]", "Comma-separated list of patterns to ignore").option("--ignore-default", "Use default ignore patterns").parse(process.argv);
const startPath: string | undefined = program.args[0] && path.resolve(program.args[0]);
const userPatterns: string[] = program.args[1] ? program.args[1].split(",").filter(Boolean).map(pattern => pattern.trim()) : [];
const useDefaultIgnore: boolean = program.opts().ignoreDefault;
const patterns: string[] = useDefaultIgnore ? [...defaultIgnorePatterns, ...userPatterns] : userPatterns;
console.log("Start Path:", startPath);
console.log("Patterns:", patterns);
function isIgnored(filePath: string, patterns: string[]): boolean {
function readDirectory(dirPath: string, ignorePatterns: string[], includePatterns: string[], treeStructure: Record<string, any> = {}, currentPath: string = ""): void {
try {
return patterns.some(pattern => {
const parsedPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
const regex = new RegExp(parsedPattern);
return regex.test(filePath);
});
} catch (e) {
console.error(`Failed to check if ignored: ${filePath}`, e);
return false;
}
}
function readDirectory(dirPath: string, patterns: string[] = [], treeStructure: Record<string, any> = {}, currentPath: string = ""): void {
try {
const dirents = fs.readdirSync(dirPath, { withFileTypes: true });
dirents.forEach((dirent) => {
const fullPath = path.relative(process.cwd(), path.join(dirPath, dirent.name)).replace(/\\/g, "/");
if (isIgnored(fullPath, patterns)) {
if (!shouldIncludeFile(fullPath, ignorePatterns, includePatterns)) {
return;

@@ -984,3 +611,3 @@ }

treeStructure[relativePath] = {};
readDirectory(path.join(dirPath, dirent.name), patterns, treeStructure[relativePath], relativePath);
readDirectory(path.join(dirPath, dirent.name), ignorePatterns, includePatterns, treeStructure[relativePath], relativePath);
} else if (dirent.isFile()) {

@@ -1015,7 +642,8 @@ treeStructure[relativePath] = {};

console.log(`Starting directory read from ${startPath}`);
console.log(`Ignoring: ${patterns.join(", ")}`);
console.log(`Ignoring: ${ignorePatterns.join(", ")}`);
console.log(`Including: ${includePatterns.length > 0 ? includePatterns.join(", ") : "All files (except ignored)"}`);
console.log(`Using default ignore: ${useDefaultIgnore}`);
readDirectory(startPath, patterns, treeStructure);
console.log("\nNon-ignored file structure:\n");
readDirectory(startPath, ignorePatterns, includePatterns, treeStructure);
console.log("\nProcessed file structure:\n");
buildTreeStructure(treeStructure);

@@ -1022,0 +650,0 @@ console.log(treeStructureString);

export const defaultIgnorePatterns: string[] = [
"node_modules", "*.log", "dist", "coverage", "documentation", ".prettierrc", ".gitignore", "dist",
"scripts", ".serverless", ".idea", ".git", ".DS_Store", ".husky", "package-lock.json", ".vscode",
"*.env", "*.bak", "*.tmp", "*.swp", ".eslintcache", ".yarn", ".yarnrc", ".yarn.lock",
".editorconfig", ".npmrc", ".babelrc", ".nyc_output", ".cache, project-print.txt",
];
"node_modules",
"*.log",
"dist",
"coverage",
"documentation",
".prettierrc",
".gitignore",
"scripts",
".serverless",
".idea",
".git",
".DS_Store",
".husky",
"package-lock.json",
".vscode",
"*.env",
"*.bak",
"*.tmp",
"*.swp",
".eslintcache",
".yarn",
".yarnrc",
".yarn.lock",
".editorconfig",
".npmrc",
".babelrc",
".nyc_output",
".cache",
"project-print.txt",
".eslintrc",
".eslintrc.js",
".eslintrc.json",
".eslintrc.yml",
".eslintrc.yaml",
".npmignore",
".babelrc.js",
".babelrc.json",
".babelrc.yml",
".babelrc.yaml",
];

@@ -12,29 +12,35 @@ #!/usr/bin/env node

const program = new Command();
program.argument("<startPath>", "Starting directory path").argument("[ignorePatterns]", "Comma-separated list of patterns to ignore").option("--ignore-default", "Use default ignore patterns").parse(process.argv);
program
.argument("<startPath>", "Starting directory path")
.option("--ignore <patterns>", "Comma-separated list of patterns to ignore")
.option("--include <patterns>", "Comma-separated list of patterns to include")
.option("--ignore-default", "Use default ignore patterns")
.parse(process.argv);
const startPath: string | undefined = program.args[0] && path.resolve(program.args[0]);
const userPatterns: string[] = program.args[1] ? program.args[1].split(",").filter(Boolean).map(pattern => pattern.trim()) : [];
const useDefaultIgnore: boolean = program.opts().ignoreDefault;
const options = program.opts();
const userIgnorePatterns: string[] = options.ignore ? options.ignore.split(",").filter(Boolean).map((pattern: string) => pattern.trim()) : [];
const includePatterns: string[] = options.include ? options.include.split(",").filter(Boolean).map((pattern: string) => pattern.trim()) : [];
const useDefaultIgnore: boolean = options.ignoreDefault;
let ignorePatterns: string[] = useDefaultIgnore ? [...defaultIgnorePatterns, ...userIgnorePatterns] : userIgnorePatterns;
ignorePatterns.push("project-print.txt");
let patterns: string[] = useDefaultIgnore ? [...defaultIgnorePatterns, ...userPatterns] : userPatterns;
patterns.push("project-print.txt");
console.log("Start Path:", startPath);
console.log("Patterns:", patterns);
console.log("Ignore Patterns:", ignorePatterns);
console.log("Include Patterns:", includePatterns);
function isIgnored(filePath: string, patterns: string[]): boolean {
try {
return patterns.some(pattern => {
const parsedPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
const regex = new RegExp(parsedPattern);
return regex.test(filePath);
});
} catch (e) {
console.error(`Failed to check if ignored: ${filePath}`, e);
return false;
}
function matchesPattern(filePath: string, patterns: string[]): boolean {
return patterns.some(pattern => {
const parsedPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
const regex = new RegExp(parsedPattern);
return regex.test(filePath);
});
}
function readDirectory(dirPath: string, patterns: string[] = [], treeStructure: Record<string, any> = {}, currentPath: string = ""): void {
function shouldIncludeFile(filePath: string, ignorePatterns: string[], includePatterns: string[]): boolean {
return !matchesPattern(filePath, ignorePatterns) || matchesPattern(filePath, includePatterns);
}
function readDirectory(dirPath: string, ignorePatterns: string[], includePatterns: string[], treeStructure: Record<string, any> = {}, currentPath: string = ""): void {
try {

@@ -44,3 +50,3 @@ const dirents = fs.readdirSync(dirPath, { withFileTypes: true });

const fullPath = path.relative(process.cwd(), path.join(dirPath, dirent.name)).replace(/\\/g, "/");
if (isIgnored(fullPath, patterns)) {
if (!shouldIncludeFile(fullPath, ignorePatterns, includePatterns)) {
return;

@@ -51,3 +57,3 @@ }

treeStructure[relativePath] = {};
readDirectory(path.join(dirPath, dirent.name), patterns, treeStructure[relativePath], relativePath);
readDirectory(path.join(dirPath, dirent.name), ignorePatterns, includePatterns, treeStructure[relativePath], relativePath);
} else if (dirent.isFile()) {

@@ -82,7 +88,8 @@ treeStructure[relativePath] = {};

console.log(`Starting directory read from ${startPath}`);
console.log(`Ignoring: ${patterns.join(", ")}`);
console.log(`Ignoring: ${ignorePatterns.join(", ")}`);
console.log(`Including: ${includePatterns.length > 0 ? includePatterns.join(", ") : "All files (except ignored)"}`);
console.log(`Using default ignore: ${useDefaultIgnore}`);
readDirectory(startPath, patterns, treeStructure);
console.log("\nNon-ignored file structure:\n");
readDirectory(startPath, ignorePatterns, includePatterns, treeStructure);
console.log("\nProcessed file structure:\n");
buildTreeStructure(treeStructure);

@@ -89,0 +96,0 @@ console.log(treeStructureString);

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc