Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
wisp.place
1import ignore, { type Ignore } from 'ignore'
2import { readFileSync, existsSync } from 'fs'
3import { join } from 'path'
4
5interface IgnoreConfig {
6 version: string
7 description: string
8 patterns: string[]
9}
10
11/**
12 * Load default ignore patterns from the .wispignore.json file in the monorepo root
13 */
14function loadDefaultPatterns(): string[] {
15 try {
16 // Path to the default ignore patterns JSON file (monorepo root, 3 levels up from this file)
17 const defaultJsonPath = join(__dirname, '../../../../.wispignore.json')
18
19 if (!existsSync(defaultJsonPath)) {
20 console.warn('⚠️ Default .wispignore.json not found, using hardcoded patterns')
21 return getHardcodedPatterns()
22 }
23
24 const contents = readFileSync(defaultJsonPath, 'utf-8')
25 const config: IgnoreConfig = JSON.parse(contents)
26 return config.patterns
27 } catch (error) {
28 console.error('Failed to load default ignore patterns:', error)
29 return getHardcodedPatterns()
30 }
31}
32
33/**
34 * Hardcoded fallback patterns (same as in .wispignore.json)
35 */
36function getHardcodedPatterns(): string[] {
37 return [
38 '.git',
39 '.git/**',
40 '.github',
41 '.github/**',
42 '.gitlab',
43 '.gitlab/**',
44 '.DS_Store',
45 '.wisp.metadata.json',
46 '.env',
47 '.env.*',
48 'node_modules',
49 'node_modules/**',
50 'Thumbs.db',
51 'desktop.ini',
52 '._*',
53 '.Spotlight-V100',
54 '.Spotlight-V100/**',
55 '.Trashes',
56 '.Trashes/**',
57 '.fseventsd',
58 '.fseventsd/**',
59 '.cache',
60 '.cache/**',
61 '.temp',
62 '.temp/**',
63 '.tmp',
64 '.tmp/**',
65 '__pycache__',
66 '__pycache__/**',
67 '*.pyc',
68 '.venv',
69 '.venv/**',
70 'venv',
71 'venv/**',
72 'env',
73 'env/**',
74 '*.swp',
75 '*.swo',
76 '*~',
77 '.tangled',
78 '.tangled/**',
79 ]
80}
81
82/**
83 * Load custom ignore patterns from a .wispignore file
84 * @param wispignoreContent - Content of the .wispignore file (one pattern per line)
85 */
86function loadWispignorePatterns(wispignoreContent: string): string[] {
87 return wispignoreContent
88 .split('\n')
89 .map(line => line.trim())
90 .filter(line => line && !line.startsWith('#')) // Skip empty lines and comments
91}
92
93/**
94 * Create an ignore matcher
95 * @param customPatterns - Optional custom patterns from a .wispignore file
96 */
97export function createIgnoreMatcher(customPatterns?: string[]): Ignore {
98 const ig = ignore()
99
100 // Add default patterns
101 const defaultPatterns = loadDefaultPatterns()
102 ig.add(defaultPatterns)
103
104 // Add custom patterns if provided
105 if (customPatterns && customPatterns.length > 0) {
106 ig.add(customPatterns)
107 console.log(`Loaded ${customPatterns.length} custom patterns from .wispignore`)
108 }
109
110 return ig
111}
112
113/**
114 * Check if a file path should be ignored
115 * @param matcher - The ignore matcher
116 * @param filePath - The file path to check (relative to site root)
117 */
118export function shouldIgnore(matcher: Ignore, filePath: string): boolean {
119 return matcher.ignores(filePath)
120}
121
122/**
123 * Parse .wispignore content and return patterns
124 */
125export function parseWispignore(content: string): string[] {
126 return loadWispignorePatterns(content)
127}