@stati/core 1.6.3 → 1.7.0

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.
Files changed (82) hide show
  1. package/README.md +2 -2
  2. package/dist/core/build.d.ts.map +1 -1
  3. package/dist/core/build.js +45 -8
  4. package/dist/core/content.d.ts.map +1 -1
  5. package/dist/core/content.js +1 -2
  6. package/dist/core/dev.d.ts.map +1 -1
  7. package/dist/core/dev.js +2 -5
  8. package/dist/core/index.d.ts +13 -0
  9. package/dist/core/index.d.ts.map +1 -0
  10. package/dist/core/index.js +12 -0
  11. package/dist/core/invalidate.d.ts.map +1 -1
  12. package/dist/core/invalidate.js +13 -7
  13. package/dist/core/isg/build-lock.js +1 -1
  14. package/dist/core/isg/deps.d.ts.map +1 -1
  15. package/dist/core/isg/deps.js +1 -3
  16. package/dist/core/isg/hash.js +1 -1
  17. package/dist/core/isg/index.d.ts +16 -0
  18. package/dist/core/isg/index.d.ts.map +1 -0
  19. package/dist/core/isg/index.js +22 -0
  20. package/dist/core/isg/manifest.js +1 -1
  21. package/dist/core/preview.d.ts.map +1 -1
  22. package/dist/core/preview.js +1 -2
  23. package/dist/core/templates.d.ts.map +1 -1
  24. package/dist/core/templates.js +4 -7
  25. package/dist/core/utils/index.d.ts +16 -0
  26. package/dist/core/utils/index.d.ts.map +1 -0
  27. package/dist/core/utils/index.js +22 -0
  28. package/dist/core/utils/partial-validation.d.ts.map +1 -1
  29. package/dist/core/utils/partial-validation.js +2 -1
  30. package/dist/index.d.ts +6 -8
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +3 -4
  33. package/dist/seo/auto-inject.d.ts +48 -0
  34. package/dist/seo/auto-inject.d.ts.map +1 -0
  35. package/dist/seo/auto-inject.js +108 -0
  36. package/dist/seo/generator.d.ts +77 -0
  37. package/dist/seo/generator.d.ts.map +1 -0
  38. package/dist/seo/generator.js +320 -0
  39. package/dist/seo/index.d.ts +12 -0
  40. package/dist/seo/index.d.ts.map +1 -0
  41. package/dist/seo/index.js +15 -0
  42. package/dist/seo/robots.d.ts +84 -0
  43. package/dist/seo/robots.d.ts.map +1 -0
  44. package/dist/seo/robots.js +165 -0
  45. package/dist/seo/sitemap.d.ts +37 -0
  46. package/dist/seo/sitemap.d.ts.map +1 -0
  47. package/dist/seo/sitemap.js +320 -0
  48. package/dist/seo/utils/escape-and-validation.d.ts +99 -0
  49. package/dist/seo/utils/escape-and-validation.d.ts.map +1 -0
  50. package/dist/seo/utils/escape-and-validation.js +319 -0
  51. package/dist/seo/utils/index.d.ts +7 -0
  52. package/dist/seo/utils/index.d.ts.map +1 -0
  53. package/dist/seo/utils/index.js +8 -0
  54. package/dist/seo/utils/url.d.ts +46 -0
  55. package/dist/seo/utils/url.d.ts.map +1 -0
  56. package/dist/seo/utils/url.js +66 -0
  57. package/dist/seo/utils.d.ts +94 -0
  58. package/dist/seo/utils.d.ts.map +1 -0
  59. package/dist/seo/utils.js +304 -0
  60. package/dist/types/config.d.ts +58 -0
  61. package/dist/types/config.d.ts.map +1 -1
  62. package/dist/types/content.d.ts +181 -0
  63. package/dist/types/content.d.ts.map +1 -1
  64. package/dist/types/index.d.ts +5 -2
  65. package/dist/types/index.d.ts.map +1 -1
  66. package/dist/types/index.js +1 -1
  67. package/dist/types/seo.d.ts +69 -0
  68. package/dist/types/seo.d.ts.map +1 -0
  69. package/dist/types/seo.js +36 -0
  70. package/dist/types/sitemap.d.ts +94 -0
  71. package/dist/types/sitemap.d.ts.map +1 -0
  72. package/dist/types/sitemap.js +4 -0
  73. package/package.json +1 -1
  74. package/dist/core/utils/partials.d.ts +0 -24
  75. package/dist/core/utils/partials.d.ts.map +0 -1
  76. package/dist/core/utils/partials.js +0 -85
  77. package/dist/tests/utils/test-mocks.d.ts +0 -69
  78. package/dist/tests/utils/test-mocks.d.ts.map +0 -1
  79. package/dist/tests/utils/test-mocks.js +0 -125
  80. package/dist/types.d.ts +0 -543
  81. package/dist/types.d.ts.map +0 -1
  82. package/dist/types.js +0 -1
