peam 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +38 -20
- package/dist/cli.js.map +1 -1
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +38 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +40 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/cli.js
CHANGED
|
@@ -24,6 +24,27 @@ var packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, "../package.js
|
|
|
24
24
|
function parseExcludePatterns(value) {
|
|
25
25
|
return value.split(",").map((p) => p.trim()).filter(Boolean);
|
|
26
26
|
}
|
|
27
|
+
function parseExporterConfigEntry(value, previous = []) {
|
|
28
|
+
return [...previous, value];
|
|
29
|
+
}
|
|
30
|
+
function parseExporterConfig(options, exporterType) {
|
|
31
|
+
const exporterConfig = {};
|
|
32
|
+
if (Array.isArray(options.exporterConfig)) {
|
|
33
|
+
for (const entry of options.exporterConfig) {
|
|
34
|
+
if (typeof entry === "string") {
|
|
35
|
+
const [key, ...valueParts] = entry.split("=");
|
|
36
|
+
const value = valueParts.join("=");
|
|
37
|
+
if (key && value !== void 0) {
|
|
38
|
+
exporterConfig[key.trim()] = value.trim();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
type: exporterType,
|
|
45
|
+
config: exporterConfig
|
|
46
|
+
};
|
|
47
|
+
}
|
|
27
48
|
var log = {
|
|
28
49
|
success: (message) => console.log(chalk__default.default.green("\u2713 ") + message),
|
|
29
50
|
error: (message) => console.error(chalk__default.default.red("\u2717 ") + message),
|
|
@@ -69,8 +90,8 @@ async function indexPages(config) {
|
|
|
69
90
|
log.text(` Project Directory: ${log.gray(config.projectDir)}`);
|
|
70
91
|
log.text(` Source Directory: ${log.gray(config.source)}`);
|
|
71
92
|
log.text(` Glob Pattern: ${log.gray(config.glob)}`);
|
|
72
|
-
log.text(`
|
|
73
|
-
log.text(`
|
|
93
|
+
log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);
|
|
94
|
+
log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);
|
|
74
95
|
log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);
|
|
75
96
|
if (config.exclude.length > 0) {
|
|
76
97
|
log.text(` Exclude Patterns: ${log.gray(config.exclude.join(", "))}`);
|
|
@@ -152,19 +173,10 @@ async function indexPages(config) {
|
|
|
152
173
|
log.text("");
|
|
153
174
|
log.text(log.bold("Saving index..."));
|
|
154
175
|
log.text("");
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
const searchIndexFile = path.join(generatedPath, config.indexFilename);
|
|
160
|
-
fs.writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));
|
|
161
|
-
const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE
|
|
162
|
-
import index from "./generated/${config.indexFilename}";
|
|
163
|
-
export default index;
|
|
164
|
-
`;
|
|
165
|
-
const indexJsFile = path.join(outputPath, "index.js");
|
|
166
|
-
fs.writeFileSync(indexJsFile, indexJsContent);
|
|
167
|
-
log.success(`Index saved to: ${log.cyan(path.relative(config.projectDir, searchIndexFile))}`);
|
|
176
|
+
const searchIndexExporter = search.createExporterFromConfig(config.searchExporter);
|
|
177
|
+
await searchIndexExporter.export(searchIndexData);
|
|
178
|
+
const indexPathDisplay = config.searchExporter.type === "fileBased" ? path.relative(config.projectDir, path.join(config.projectDir, config.searchExporter.config.indexPath)) : "configured location";
|
|
179
|
+
log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);
|
|
168
180
|
log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);
|
|
169
181
|
log.text(
|
|
170
182
|
` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), "utf8") / 1024).toFixed(2))} KB`
|
|
@@ -185,7 +197,10 @@ function probeSourceDirectory(projectDir) {
|
|
|
185
197
|
}
|
|
186
198
|
async function main() {
|
|
187
199
|
const program = new commander.Command();
|
|
188
|
-
program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--
|
|
200
|
+
program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--exporter <type>", "Search exporter type", "fileBased").option("--exporterConfig <key=value>", "Exporter config entry (repeatable)", parseExporterConfigEntry, [
|
|
201
|
+
`baseDir=${process.cwd()}`,
|
|
202
|
+
"indexPath=.peam/index.json"
|
|
203
|
+
]).option("--ignore-robots-txt", "Disable robots.txt checking").option("--robots-path <path>", "Custom path to robots.txt file").option("--exclude <patterns>", "Comma-separated exclude patterns", parseExcludePatterns, []).option("--project-dir <path>", "Project root directory", process.cwd()).addHelpText(
|
|
189
204
|
"after",
|
|
190
205
|
`
|
|
191
206
|
Examples:
|
|
@@ -198,8 +213,11 @@ Examples:
|
|
|
198
213
|
# Next.js
|
|
199
214
|
$ peam --source .next
|
|
200
215
|
|
|
201
|
-
# Custom
|
|
202
|
-
$ peam --source dist --
|
|
216
|
+
# Custom index path using file-based exporter
|
|
217
|
+
$ peam --source dist --exporterConfig indexPath=.search/index.json
|
|
218
|
+
|
|
219
|
+
# Multiple exporter config entries
|
|
220
|
+
$ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp
|
|
203
221
|
|
|
204
222
|
# Exclude patterns
|
|
205
223
|
$ peam --exclude "/admin/**,/api/*,/private-*"
|
|
@@ -225,11 +243,11 @@ More information: https://peam.ai
|
|
|
225
243
|
process.exit(1);
|
|
226
244
|
}
|
|
227
245
|
}
|
|
246
|
+
const searchExporter = parseExporterConfig(options, options.exporter);
|
|
228
247
|
const config = {
|
|
229
248
|
source: sourceDir,
|
|
230
249
|
glob: options.glob,
|
|
231
|
-
|
|
232
|
-
indexFilename: options.indexFilename,
|
|
250
|
+
searchExporter,
|
|
233
251
|
respectRobotsTxt: !options.ignoreRobotsTxt,
|
|
234
252
|
robotsTxtPath: options.robotsPath,
|
|
235
253
|
exclude: options.exclude,
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"names":["readFileSync","join","chalk","fg","relative","filePathToPathname","existsSync","loadRobotsTxt","shouldIncludePath","parseHTML","buildSearchIndex","mkdirSync","writeFileSync","Command"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n outputDir: string;\n indexFilename: string;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Output Directory: ${log.gray(config.outputDir)}`);\n log.text(` Index Filename: ${log.gray(config.indexFilename)}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const outputPath = join(config.projectDir, config.outputDir);\n mkdirSync(outputPath, { recursive: true });\n\n const generatedPath = join(outputPath, 'generated');\n mkdirSync(generatedPath, { recursive: true });\n\n const searchIndexFile = join(generatedPath, config.indexFilename);\n writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));\n\n const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE\nimport index from \"./generated/${config.indexFilename}\";\nexport default index;\n`;\n const indexJsFile = join(outputPath, 'index.js');\n writeFileSync(indexJsFile, indexJsContent);\n\n log.success(`Index saved to: ${log.cyan(relative(config.projectDir, searchIndexFile))}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--output-dir <path>', 'Output directory for index', '.peam')\n .option('--index-filename <name>', 'Name of index file', 'index.json')\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom output directory\n $ peam --source dist --glob \"**/*.html\"\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n outputDir: options.outputDir,\n indexFilename: options.indexFilename,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"names":["readFileSync","join","chalk","fg","relative","filePathToPathname","existsSync","loadRobotsTxt","shouldIncludePath","parseHTML","buildSearchIndex","createExporterFromConfig","Command"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex, createExporterFromConfig, type SearchExporterConfig } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, readFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n searchExporter: SearchExporterConfig;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\n/**\n * Parse exporterConfig key=value pairs\n */\nfunction parseExporterConfigEntry(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n\n/**\n * Parse command line options and extract exporter configuration dynamically.\n * Supports --exporterConfig key=value pairs\n */\nfunction parseExporterConfig(options: Record<string, unknown>, exporterType: string): SearchExporterConfig {\n const exporterConfig: Record<string, unknown> = {};\n\n // Parse key=value pairs from --exporterConfig options\n if (Array.isArray(options.exporterConfig)) {\n for (const entry of options.exporterConfig) {\n if (typeof entry === 'string') {\n const [key, ...valueParts] = entry.split('=');\n const value = valueParts.join('=');\n if (key && value !== undefined) {\n exporterConfig[key.trim()] = value.trim();\n }\n }\n }\n }\n\n return {\n type: exporterType,\n config: exporterConfig,\n } as unknown as SearchExporterConfig;\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);\n log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const searchIndexExporter = createExporterFromConfig(config.searchExporter);\n await searchIndexExporter.export(searchIndexData);\n\n const indexPathDisplay =\n config.searchExporter.type === 'fileBased'\n ? relative(config.projectDir, join(config.projectDir, config.searchExporter.config.indexPath))\n : 'configured location';\n\n log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--exporter <type>', 'Search exporter type', 'fileBased')\n .option('--exporterConfig <key=value>', 'Exporter config entry (repeatable)', parseExporterConfigEntry, [\n `baseDir=${process.cwd()}`,\n 'indexPath=.peam/index.json',\n ])\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom index path using file-based exporter\n $ peam --source dist --exporterConfig indexPath=.search/index.json\n\n # Multiple exporter config entries\n $ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const searchExporter = parseExporterConfig(options, options.exporter);\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n searchExporter,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import { SearchExporterConfig } from '@peam-ai/search';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Peam Static Site Indexer
|
|
3
5
|
*
|
|
4
6
|
* Scans a static site output directory, discovers HTML files,
|
|
5
7
|
* parses them into structured pages, and creates a searchable index.
|
|
6
8
|
*/
|
|
9
|
+
|
|
7
10
|
interface IndexerConfig {
|
|
8
11
|
source: string;
|
|
9
|
-
|
|
10
|
-
indexFilename: string;
|
|
12
|
+
searchExporter: SearchExporterConfig;
|
|
11
13
|
respectRobotsTxt: boolean;
|
|
12
14
|
robotsTxtPath?: string;
|
|
13
15
|
exclude: string[];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import { SearchExporterConfig } from '@peam-ai/search';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Peam Static Site Indexer
|
|
3
5
|
*
|
|
4
6
|
* Scans a static site output directory, discovers HTML files,
|
|
5
7
|
* parses them into structured pages, and creates a searchable index.
|
|
6
8
|
*/
|
|
9
|
+
|
|
7
10
|
interface IndexerConfig {
|
|
8
11
|
source: string;
|
|
9
|
-
|
|
10
|
-
indexFilename: string;
|
|
12
|
+
searchExporter: SearchExporterConfig;
|
|
11
13
|
respectRobotsTxt: boolean;
|
|
12
14
|
robotsTxtPath?: string;
|
|
13
15
|
exclude: string[];
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,27 @@ var packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, "../package.js
|
|
|
23
23
|
function parseExcludePatterns(value) {
|
|
24
24
|
return value.split(",").map((p) => p.trim()).filter(Boolean);
|
|
25
25
|
}
|
|
26
|
+
function parseExporterConfigEntry(value, previous = []) {
|
|
27
|
+
return [...previous, value];
|
|
28
|
+
}
|
|
29
|
+
function parseExporterConfig(options, exporterType) {
|
|
30
|
+
const exporterConfig = {};
|
|
31
|
+
if (Array.isArray(options.exporterConfig)) {
|
|
32
|
+
for (const entry of options.exporterConfig) {
|
|
33
|
+
if (typeof entry === "string") {
|
|
34
|
+
const [key, ...valueParts] = entry.split("=");
|
|
35
|
+
const value = valueParts.join("=");
|
|
36
|
+
if (key && value !== void 0) {
|
|
37
|
+
exporterConfig[key.trim()] = value.trim();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
type: exporterType,
|
|
44
|
+
config: exporterConfig
|
|
45
|
+
};
|
|
46
|
+
}
|
|
26
47
|
var log = {
|
|
27
48
|
success: (message) => console.log(chalk__default.default.green("\u2713 ") + message),
|
|
28
49
|
error: (message) => console.error(chalk__default.default.red("\u2717 ") + message),
|
|
@@ -68,8 +89,8 @@ async function indexPages(config) {
|
|
|
68
89
|
log.text(` Project Directory: ${log.gray(config.projectDir)}`);
|
|
69
90
|
log.text(` Source Directory: ${log.gray(config.source)}`);
|
|
70
91
|
log.text(` Glob Pattern: ${log.gray(config.glob)}`);
|
|
71
|
-
log.text(`
|
|
72
|
-
log.text(`
|
|
92
|
+
log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);
|
|
93
|
+
log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);
|
|
73
94
|
log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);
|
|
74
95
|
if (config.exclude.length > 0) {
|
|
75
96
|
log.text(` Exclude Patterns: ${log.gray(config.exclude.join(", "))}`);
|
|
@@ -151,19 +172,10 @@ async function indexPages(config) {
|
|
|
151
172
|
log.text("");
|
|
152
173
|
log.text(log.bold("Saving index..."));
|
|
153
174
|
log.text("");
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
const searchIndexFile = path.join(generatedPath, config.indexFilename);
|
|
159
|
-
fs.writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));
|
|
160
|
-
const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE
|
|
161
|
-
import index from "./generated/${config.indexFilename}";
|
|
162
|
-
export default index;
|
|
163
|
-
`;
|
|
164
|
-
const indexJsFile = path.join(outputPath, "index.js");
|
|
165
|
-
fs.writeFileSync(indexJsFile, indexJsContent);
|
|
166
|
-
log.success(`Index saved to: ${log.cyan(path.relative(config.projectDir, searchIndexFile))}`);
|
|
175
|
+
const searchIndexExporter = search.createExporterFromConfig(config.searchExporter);
|
|
176
|
+
await searchIndexExporter.export(searchIndexData);
|
|
177
|
+
const indexPathDisplay = config.searchExporter.type === "fileBased" ? path.relative(config.projectDir, path.join(config.projectDir, config.searchExporter.config.indexPath)) : "configured location";
|
|
178
|
+
log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);
|
|
167
179
|
log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);
|
|
168
180
|
log.text(
|
|
169
181
|
` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), "utf8") / 1024).toFixed(2))} KB`
|
|
@@ -184,7 +196,10 @@ function probeSourceDirectory(projectDir) {
|
|
|
184
196
|
}
|
|
185
197
|
async function main() {
|
|
186
198
|
const program = new commander.Command();
|
|
187
|
-
program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--
|
|
199
|
+
program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--exporter <type>", "Search exporter type", "fileBased").option("--exporterConfig <key=value>", "Exporter config entry (repeatable)", parseExporterConfigEntry, [
|
|
200
|
+
`baseDir=${process.cwd()}`,
|
|
201
|
+
"indexPath=.peam/index.json"
|
|
202
|
+
]).option("--ignore-robots-txt", "Disable robots.txt checking").option("--robots-path <path>", "Custom path to robots.txt file").option("--exclude <patterns>", "Comma-separated exclude patterns", parseExcludePatterns, []).option("--project-dir <path>", "Project root directory", process.cwd()).addHelpText(
|
|
188
203
|
"after",
|
|
189
204
|
`
|
|
190
205
|
Examples:
|
|
@@ -197,8 +212,11 @@ Examples:
|
|
|
197
212
|
# Next.js
|
|
198
213
|
$ peam --source .next
|
|
199
214
|
|
|
200
|
-
# Custom
|
|
201
|
-
$ peam --source dist --
|
|
215
|
+
# Custom index path using file-based exporter
|
|
216
|
+
$ peam --source dist --exporterConfig indexPath=.search/index.json
|
|
217
|
+
|
|
218
|
+
# Multiple exporter config entries
|
|
219
|
+
$ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp
|
|
202
220
|
|
|
203
221
|
# Exclude patterns
|
|
204
222
|
$ peam --exclude "/admin/**,/api/*,/private-*"
|
|
@@ -224,11 +242,11 @@ More information: https://peam.ai
|
|
|
224
242
|
process.exit(1);
|
|
225
243
|
}
|
|
226
244
|
}
|
|
245
|
+
const searchExporter = parseExporterConfig(options, options.exporter);
|
|
227
246
|
const config = {
|
|
228
247
|
source: sourceDir,
|
|
229
248
|
glob: options.glob,
|
|
230
|
-
|
|
231
|
-
indexFilename: options.indexFilename,
|
|
249
|
+
searchExporter,
|
|
232
250
|
respectRobotsTxt: !options.ignoreRobotsTxt,
|
|
233
251
|
robotsTxtPath: options.robotsPath,
|
|
234
252
|
exclude: options.exclude,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"names":["readFileSync","join","chalk","fg","relative","filePathToPathname","existsSync","loadRobotsTxt","shouldIncludePath","parseHTML","buildSearchIndex","mkdirSync","writeFileSync","Command"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n outputDir: string;\n indexFilename: string;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Output Directory: ${log.gray(config.outputDir)}`);\n log.text(` Index Filename: ${log.gray(config.indexFilename)}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const outputPath = join(config.projectDir, config.outputDir);\n mkdirSync(outputPath, { recursive: true });\n\n const generatedPath = join(outputPath, 'generated');\n mkdirSync(generatedPath, { recursive: true });\n\n const searchIndexFile = join(generatedPath, config.indexFilename);\n writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));\n\n const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE\nimport index from \"./generated/${config.indexFilename}\";\nexport default index;\n`;\n const indexJsFile = join(outputPath, 'index.js');\n writeFileSync(indexJsFile, indexJsContent);\n\n log.success(`Index saved to: ${log.cyan(relative(config.projectDir, searchIndexFile))}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--output-dir <path>', 'Output directory for index', '.peam')\n .option('--index-filename <name>', 'Name of index file', 'index.json')\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom output directory\n $ peam --source dist --glob \"**/*.html\"\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n outputDir: options.outputDir,\n indexFilename: options.indexFilename,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"names":["readFileSync","join","chalk","fg","relative","filePathToPathname","existsSync","loadRobotsTxt","shouldIncludePath","parseHTML","buildSearchIndex","createExporterFromConfig","Command"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex, createExporterFromConfig, type SearchExporterConfig } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, readFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n searchExporter: SearchExporterConfig;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\n/**\n * Parse exporterConfig key=value pairs\n */\nfunction parseExporterConfigEntry(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n\n/**\n * Parse command line options and extract exporter configuration dynamically.\n * Supports --exporterConfig key=value pairs\n */\nfunction parseExporterConfig(options: Record<string, unknown>, exporterType: string): SearchExporterConfig {\n const exporterConfig: Record<string, unknown> = {};\n\n // Parse key=value pairs from --exporterConfig options\n if (Array.isArray(options.exporterConfig)) {\n for (const entry of options.exporterConfig) {\n if (typeof entry === 'string') {\n const [key, ...valueParts] = entry.split('=');\n const value = valueParts.join('=');\n if (key && value !== undefined) {\n exporterConfig[key.trim()] = value.trim();\n }\n }\n }\n }\n\n return {\n type: exporterType,\n config: exporterConfig,\n } as unknown as SearchExporterConfig;\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);\n log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const searchIndexExporter = createExporterFromConfig(config.searchExporter);\n await searchIndexExporter.export(searchIndexData);\n\n const indexPathDisplay =\n config.searchExporter.type === 'fileBased'\n ? relative(config.projectDir, join(config.projectDir, config.searchExporter.config.indexPath))\n : 'configured location';\n\n log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--exporter <type>', 'Search exporter type', 'fileBased')\n .option('--exporterConfig <key=value>', 'Exporter config entry (repeatable)', parseExporterConfigEntry, [\n `baseDir=${process.cwd()}`,\n 'indexPath=.peam/index.json',\n ])\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom index path using file-based exporter\n $ peam --source dist --exporterConfig indexPath=.search/index.json\n\n # Multiple exporter config entries\n $ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const searchExporter = parseExporterConfig(options, options.exporter);\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n searchExporter,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
import { __require } from './chunk-BJTO5JO5.mjs';
|
|
2
2
|
import { loadRobotsTxt, shouldIncludePath, parseHTML, filePathToPathname } from '@peam-ai/parser';
|
|
3
|
-
import { buildSearchIndex } from '@peam-ai/search';
|
|
3
|
+
import { buildSearchIndex, createExporterFromConfig } from '@peam-ai/search';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { Command } from 'commander';
|
|
6
6
|
import fg from 'fast-glob';
|
|
7
|
-
import { readFileSync, existsSync
|
|
7
|
+
import { readFileSync, existsSync } from 'fs';
|
|
8
8
|
import { join, relative } from 'path';
|
|
9
9
|
|
|
10
10
|
var packageJson = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8"));
|
|
11
11
|
function parseExcludePatterns(value) {
|
|
12
12
|
return value.split(",").map((p) => p.trim()).filter(Boolean);
|
|
13
13
|
}
|
|
14
|
+
function parseExporterConfigEntry(value, previous = []) {
|
|
15
|
+
return [...previous, value];
|
|
16
|
+
}
|
|
17
|
+
function parseExporterConfig(options, exporterType) {
|
|
18
|
+
const exporterConfig = {};
|
|
19
|
+
if (Array.isArray(options.exporterConfig)) {
|
|
20
|
+
for (const entry of options.exporterConfig) {
|
|
21
|
+
if (typeof entry === "string") {
|
|
22
|
+
const [key, ...valueParts] = entry.split("=");
|
|
23
|
+
const value = valueParts.join("=");
|
|
24
|
+
if (key && value !== void 0) {
|
|
25
|
+
exporterConfig[key.trim()] = value.trim();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
type: exporterType,
|
|
32
|
+
config: exporterConfig
|
|
33
|
+
};
|
|
34
|
+
}
|
|
14
35
|
var log = {
|
|
15
36
|
success: (message) => console.log(chalk.green("\u2713 ") + message),
|
|
16
37
|
error: (message) => console.error(chalk.red("\u2717 ") + message),
|
|
@@ -56,8 +77,8 @@ async function indexPages(config) {
|
|
|
56
77
|
log.text(` Project Directory: ${log.gray(config.projectDir)}`);
|
|
57
78
|
log.text(` Source Directory: ${log.gray(config.source)}`);
|
|
58
79
|
log.text(` Glob Pattern: ${log.gray(config.glob)}`);
|
|
59
|
-
log.text(`
|
|
60
|
-
log.text(`
|
|
80
|
+
log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);
|
|
81
|
+
log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);
|
|
61
82
|
log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);
|
|
62
83
|
if (config.exclude.length > 0) {
|
|
63
84
|
log.text(` Exclude Patterns: ${log.gray(config.exclude.join(", "))}`);
|
|
@@ -139,19 +160,10 @@ async function indexPages(config) {
|
|
|
139
160
|
log.text("");
|
|
140
161
|
log.text(log.bold("Saving index..."));
|
|
141
162
|
log.text("");
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
const searchIndexFile = join(generatedPath, config.indexFilename);
|
|
147
|
-
writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));
|
|
148
|
-
const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE
|
|
149
|
-
import index from "./generated/${config.indexFilename}";
|
|
150
|
-
export default index;
|
|
151
|
-
`;
|
|
152
|
-
const indexJsFile = join(outputPath, "index.js");
|
|
153
|
-
writeFileSync(indexJsFile, indexJsContent);
|
|
154
|
-
log.success(`Index saved to: ${log.cyan(relative(config.projectDir, searchIndexFile))}`);
|
|
163
|
+
const searchIndexExporter = createExporterFromConfig(config.searchExporter);
|
|
164
|
+
await searchIndexExporter.export(searchIndexData);
|
|
165
|
+
const indexPathDisplay = config.searchExporter.type === "fileBased" ? relative(config.projectDir, join(config.projectDir, config.searchExporter.config.indexPath)) : "configured location";
|
|
166
|
+
log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);
|
|
155
167
|
log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);
|
|
156
168
|
log.text(
|
|
157
169
|
` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), "utf8") / 1024).toFixed(2))} KB`
|
|
@@ -172,7 +184,10 @@ function probeSourceDirectory(projectDir) {
|
|
|
172
184
|
}
|
|
173
185
|
async function main() {
|
|
174
186
|
const program = new Command();
|
|
175
|
-
program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--
|
|
187
|
+
program.name("peam").description("Peam static site indexer (Next.js, Hugo, etc.)").version(packageJson.version).option("--source <path>", "Source directory containing HTML files (auto-detected if not provided)").option("--glob <pattern>", "Glob pattern for HTML files", "**/*.{html,htm}").option("--exporter <type>", "Search exporter type", "fileBased").option("--exporterConfig <key=value>", "Exporter config entry (repeatable)", parseExporterConfigEntry, [
|
|
188
|
+
`baseDir=${process.cwd()}`,
|
|
189
|
+
"indexPath=.peam/index.json"
|
|
190
|
+
]).option("--ignore-robots-txt", "Disable robots.txt checking").option("--robots-path <path>", "Custom path to robots.txt file").option("--exclude <patterns>", "Comma-separated exclude patterns", parseExcludePatterns, []).option("--project-dir <path>", "Project root directory", process.cwd()).addHelpText(
|
|
176
191
|
"after",
|
|
177
192
|
`
|
|
178
193
|
Examples:
|
|
@@ -185,8 +200,11 @@ Examples:
|
|
|
185
200
|
# Next.js
|
|
186
201
|
$ peam --source .next
|
|
187
202
|
|
|
188
|
-
# Custom
|
|
189
|
-
$ peam --source dist --
|
|
203
|
+
# Custom index path using file-based exporter
|
|
204
|
+
$ peam --source dist --exporterConfig indexPath=.search/index.json
|
|
205
|
+
|
|
206
|
+
# Multiple exporter config entries
|
|
207
|
+
$ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp
|
|
190
208
|
|
|
191
209
|
# Exclude patterns
|
|
192
210
|
$ peam --exclude "/admin/**,/api/*,/private-*"
|
|
@@ -212,11 +230,11 @@ More information: https://peam.ai
|
|
|
212
230
|
process.exit(1);
|
|
213
231
|
}
|
|
214
232
|
}
|
|
233
|
+
const searchExporter = parseExporterConfig(options, options.exporter);
|
|
215
234
|
const config = {
|
|
216
235
|
source: sourceDir,
|
|
217
236
|
glob: options.glob,
|
|
218
|
-
|
|
219
|
-
indexFilename: options.indexFilename,
|
|
237
|
+
searchExporter,
|
|
220
238
|
respectRobotsTxt: !options.ignoreRobotsTxt,
|
|
221
239
|
robotsTxtPath: options.robotsPath,
|
|
222
240
|
exclude: options.exclude,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n outputDir: string;\n indexFilename: string;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Output Directory: ${log.gray(config.outputDir)}`);\n log.text(` Index Filename: ${log.gray(config.indexFilename)}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const outputPath = join(config.projectDir, config.outputDir);\n mkdirSync(outputPath, { recursive: true });\n\n const generatedPath = join(outputPath, 'generated');\n mkdirSync(generatedPath, { recursive: true });\n\n const searchIndexFile = join(generatedPath, config.indexFilename);\n writeFileSync(searchIndexFile, JSON.stringify(searchIndexData));\n\n const indexJsContent = `// Auto-generated by Peam - DO NOT EDIT THIS FILE\nimport index from \"./generated/${config.indexFilename}\";\nexport default index;\n`;\n const indexJsFile = join(outputPath, 'index.js');\n writeFileSync(indexJsFile, indexJsContent);\n\n log.success(`Index saved to: ${log.cyan(relative(config.projectDir, searchIndexFile))}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--output-dir <path>', 'Output directory for index', '.peam')\n .option('--index-filename <name>', 'Name of index file', 'index.json')\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom output directory\n $ peam --source dist --glob \"**/*.html\"\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n outputDir: options.outputDir,\n indexFilename: options.indexFilename,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Peam Static Site Indexer\n *\n * Scans a static site output directory, discovers HTML files,\n * parses them into structured pages, and creates a searchable index.\n */\n\nimport { filePathToPathname, loadRobotsTxt, parseHTML, shouldIncludePath, type StructuredPage } from '@peam-ai/parser';\nimport { buildSearchIndex, createExporterFromConfig, type SearchExporterConfig } from '@peam-ai/search';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport fg from 'fast-glob';\nimport { existsSync, readFileSync } from 'fs';\nimport { join, relative } from 'path';\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\ninterface IndexerConfig {\n source: string;\n searchExporter: SearchExporterConfig;\n respectRobotsTxt: boolean;\n robotsTxtPath?: string;\n exclude: string[];\n glob: string;\n projectDir: string;\n}\n\ninterface DiscoveredPage {\n pathname: string;\n htmlFilePath: string;\n relativeHtmlPath: string;\n}\n\nfunction parseExcludePatterns(value: string): string[] {\n return value\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n}\n\n/**\n * Parse exporterConfig key=value pairs\n */\nfunction parseExporterConfigEntry(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n\n/**\n * Parse command line options and extract exporter configuration dynamically.\n * Supports --exporterConfig key=value pairs\n */\nfunction parseExporterConfig(options: Record<string, unknown>, exporterType: string): SearchExporterConfig {\n const exporterConfig: Record<string, unknown> = {};\n\n // Parse key=value pairs from --exporterConfig options\n if (Array.isArray(options.exporterConfig)) {\n for (const entry of options.exporterConfig) {\n if (typeof entry === 'string') {\n const [key, ...valueParts] = entry.split('=');\n const value = valueParts.join('=');\n if (key && value !== undefined) {\n exporterConfig[key.trim()] = value.trim();\n }\n }\n }\n }\n\n return {\n type: exporterType,\n config: exporterConfig,\n } as unknown as SearchExporterConfig;\n}\n\nconst log = {\n success: (message: string) => console.log(chalk.green('✓ ') + message),\n error: (message: string) => console.error(chalk.red('✗ ') + message),\n warn: (message: string) => console.warn(chalk.yellow('⚠ ') + message),\n info: (message: string) => console.log(chalk.blue('ℹ ') + message),\n text: (message: string) => console.log(message),\n\n cyan: (text: string) => chalk.cyan(text),\n gray: (text: string) => chalk.gray(text),\n bold: (text: string) => chalk.bold(text),\n yellow: (text: string) => chalk.yellow(text),\n red: (text: string) => chalk.red(text),\n green: (text: string) => chalk.green(text),\n};\n\nasync function discoverHtmlFiles(\n sourceDir: string,\n globPattern: string,\n projectDir: string\n): Promise<DiscoveredPage[]> {\n const pages: DiscoveredPage[] = [];\n\n try {\n const sourceFullPath = join(projectDir, sourceDir);\n\n const htmlFiles = await fg(globPattern, {\n cwd: sourceFullPath,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: ['**/_next/**', '**/_astro/**', '**/404.{html,htm}', '**/500.{html,htm}'],\n });\n\n for (const htmlFilePath of htmlFiles) {\n const relativePath = relative(sourceFullPath, htmlFilePath);\n const pathname = filePathToPathname(relativePath);\n\n pages.push({\n pathname,\n htmlFilePath,\n relativeHtmlPath: relativePath,\n });\n }\n } catch (error) {\n log.warn(`Error discovering HTML files: ${error}`);\n }\n\n return pages;\n}\n\nasync function indexPages(config: IndexerConfig): Promise<void> {\n log.text('\\n' + log.bold(log.cyan('Peam Static Site Indexer')) + '\\n');\n log.text(log.bold('Configuration:'));\n log.text(` Project Directory: ${log.gray(config.projectDir)}`);\n log.text(` Source Directory: ${log.gray(config.source)}`);\n log.text(` Glob Pattern: ${log.gray(config.glob)}`);\n log.text(` Exporter Type: ${log.gray(config.searchExporter.type)}`);\n log.text(` Exporter Config: ${log.gray(JSON.stringify(config.searchExporter.config, null, 2))}`);\n log.text(` Respect robots.txt: ${log.gray(config.respectRobotsTxt.toString())}`);\n if (config.exclude.length > 0) {\n log.text(` Exclude Patterns: ${log.gray(config.exclude.join(', '))}`);\n }\n log.text('');\n\n const sourcePath = join(config.projectDir, config.source);\n if (!existsSync(sourcePath)) {\n log.error(`Source directory not found: ${sourcePath}`);\n log.text(log.yellow(' Please build your site first or specify the correct --source directory'));\n process.exit(1);\n }\n\n const searchPaths = [join(config.source, 'robots.txt'), 'public/robots.txt', 'robots.txt'];\n\n const robotsResult = config.respectRobotsTxt\n ? loadRobotsTxt(config.projectDir, searchPaths, config.robotsTxtPath)\n : null;\n\n if (robotsResult && config.respectRobotsTxt) {\n log.info(`robots.txt loaded from ${log.cyan(relative(config.projectDir, robotsResult.path))}`);\n } else if (config.respectRobotsTxt) {\n log.info('No robots.txt found, all paths will be indexed');\n }\n\n log.text(log.bold('Discovering HTML files...'));\n log.text('');\n log.text(` Scanning: ${log.gray(config.source)}`);\n log.text(` Pattern: ${log.gray(config.glob)}`);\n log.text('');\n\n const discoveredPages = await discoverHtmlFiles(config.source, config.glob, config.projectDir);\n\n if (discoveredPages.length === 0) {\n log.text('');\n log.warn('No HTML files found');\n log.text(log.yellow(' Check that your source directory contains HTML files'));\n log.text(log.yellow(` Source: ${sourcePath}`));\n log.text(log.yellow(` Pattern: ${config.glob}`));\n process.exit(1);\n }\n\n const uniquePages = new Map<string, DiscoveredPage>();\n for (const page of discoveredPages) {\n if (!uniquePages.has(page.pathname)) {\n uniquePages.set(page.pathname, page);\n }\n }\n\n log.text('');\n log.success(`Found ${log.bold(uniquePages.size.toString())} unique pages`);\n log.text('');\n log.text(log.bold('Processing pages...'));\n log.text('');\n\n const processedPages: Array<{\n path: string;\n htmlFile: string;\n structuredPage: StructuredPage;\n }> = [];\n\n for (const [pathname, page] of uniquePages) {\n const result = shouldIncludePath(pathname, robotsResult?.parser ?? null, config.exclude, config.respectRobotsTxt);\n\n if (!result.included) {\n // Log the specific reason for exclusion\n if (result.reason === 'robots-txt') {\n log.error(`Excluded by robots.txt: ${pathname}`);\n } else if (result.reason === 'exclude-pattern') {\n log.error(`Excluded by pattern: ${pathname}`);\n }\n continue;\n }\n\n try {\n const html = readFileSync(page.htmlFilePath, 'utf-8');\n\n const structuredPage = parseHTML(html);\n\n if (!structuredPage) {\n log.warn(`No content extracted from ${log.gray(pathname)}`);\n continue;\n }\n\n log.success(`${log.cyan(pathname)}`);\n\n processedPages.push({\n path: pathname,\n htmlFile: page.relativeHtmlPath,\n structuredPage,\n });\n } catch (error) {\n log.error(`Error processing ${log.gray(pathname)}: ${error}`);\n }\n }\n\n log.text('');\n log.success(`Successfully processed ${log.bold(processedPages.length.toString())} pages`);\n log.text('');\n log.text(log.bold('Creating search index...'));\n log.text('');\n\n const searchIndexData = await buildSearchIndex(processedPages);\n\n log.success(`Added ${log.bold(processedPages.length.toString())} pages to search index`);\n log.text('');\n log.text(log.bold('Saving index...'));\n log.text('');\n\n const searchIndexExporter = createExporterFromConfig(config.searchExporter);\n await searchIndexExporter.export(searchIndexData);\n\n const indexPathDisplay =\n config.searchExporter.type === 'fileBased'\n ? relative(config.projectDir, join(config.projectDir, config.searchExporter.config.indexPath))\n : 'configured location';\n\n log.success(`Index saved to: ${log.cyan(indexPathDisplay)}`);\n log.text(` Total pages indexed: ${log.bold(processedPages.length.toString())}`);\n log.text(\n ` Index size: ${log.bold((Buffer.byteLength(JSON.stringify(searchIndexData), 'utf8') / 1024).toFixed(2))} KB`\n );\n log.text('');\n log.success(log.bold('Indexing complete!'));\n log.text('');\n}\n\nfunction probeSourceDirectory(projectDir: string): string | null {\n const commonDirs = ['.next', '.build', '.out'];\n\n for (const dir of commonDirs) {\n const fullPath = join(projectDir, dir);\n if (existsSync(fullPath)) {\n return dir;\n }\n }\n\n return null;\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name('peam')\n .description('Peam static site indexer (Next.js, Hugo, etc.)')\n .version(packageJson.version)\n .option('--source <path>', 'Source directory containing HTML files (auto-detected if not provided)')\n .option('--glob <pattern>', 'Glob pattern for HTML files', '**/*.{html,htm}')\n .option('--exporter <type>', 'Search exporter type', 'fileBased')\n .option('--exporterConfig <key=value>', 'Exporter config entry (repeatable)', parseExporterConfigEntry, [\n `baseDir=${process.cwd()}`,\n 'indexPath=.peam/index.json',\n ])\n .option('--ignore-robots-txt', 'Disable robots.txt checking')\n .option('--robots-path <path>', 'Custom path to robots.txt file')\n .option('--exclude <patterns>', 'Comma-separated exclude patterns', parseExcludePatterns, [])\n .option('--project-dir <path>', 'Project root directory', process.cwd())\n .addHelpText(\n 'after',\n `\nExamples:\n # Auto-detect build directory\n $ peam\n\n # Hugo\n $ peam --source public\n\n # Next.js\n $ peam --source .next\n\n # Custom index path using file-based exporter\n $ peam --source dist --exporterConfig indexPath=.search/index.json\n\n # Multiple exporter config entries\n $ peam --exporterConfig indexPath=custom/index.json --exporterConfig baseDir=/tmp\n\n # Exclude patterns\n $ peam --exclude \"/admin/**,/api/*,/private-*\"\n\nFor Next.js 15+, the @peam-ai/next integration is recommended for production use.\n\nMore information: https://peam.ai\n `\n )\n .parse();\n\n const options = program.opts();\n\n try {\n let sourceDir = options.source;\n if (!sourceDir) {\n const probedDir = probeSourceDirectory(options.projectDir);\n if (probedDir) {\n sourceDir = probedDir;\n log.info(`Auto-detected source directory: ${log.cyan(probedDir)}`);\n log.text('');\n } else {\n log.error('No build output directory found');\n log.text(log.yellow(' Searched for: .next, .build, .out'));\n log.text(log.yellow(' Please build your site first or specify --source <directory>'));\n process.exit(1);\n }\n }\n\n const searchExporter = parseExporterConfig(options, options.exporter);\n\n const config: IndexerConfig = {\n source: sourceDir,\n glob: options.glob,\n searchExporter,\n respectRobotsTxt: !options.ignoreRobotsTxt,\n robotsTxtPath: options.robotsPath,\n exclude: options.exclude,\n projectDir: options.projectDir,\n };\n\n await indexPages(config);\n } catch (error) {\n log.text('');\n log.error(`Fatal error: ${error}`);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n main();\n}\n\nexport { indexPages, type IndexerConfig };\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "peam",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Peam - AI that knows your website.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -64,11 +64,11 @@
|
|
|
64
64
|
"chalk": "^4.1.2",
|
|
65
65
|
"commander": "^12.1.0",
|
|
66
66
|
"fast-glob": "^3.3.3",
|
|
67
|
-
"@peam-ai/logger": "0.1.
|
|
68
|
-
"@peam-ai/
|
|
69
|
-
"@peam-ai/
|
|
70
|
-
"@peam-ai/
|
|
71
|
-
"@peam-ai/
|
|
67
|
+
"@peam-ai/logger": "0.1.3",
|
|
68
|
+
"@peam-ai/search": "0.1.3",
|
|
69
|
+
"@peam-ai/parser": "0.1.3",
|
|
70
|
+
"@peam-ai/client": "0.1.3",
|
|
71
|
+
"@peam-ai/server": "0.1.3"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@types/node": "^20.0.0",
|