tangled
alpha
login
or
join now
stevedylan.dev
/
sequoia
36
fork
atom
A CLI for publishing standard.site documents to ATProto
sequoia.pub
standard
site
lexicon
cli
publishing
36
fork
atom
overview
issues
5
pulls
1
pipelines
chore: added ignore field to config
stevedylan.dev
1 month ago
bde611d3
ce21736f
+25
-3
4 changed files
expand all
collapse all
unified
split
packages
cli
src
commands
publish.ts
lib
config.ts
markdown.ts
types.ts
+3
-2
packages/cli/src/commands/publish.ts
···
84
84
85
85
// Scan for posts
86
86
consola.start("Scanning for posts...");
87
87
-
const posts = await scanContentDirectory(contentDir, config.frontmatter);
87
87
+
const posts = await scanContentDirectory(contentDir, config.frontmatter, config.ignore);
88
88
consola.info(`Found ${posts.length} posts`);
89
89
90
90
// Determine which posts need publishing
···
213
213
lastPublished: new Date().toISOString(),
214
214
};
215
215
} catch (error) {
216
216
-
consola.error(` Error: ${error}`);
216
216
+
const errorMessage = error instanceof Error ? error.message : String(error);
217
217
+
consola.error(` Error publishing "${path.basename(post.filePath)}": ${errorMessage}`);
217
218
errorCount++;
218
219
}
219
220
}
+5
packages/cli/src/lib/config.ts
···
67
67
publicationUri: string;
68
68
pdsUrl?: string;
69
69
frontmatter?: FrontmatterMapping;
70
70
+
ignore?: string[];
70
71
}): string {
71
72
const config: Record<string, unknown> = {
72
73
siteUrl: options.siteUrl,
···
97
98
98
99
if (options.frontmatter && Object.keys(options.frontmatter).length > 0) {
99
100
config.frontmatter = options.frontmatter;
101
101
+
}
102
102
+
103
103
+
if (options.ignore && options.ignore.length > 0) {
104
104
+
config.ignore = options.ignore;
100
105
}
101
106
102
107
return JSON.stringify(config, null, 2);
+16
-1
packages/cli/src/lib/markdown.ts
···
118
118
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
119
119
}
120
120
121
121
+
function shouldIgnore(relativePath: string, ignorePatterns: string[]): boolean {
122
122
+
for (const pattern of ignorePatterns) {
123
123
+
const glob = new Glob(pattern);
124
124
+
if (glob.match(relativePath)) {
125
125
+
return true;
126
126
+
}
127
127
+
}
128
128
+
return false;
129
129
+
}
130
130
+
121
131
export async function scanContentDirectory(
122
132
contentDir: string,
123
123
-
frontmatterMapping?: FrontmatterMapping
133
133
+
frontmatterMapping?: FrontmatterMapping,
134
134
+
ignorePatterns: string[] = []
124
135
): Promise<BlogPost[]> {
125
136
const patterns = ["**/*.md", "**/*.mdx"];
126
137
const posts: BlogPost[] = [];
···
132
143
cwd: contentDir,
133
144
absolute: false,
134
145
})) {
146
146
+
// Skip files matching ignore patterns
147
147
+
if (shouldIgnore(relativePath, ignorePatterns)) {
148
148
+
continue;
149
149
+
}
135
150
136
151
const filePath = path.join(contentDir, relativePath);
137
152
const file = Bun.file(filePath);
+1
packages/cli/src/lib/types.ts
···
17
17
pdsUrl?: string;
18
18
identity?: string; // Which stored identity to use (matches identifier)
19
19
frontmatter?: FrontmatterMapping; // Custom frontmatter field mappings
20
20
+
ignore?: string[]; // Glob patterns for files to ignore (e.g., ["_index.md", "**/drafts/**"])
20
21
}
21
22
22
23
export interface Credentials {