@@ -0,0 +1,69 @@
1
+ /**
2
+ * SEO processing type definitions
3
+ */
4
+ import type { PageModel } from './content.js';
5
+ import type { StatiConfig } from './config.js';
6
+ import type { Logger } from './logging.js';
7
+ /**
8
+ * Enum for SEO tag types used in selective generation and detection.
9
+ *
10
+ * Used to control which SEO tags are generated or excluded during rendering.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Generate only title and description
15
+ * const include = new Set([SEOTagType.Title, SEOTagType.Description]);
16
+ * generateSEOMetadata({ page, config, siteUrl, include });
17
+ * ```
18
+ */
19
+ export declare enum SEOTagType {
20
+ /** HTML <title> tag */
21
+ Title = "title",
22
+ /** Meta description tag */
23
+ Description = "description",
24
+ /** Meta keywords tag */
25
+ Keywords = "keywords",
26
+ /** Meta author tag */
27
+ Author = "author",
28
+ /** Meta robots tag */
29
+ Robots = "robots",
30
+ /** Canonical link tag */
31
+ Canonical = "canonical",
32
+ /** Open Graph meta tags (og:*) */
33
+ OpenGraph = "opengraph",
34
+ /** Twitter Card meta tags (twitter:*) */
35
+ Twitter = "twitter",
36
+ /** JSON-LD structured data */
37
+ StructuredData = "structuredData"
38
+ }
39
+ /**
40
+ * Context object for SEO metadata generation.
41
+ * Contains all necessary information to generate SEO tags for a page.
42
+ */
43
+ export interface SEOContext {
44
+ /** The page to generate SEO metadata for */
45
+ page: PageModel;
46
+ /** Site configuration */
47
+ config: StatiConfig;
48
+ /** Base site URL (e.g., 'https://example.com') */
49
+ siteUrl: string;
50
+ /** Logger for debug output */
51
+ logger: Logger;
52
+ /** Set of tag types to exclude from generation (blacklist mode) */
53
+ exclude?: Set<SEOTagType>;
54
+ /** Set of tag types to include in generation (whitelist mode) */
55
+ include?: Set<SEOTagType>;
56
+ }
57
+ /**
58
+ * Result of SEO metadata validation.
59
+ * Contains validation status and any errors or warnings.
60
+ */
61
+ export interface SEOValidationResult {
62
+ /** Whether the SEO metadata is valid */
63
+ valid: boolean;
64
+ /** Array of validation errors (blocking issues) */
65
+ errors: string[];
66
+ /** Array of validation warnings (non-blocking recommendations) */
67
+ warnings: string[];
68
+ }
69
+ //# sourceMappingURL=seo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/types/seo.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,oBAAY,UAAU;IACpB,uBAAuB;IACvB,KAAK,UAAU;IACf,2BAA2B;IAC3B,WAAW,gBAAgB;IAC3B,wBAAwB;IACxB,QAAQ,aAAa;IACrB,sBAAsB;IACtB,MAAM,WAAW;IACjB,sBAAsB;IACtB,MAAM,WAAW;IACjB,yBAAyB;IACzB,SAAS,cAAc;IACvB,kCAAkC;IAClC,SAAS,cAAc;IACvB,yCAAyC;IACzC,OAAO,YAAY;IACnB,8BAA8B;IAC9B,cAAc,mBAAmB;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,4CAA4C;IAC5C,IAAI,EAAE,SAAS,CAAC;IAChB,yBAAyB;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IAC1B,iEAAiE;IACjE,OAAO,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,KAAK,EAAE,OAAO,CAAC;IACf,mDAAmD;IACnD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * SEO processing type definitions
3
+ */
4
+ /**
5
+ * Enum for SEO tag types used in selective generation and detection.
6
+ *
7
+ * Used to control which SEO tags are generated or excluded during rendering.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * // Generate only title and description
12
+ * const include = new Set([SEOTagType.Title, SEOTagType.Description]);
13
+ * generateSEOMetadata({ page, config, siteUrl, include });
14
+ * ```
15
+ */
16
+ export var SEOTagType;
17
+ (function (SEOTagType) {
18
+ /** HTML <title> tag */
19
+ SEOTagType["Title"] = "title";
20
+ /** Meta description tag */
21
+ SEOTagType["Description"] = "description";
22
+ /** Meta keywords tag */
23
+ SEOTagType["Keywords"] = "keywords";
24
+ /** Meta author tag */
25
+ SEOTagType["Author"] = "author";
26
+ /** Meta robots tag */
27
+ SEOTagType["Robots"] = "robots";
28
+ /** Canonical link tag */
29
+ SEOTagType["Canonical"] = "canonical";
30
+ /** Open Graph meta tags (og:*) */
31
+ SEOTagType["OpenGraph"] = "opengraph";
32
+ /** Twitter Card meta tags (twitter:*) */
33
+ SEOTagType["Twitter"] = "twitter";
34
+ /** JSON-LD structured data */
35
+ SEOTagType["StructuredData"] = "structuredData";
36
+ })(SEOTagType || (SEOTagType = {}));
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Sitemap generation type definitions
3
+ */
4
+ import type { PageModel } from './content.js';
5
+ import type { StatiConfig } from './config.js';
6
+ /**
7
+ * Change frequency hint for sitemap entries.
8
+ * Indicates how frequently the page content is likely to change.
9
+ *
10
+ * @see https://www.sitemaps.org/protocol.html
11
+ */
12
+ export type ChangeFrequency = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
13
+ /**
14
+ * A single entry in the sitemap.
15
+ * Represents one URL with its associated metadata.
16
+ */
17
+ export interface SitemapEntry {
18
+ /** Full URL of the page */
19
+ url: string;
20
+ /** Last modification date (ISO 8601 format: YYYY-MM-DD) */
21
+ lastmod?: string;
22
+ /** Change frequency hint */
23
+ changefreq?: ChangeFrequency;
24
+ /** Priority of this URL relative to other URLs on the site (0.0 to 1.0) */
25
+ priority?: number;
26
+ }
27
+ /**
28
+ * Configuration for sitemap generation.
29
+ * Controls how sitemaps are generated and which pages are included.
30
+ */
31
+ export interface SitemapConfig {
32
+ /** Enable sitemap generation (default: false) */
33
+ enabled?: boolean;
34
+ /** Default priority for all pages (0.0-1.0, default: 0.5) */
35
+ defaultPriority?: number;
36
+ /** Default change frequency for all pages (default: 'monthly') */
37
+ defaultChangeFreq?: ChangeFrequency;
38
+ /** Glob patterns for pages to exclude from sitemap */
39
+ excludePatterns?: string[];
40
+ /** Glob patterns for pages to include in sitemap (if specified, only these are included) */
41
+ includePatterns?: string[];
42
+ /** Custom filter function for fine-grained control over page inclusion */
43
+ filter?: (page: PageModel) => boolean;
44
+ /**
45
+ * Transform URL before adding to sitemap.
46
+ * Useful for adding query parameters, changing domains, etc.
47
+ */
48
+ transformUrl?: (url: string, page: PageModel, config: StatiConfig) => string;
49
+ /**
50
+ * Transform sitemap entry before adding to sitemap.
51
+ * Return null to exclude the entry. Allows complete control over entry metadata.
52
+ */
53
+ transformEntry?: (entry: SitemapEntry, page: PageModel) => SitemapEntry | null;
54
+ /**
55
+ * Priority rules based on URL patterns.
56
+ * Applied in order, first match wins.
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * priorityRules: [
61
+ * { pattern: '/blog/**', priority: 0.8 },
62
+ * { pattern: '/docs/**', priority: 0.9 },
63
+ * { pattern: '/', priority: 1.0 }
64
+ * ]
65
+ * ```
66
+ */
67
+ priorityRules?: Array<{
68
+ pattern: string;
69
+ priority: number;
70
+ }>;
71
+ /**
72
+ * Generate sitemap index file when splitting into multiple sitemaps.
73
+ * Required when site has >50,000 URLs.
74
+ */
75
+ generateIndex?: boolean;
76
+ }
77
+ /**
78
+ * Result of sitemap generation.
79
+ * Contains the generated XML and metadata about the sitemap.
80
+ */
81
+ export interface SitemapGenerationResult {
82
+ /** Generated sitemap XML string (index XML if multiple sitemaps) */
83
+ xml: string;
84
+ /** Number of entries in the sitemap(s) */
85
+ entryCount: number;
86
+ /** Size of the main sitemap/index in bytes */
87
+ sizeInBytes: number;
88
+ /** Individual sitemap files (when split into multiple sitemaps) */
89
+ sitemaps?: Array<{
90
+ filename: string;
91
+ xml: string;
92
+ }>;
93
+ }
94
+ //# sourceMappingURL=sitemap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap.d.ts","sourceRoot":"","sources":["../../src/types/sitemap.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GACvB,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,CAAC;AAEZ;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,eAAe,CAAC;IACpC,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,4FAA4F;IAC5F,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,0EAA0E;IAC1E,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IACtC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,KAAK,MAAM,CAAC;IAC7E;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,KAAK,YAAY,GAAG,IAAI,CAAC;IAC/E;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Sitemap generation type definitions
3
+ */
4
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stati/core",
3
- "version": "1.6.3",
3
+ "version": "1.7.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,24 +0,0 @@
1
- import type { StatiConfig } from '../../types.js';
2
- export interface PartialEntry {
3
- name: string;
4
- absPath: string;
5
- relFromSrc: string;
6
- }
7
- /**
8
- * Scan underscore folders from root to the page's directory for .eta partials.
9
- * Returns structured entries usable by both renderer and ISG deps.
10
- */
11
- export declare function scanPartialsHierarchy(pageRelativePath: string, config: StatiConfig): Promise<PartialEntry[]>;
12
- /**
13
- * Build the list of directories to scan for partials from root → current page directory.
14
- */
15
- export declare function buildDirsToScan(pageRelativePath: string): string[];
16
- /**
17
- * Renderer-focused partial discovery.
18
- * Matches historical renderer behavior used by templates tests:
19
- * - Only scans the current page directory (not parents)
20
- * - First finds underscore folders (e.g. "_partials/")
21
- * - Then finds .eta files within those folders, returning relative paths like "_partials/header.eta"
22
- */
23
- export declare function scanPartialsForRenderer(pageRelativePath: string, config: StatiConfig): Promise<PartialEntry[]>;
24
- //# sourceMappingURL=partials.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"partials.d.ts","sourceRoot":"","sources":["../../../src/core/utils/partials.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CA2BzB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,EAAE,CASlE;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CAkCzB"}
@@ -1,85 +0,0 @@
1
- // dedup: partials scanning centralized in utils/partials.ts
2
- import { join, dirname, relative, basename, posix } from 'path';
3
- import glob from 'fast-glob';
4
- import { resolveSrcDir } from './paths.js';
5
- /**
6
- * Scan underscore folders from root to the page's directory for .eta partials.
7
- * Returns structured entries usable by both renderer and ISG deps.
8
- */
9
- export async function scanPartialsHierarchy(pageRelativePath, config) {
10
- const srcDir = resolveSrcDir(config);
11
- const entries = [];
12
- const dirsToScan = buildDirsToScan(pageRelativePath);
13
- for (const dir of dirsToScan) {
14
- const searchDir = dir ? join(srcDir, dir) : srcDir;
15
- const normalizedSearchDir = searchDir.replace(/\\/g, '/');
16
- const pattern = posix.join(normalizedSearchDir, '_*/**/*.eta');
17
- try {
18
- const files = (await glob(pattern, { absolute: true }));
19
- for (const file of files) {
20
- entries.push({
21
- name: basename(file, '.eta'),
22
- absPath: file,
23
- relFromSrc: relative(srcDir, file),
24
- });
25
- }
26
- }
27
- catch {
28
- // Ignore errors for non-existent directories, continue scanning
29
- continue;
30
- }
31
- }
32
- return entries;
33
- }
34
- /**
35
- * Build the list of directories to scan for partials from root → current page directory.
36
- */
37
- export function buildDirsToScan(pageRelativePath) {
38
- const pageDir = dirname(pageRelativePath);
39
- const pathSegments = pageDir === '.' ? [] : pageDir.split(/[/\\]/);
40
- const dirsToScan = [''];
41
- for (let i = 0; i < pathSegments.length; i++) {
42
- dirsToScan.push(pathSegments.slice(0, i + 1).join('/'));
43
- }
44
- return dirsToScan;
45
- }
46
- /**
47
- * Renderer-focused partial discovery.
48
- * Matches historical renderer behavior used by templates tests:
49
- * - Only scans the current page directory (not parents)
50
- * - First finds underscore folders (e.g. "_partials/")
51
- * - Then finds .eta files within those folders, returning relative paths like "_partials/header.eta"
52
- */
53
- export async function scanPartialsForRenderer(pageRelativePath, config) {
54
- const srcDir = resolveSrcDir(config);
55
- const pageDirRel = dirname(pageRelativePath);
56
- const searchDir = pageDirRel === '.' ? srcDir : join(srcDir, pageDirRel);
57
- const entries = [];
58
- try {
59
- // Find underscore directories relative to the page directory
60
- const underscoreDirs = (await glob('_*/', { cwd: searchDir }));
61
- for (const dir of underscoreDirs) {
62
- try {
63
- // Find .eta files inside each underscore directory
64
- const etaFiles = (await glob('*.eta', { cwd: join(searchDir, dir) }));
65
- for (const file of etaFiles) {
66
- const rel = join(dir, file);
67
- entries.push({
68
- name: basename(file, '.eta'),
69
- absPath: join(searchDir, rel),
70
- relFromSrc: rel,
71
- });
72
- }
73
- }
74
- catch {
75
- // Ignore per-dir errors and continue
76
- continue;
77
- }
78
- }
79
- }
80
- catch {
81
- // Ignore errors and return empty list (graceful)
82
- return [];
83
- }
84
- return entries;
85
- }
@@ -1,69 +0,0 @@
1
- /**
2
- * Test mock utilities for Stati core tests.
3
- * Centralized mock factory functions to reduce duplication across test files.
4
- */
5
- /**
6
- * Creates a complete set of hoisted mocks for build tests.
7
- * Use this inside vi.hoisted() calls.
8
- */
9
- export declare function createBuildTestMocksObject(): {
10
- mockEnsureDir: import("vitest").Mock<(...args: any[]) => any>;
11
- mockWriteFile: import("vitest").Mock<(...args: any[]) => any>;
12
- mockCopy: import("vitest").Mock<(...args: any[]) => any>;
13
- mockCopyFile: import("vitest").Mock<(...args: any[]) => any>;
14
- mockRemove: import("vitest").Mock<(...args: any[]) => any>;
15
- mockPathExists: import("vitest").Mock<(...args: any[]) => any>;
16
- mockReaddir: import("vitest").Mock<(...args: any[]) => any>;
17
- mockStat: import("vitest").Mock<(...args: any[]) => any>;
18
- mockReadFile: import("vitest").Mock<(...args: any[]) => any>;
19
- mockLoadConfig: import("vitest").Mock<(...args: any[]) => any>;
20
- mockLoadContent: import("vitest").Mock<(...args: any[]) => any>;
21
- mockCreateMarkdownProcessor: import("vitest").Mock<(...args: any[]) => any>;
22
- mockRenderMarkdown: import("vitest").Mock<(...args: any[]) => any>;
23
- mockCreateTemplateEngine: import("vitest").Mock<(...args: any[]) => any>;
24
- mockRenderPage: import("vitest").Mock<(...args: any[]) => any>;
25
- mockBuildNavigation: import("vitest").Mock<(...args: any[]) => any>;
26
- mockLoadCacheManifest: import("vitest").Mock<(...args: any[]) => any>;
27
- mockSaveCacheManifest: import("vitest").Mock<(...args: any[]) => any>;
28
- mockShouldRebuildPage: import("vitest").Mock<(...args: any[]) => any>;
29
- mockCreateCacheEntry: import("vitest").Mock<(...args: any[]) => any>;
30
- mockUpdateCacheEntry: import("vitest").Mock<(...args: any[]) => any>;
31
- mockWithBuildLock: import("vitest").Mock<(...args: any[]) => any>;
32
- mockComputeContentHash: import("vitest").Mock<(...args: any[]) => any>;
33
- mockComputeFileHash: import("vitest").Mock<(...args: any[]) => any>;
34
- mockComputeInputsHash: import("vitest").Mock<(...args: any[]) => any>;
35
- mockTrackTemplateDependencies: import("vitest").Mock<(...args: any[]) => any>;
36
- mockComputeEffectiveTTL: import("vitest").Mock<(...args: any[]) => any>;
37
- mockComputeNextRebuildAt: import("vitest").Mock<(...args: any[]) => any>;
38
- mockIsPageFrozen: import("vitest").Mock<(...args: any[]) => any>;
39
- };
40
- /**
41
- * Creates fs-extra module mock implementation.
42
- */
43
- export declare function mockFsExtraModule(mocks: ReturnType<typeof createBuildTestMocksObject>): {
44
- default: {
45
- ensureDir: import("vitest").Mock<(...args: any[]) => any>;
46
- writeFile: import("vitest").Mock<(...args: any[]) => any>;
47
- copy: import("vitest").Mock<(...args: any[]) => any>;
48
- copyFile: import("vitest").Mock<(...args: any[]) => any>;
49
- remove: import("vitest").Mock<(...args: any[]) => any>;
50
- pathExists: import("vitest").Mock<(...args: any[]) => any>;
51
- readdir: import("vitest").Mock<(...args: any[]) => any>;
52
- stat: import("vitest").Mock<(...args: any[]) => any>;
53
- readFile: import("vitest").Mock<(...args: any[]) => any>;
54
- };
55
- };
56
- /**
57
- * Sets up standard module mocks for build tests.
58
- * Call this after creating mocks with vi.hoisted().
59
- */
60
- export declare function setupBuildModuleMocks(mocks: ReturnType<typeof createBuildTestMocksObject>): void;
61
- /**
62
- * Sets up ISG-specific module mocks.
63
- */
64
- export declare function setupISGModuleMocks(mocks: ReturnType<typeof createBuildTestMocksObject>): void;
65
- export declare const createFsExtraMocks: typeof createBuildTestMocksObject;
66
- export declare const createCoreModuleMocks: typeof createBuildTestMocksObject;
67
- export declare const createISGMocks: typeof createBuildTestMocksObject;
68
- export declare const createBuildTestMocks: typeof createBuildTestMocksObject;
69
- //# sourceMappingURL=test-mocks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"test-mocks.d.ts","sourceRoot":"","sources":["../../../src/tests/utils/test-mocks.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCzC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,0BAA0B,CAAC;;;;;;;;;;;;EAcrF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,0BAA0B,CAAC,QAuCzF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,0BAA0B,CAAC,QAgBvF;AAGD,eAAO,MAAM,kBAAkB,mCAA6B,CAAC;AAC7D,eAAO,MAAM,qBAAqB,mCAA6B,CAAC;AAChE,eAAO,MAAM,cAAc,mCAA6B,CAAC;AACzD,eAAO,MAAM,oBAAoB,mCAA6B,CAAC"}
@@ -1,125 +0,0 @@
1
- import { vi } from 'vitest';
2
- /**
3
- * Test mock utilities for Stati core tests.
4
- * Centralized mock factory functions to reduce duplication across test files.
5
- */
6
- /**
7
- * Creates a complete set of hoisted mocks for build tests.
8
- * Use this inside vi.hoisted() calls.
9
- */
10
- export function createBuildTestMocksObject() {
11
- return {
12
- // fs-extra mocks
13
- mockEnsureDir: vi.fn(),
14
- mockWriteFile: vi.fn(),
15
- mockCopy: vi.fn(),
16
- mockCopyFile: vi.fn(),
17
- mockRemove: vi.fn(),
18
- mockPathExists: vi.fn(),
19
- mockReaddir: vi.fn(),
20
- mockStat: vi.fn(),
21
- mockReadFile: vi.fn(),
22
- // core module mocks
23
- mockLoadConfig: vi.fn(),
24
- mockLoadContent: vi.fn(),
25
- mockCreateMarkdownProcessor: vi.fn(),
26
- mockRenderMarkdown: vi.fn(),
27
- mockCreateTemplateEngine: vi.fn(),
28
- mockRenderPage: vi.fn(),
29
- mockBuildNavigation: vi.fn(),
30
- // ISG mocks
31
- mockLoadCacheManifest: vi.fn(),
32
- mockSaveCacheManifest: vi.fn(),
33
- mockShouldRebuildPage: vi.fn(),
34
- mockCreateCacheEntry: vi.fn(),
35
- mockUpdateCacheEntry: vi.fn(),
36
- mockWithBuildLock: vi.fn(),
37
- // Hash mocks
38
- mockComputeContentHash: vi.fn(),
39
- mockComputeFileHash: vi.fn(),
40
- mockComputeInputsHash: vi.fn(),
41
- // Dependency tracking mocks
42
- mockTrackTemplateDependencies: vi.fn(),
43
- // TTL mocks
44
- mockComputeEffectiveTTL: vi.fn(),
45
- mockComputeNextRebuildAt: vi.fn(),
46
- mockIsPageFrozen: vi.fn(),
47
- };
48
- }
49
- /**
50
- * Creates fs-extra module mock implementation.
51
- */
52
- export function mockFsExtraModule(mocks) {
53
- return {
54
- default: {
55
- ensureDir: mocks.mockEnsureDir,
56
- writeFile: mocks.mockWriteFile,
57
- copy: mocks.mockCopy,
58
- copyFile: mocks.mockCopyFile,
59
- remove: mocks.mockRemove,
60
- pathExists: mocks.mockPathExists,
61
- readdir: mocks.mockReaddir,
62
- stat: mocks.mockStat,
63
- readFile: mocks.mockReadFile,
64
- },
65
- };
66
- }
67
- /**
68
- * Sets up standard module mocks for build tests.
69
- * Call this after creating mocks with vi.hoisted().
70
- */
71
- export function setupBuildModuleMocks(mocks) {
72
- vi.mock('fs-extra', () => mockFsExtraModule(mocks));
73
- vi.mock('../../config/loader.js', () => ({
74
- loadConfig: mocks.mockLoadConfig,
75
- }));
76
- vi.mock('../../core/content.js', () => ({
77
- loadContent: mocks.mockLoadContent,
78
- }));
79
- vi.mock('../../core/markdown.js', () => ({
80
- createMarkdownProcessor: mocks.mockCreateMarkdownProcessor,
81
- renderMarkdown: mocks.mockRenderMarkdown,
82
- }));
83
- vi.mock('../../core/templates.js', () => ({
84
- createTemplateEngine: mocks.mockCreateTemplateEngine,
85
- renderPage: mocks.mockRenderPage,
86
- }));
87
- vi.mock('../../core/navigation.js', () => ({
88
- buildNavigation: mocks.mockBuildNavigation,
89
- }));
90
- vi.mock('../../core/isg/manifest.js', () => ({
91
- loadCacheManifest: mocks.mockLoadCacheManifest,
92
- saveCacheManifest: mocks.mockSaveCacheManifest,
93
- }));
94
- vi.mock('../../core/isg/builder.js', () => ({
95
- shouldRebuildPage: mocks.mockShouldRebuildPage,
96
- createCacheEntry: mocks.mockCreateCacheEntry,
97
- updateCacheEntry: mocks.mockUpdateCacheEntry,
98
- }));
99
- vi.mock('../../core/isg/build-lock.js', () => ({
100
- withBuildLock: mocks.mockWithBuildLock,
101
- }));
102
- }
103
- /**
104
- * Sets up ISG-specific module mocks.
105
- */
106
- export function setupISGModuleMocks(mocks) {
107
- vi.mock('../../core/isg/hash.js', () => ({
108
- computeContentHash: mocks.mockComputeContentHash,
109
- computeFileHash: mocks.mockComputeFileHash,
110
- computeInputsHash: mocks.mockComputeInputsHash,
111
- }));
112
- vi.mock('../../core/isg/deps.js', () => ({
113
- trackTemplateDependencies: mocks.mockTrackTemplateDependencies,
114
- }));
115
- vi.mock('../../core/isg/ttl.js', () => ({
116
- computeEffectiveTTL: mocks.mockComputeEffectiveTTL,
117
- computeNextRebuildAt: mocks.mockComputeNextRebuildAt,
118
- isPageFrozen: mocks.mockIsPageFrozen,
119
- }));
120
- }
121
- // Legacy exports for compatibility
122
- export const createFsExtraMocks = createBuildTestMocksObject;
123
- export const createCoreModuleMocks = createBuildTestMocksObject;
124
- export const createISGMocks = createBuildTestMocksObject;
125
- export const createBuildTestMocks = createBuildTestMocksObject;