@stati/core 1.3.1 → 1.4.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.
- package/dist/config/loader.d.ts +7 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +17 -12
- package/dist/constants.d.ts +71 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +78 -0
- package/dist/core/build.d.ts +1 -1
- package/dist/core/build.d.ts.map +1 -1
- package/dist/core/build.js +94 -69
- package/dist/core/content.d.ts +1 -1
- package/dist/core/content.d.ts.map +1 -1
- package/dist/core/content.js +10 -5
- package/dist/core/dev.d.ts +1 -7
- package/dist/core/dev.d.ts.map +1 -1
- package/dist/core/dev.js +202 -141
- package/dist/core/invalidate.d.ts +1 -1
- package/dist/core/invalidate.d.ts.map +1 -1
- package/dist/core/invalidate.js +3 -3
- package/dist/core/isg/build-lock.d.ts.map +1 -1
- package/dist/core/isg/build-lock.js +4 -2
- package/dist/core/isg/builder.d.ts +1 -1
- package/dist/core/isg/builder.d.ts.map +1 -1
- package/dist/core/isg/deps.d.ts +1 -1
- package/dist/core/isg/deps.d.ts.map +1 -1
- package/dist/core/isg/deps.js +59 -78
- package/dist/core/isg/hash.d.ts.map +1 -1
- package/dist/core/isg/hash.js +26 -17
- package/dist/core/isg/manifest.d.ts +1 -1
- package/dist/core/isg/manifest.d.ts.map +1 -1
- package/dist/core/isg/manifest.js +21 -8
- package/dist/core/isg/ttl.d.ts +1 -1
- package/dist/core/isg/ttl.d.ts.map +1 -1
- package/dist/core/isg/ttl.js +6 -9
- package/dist/core/isg/validation.d.ts +1 -1
- package/dist/core/isg/validation.d.ts.map +1 -1
- package/dist/core/markdown.d.ts +1 -1
- package/dist/core/markdown.d.ts.map +1 -1
- package/dist/core/navigation.d.ts +1 -1
- package/dist/core/navigation.d.ts.map +1 -1
- package/dist/core/preview.d.ts +19 -0
- package/dist/core/preview.d.ts.map +1 -0
- package/dist/core/preview.js +163 -0
- package/dist/core/templates.d.ts +1 -1
- package/dist/core/templates.d.ts.map +1 -1
- package/dist/core/templates.js +28 -105
- package/dist/core/utils/fs.d.ts +37 -0
- package/dist/core/utils/fs.d.ts.map +1 -0
- package/dist/core/utils/fs.js +86 -0
- package/dist/core/utils/partials.d.ts +24 -0
- package/dist/core/utils/partials.d.ts.map +1 -0
- package/dist/core/utils/partials.js +85 -0
- package/dist/core/utils/paths.d.ts +67 -0
- package/dist/core/utils/paths.d.ts.map +1 -0
- package/dist/core/utils/paths.js +86 -0
- package/dist/core/utils/template-discovery.d.ts +34 -0
- package/dist/core/utils/template-discovery.d.ts.map +1 -0
- package/dist/core/utils/template-discovery.js +111 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/tests/utils/test-mocks.d.ts +69 -0
- package/dist/tests/utils/test-mocks.d.ts.map +1 -0
- package/dist/tests/utils/test-mocks.js +125 -0
- package/dist/types/config.d.ts +178 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +1 -0
- package/dist/types/content.d.ts +124 -0
- package/dist/types/content.d.ts.map +1 -0
- package/dist/types/content.js +4 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/isg.d.ts +103 -0
- package/dist/types/isg.d.ts.map +1 -0
- package/dist/types/isg.js +4 -0
- package/dist/types/logging.d.ts +113 -0
- package/dist/types/logging.d.ts.map +1 -0
- package/dist/types/logging.js +4 -0
- package/dist/types/navigation.d.ts +43 -0
- package/dist/types/navigation.d.ts.map +1 -0
- package/dist/types/navigation.js +4 -0
- package/dist/types.d.ts +10 -10
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { join, dirname } from 'path';
|
|
2
|
+
import { posix } from 'path';
|
|
3
|
+
import { pathExists } from './fs.js';
|
|
4
|
+
import { LAYOUT_TEMPLATE } from '../../constants.js';
|
|
5
|
+
import { resolveSrcDir } from './paths.js';
|
|
6
|
+
/**
|
|
7
|
+
* Shared template discovery utilities.
|
|
8
|
+
* Extracted from templates.ts and isg/deps.ts to eliminate duplication.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Determines if the given page is a collection index page.
|
|
12
|
+
* A collection index page is one whose URL matches a directory path that contains other pages.
|
|
13
|
+
*
|
|
14
|
+
* @param page - The page to check
|
|
15
|
+
* @param allPages - All pages in the site (optional for simplified check)
|
|
16
|
+
* @returns True if the page is a collection index page
|
|
17
|
+
*/
|
|
18
|
+
export function isCollectionIndexPage(page, allPages) {
|
|
19
|
+
// Root index page is always a collection index
|
|
20
|
+
if (page.url === '/') {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
// If we have all pages, do a proper check
|
|
24
|
+
if (allPages) {
|
|
25
|
+
// Check if this page's URL is a directory path that contains other pages
|
|
26
|
+
const pageUrlAsDir = page.url.endsWith('/') ? page.url : page.url + '/';
|
|
27
|
+
return allPages.some((otherPage) => otherPage.url !== page.url && otherPage.url.startsWith(pageUrlAsDir));
|
|
28
|
+
}
|
|
29
|
+
// Simplified version when we don't have all pages
|
|
30
|
+
// Assume any page ending in /index or at root is a collection page
|
|
31
|
+
return page.url.endsWith('/index') || page.slug === 'index';
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Discovers layout files by searching up the directory hierarchy.
|
|
35
|
+
* Supports both explicit layout specification and automatic discovery.
|
|
36
|
+
*
|
|
37
|
+
* @param pagePath - The path to the page (relative to srcDir)
|
|
38
|
+
* @param config - Stati configuration
|
|
39
|
+
* @param explicitLayout - Explicit layout name from front-matter
|
|
40
|
+
* @param isIndexPage - Whether this is an aggregation/index page (enables index.eta lookup)
|
|
41
|
+
* @returns The layout file path (relative to srcDir) or null if none found
|
|
42
|
+
*/
|
|
43
|
+
export async function discoverLayout(pagePath, config, explicitLayout, isIndexPage) {
|
|
44
|
+
// Early return if required config values are missing
|
|
45
|
+
if (!config.srcDir) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const srcDir = resolveSrcDir(config);
|
|
49
|
+
// If explicit layout is specified, use it
|
|
50
|
+
if (explicitLayout) {
|
|
51
|
+
const layoutPath = join(srcDir, `${explicitLayout}.eta`);
|
|
52
|
+
if (await pathExists(layoutPath)) {
|
|
53
|
+
return `${explicitLayout}.eta`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Get the directory of the current page
|
|
57
|
+
const pageDir = dirname(pagePath);
|
|
58
|
+
const pathSegments = pageDir === '.' ? [] : pageDir.split(/[/\\]/); // Handle both separators
|
|
59
|
+
// Search for layout.eta from current directory up to root
|
|
60
|
+
const dirsToSearch = [];
|
|
61
|
+
// Add current directory if not root
|
|
62
|
+
if (pathSegments.length > 0) {
|
|
63
|
+
for (let i = pathSegments.length; i > 0; i--) {
|
|
64
|
+
dirsToSearch.push(pathSegments.slice(0, i).join('/'));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Add root directory
|
|
68
|
+
dirsToSearch.push('');
|
|
69
|
+
for (const dir of dirsToSearch) {
|
|
70
|
+
// For index pages, first check for index.eta in each directory
|
|
71
|
+
if (isIndexPage) {
|
|
72
|
+
const indexLayoutPath = dir ? join(srcDir, dir, 'index.eta') : join(srcDir, 'index.eta');
|
|
73
|
+
if (await pathExists(indexLayoutPath)) {
|
|
74
|
+
// Return relative path with forward slashes for Eta
|
|
75
|
+
const relativePath = dir ? `${dir}/index.eta` : 'index.eta';
|
|
76
|
+
return posix.normalize(relativePath);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Then check for layout.eta as fallback
|
|
80
|
+
const layoutPath = dir ? join(srcDir, dir, LAYOUT_TEMPLATE) : join(srcDir, LAYOUT_TEMPLATE);
|
|
81
|
+
if (await pathExists(layoutPath)) {
|
|
82
|
+
// Return relative path with forward slashes for Eta
|
|
83
|
+
const relativePath = dir ? `${dir}/${LAYOUT_TEMPLATE}` : LAYOUT_TEMPLATE;
|
|
84
|
+
return posix.normalize(relativePath);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Gets the collection path for a given page URL.
|
|
91
|
+
* For index pages, returns the page's URL. For child pages, returns the parent directory.
|
|
92
|
+
*
|
|
93
|
+
* @param pageUrl - The page URL
|
|
94
|
+
* @returns The collection path
|
|
95
|
+
*/
|
|
96
|
+
export function getCollectionPathForPage(pageUrl) {
|
|
97
|
+
if (pageUrl === '/') {
|
|
98
|
+
return '/';
|
|
99
|
+
}
|
|
100
|
+
// If it's an index page (ends with /), return the URL as-is
|
|
101
|
+
if (pageUrl.endsWith('/')) {
|
|
102
|
+
return pageUrl;
|
|
103
|
+
}
|
|
104
|
+
// For non-index pages, return the parent directory
|
|
105
|
+
const lastSlashIndex = pageUrl.lastIndexOf('/');
|
|
106
|
+
if (lastSlashIndex === -1) {
|
|
107
|
+
return '/';
|
|
108
|
+
}
|
|
109
|
+
const parentPath = pageUrl.substring(0, lastSlashIndex + 1);
|
|
110
|
+
return parentPath === '' ? '/' : parentPath;
|
|
111
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,15 +19,17 @@
|
|
|
19
19
|
* await build({ clean: true });
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
export type { StatiConfig, PageModel, FrontMatter, BuildContext, PageContext, BuildHooks, NavNode, ISGConfig, AgingRule, BuildStats, } from './types.js';
|
|
22
|
+
export type { StatiConfig, PageModel, FrontMatter, BuildContext, PageContext, BuildHooks, NavNode, ISGConfig, AgingRule, BuildStats, } from './types/index.js';
|
|
23
23
|
export type { BuildOptions } from './core/build.js';
|
|
24
24
|
export type { DevServerOptions } from './core/dev.js';
|
|
25
|
+
export type { PreviewServerOptions } from './core/preview.js';
|
|
25
26
|
export type { InvalidationResult } from './core/invalidate.js';
|
|
26
27
|
export { build } from './core/build.js';
|
|
27
28
|
export { createDevServer } from './core/dev.js';
|
|
29
|
+
export { createPreviewServer } from './core/preview.js';
|
|
28
30
|
export { loadConfig } from './config/loader.js';
|
|
29
31
|
export { invalidate } from './core/invalidate.js';
|
|
30
|
-
import type { StatiConfig } from './types.js';
|
|
32
|
+
import type { StatiConfig } from './types/index.js';
|
|
31
33
|
/**
|
|
32
34
|
* Helper function for defining Stati configuration with TypeScript IntelliSense.
|
|
33
35
|
* Provides type checking and autocompletion for configuration options.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,YAAY,EACV,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,SAAS,EACT,SAAS,EACT,UAAU,GACX,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,YAAY,EACV,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,SAAS,EACT,SAAS,EACT,UAAU,GACX,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAE7D"}
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
export { build } from './core/build.js';
|
|
23
23
|
export { createDevServer } from './core/dev.js';
|
|
24
|
+
export { createPreviewServer } from './core/preview.js';
|
|
24
25
|
export { loadConfig } from './config/loader.js';
|
|
25
26
|
export { invalidate } from './core/invalidate.js';
|
|
26
27
|
/**
|
|
@@ -0,0 +1,69 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
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;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import type MarkdownIt from 'markdown-it';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration related type definitions
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Site-wide configuration settings.
|
|
7
|
+
* Contains global metadata and URL configuration for the static site.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const siteConfig: SiteConfig = {
|
|
12
|
+
* title: "My Awesome Blog",
|
|
13
|
+
* baseUrl: "https://myblog.com",
|
|
14
|
+
* defaultLocale: "en-US"
|
|
15
|
+
* };
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export interface SiteConfig {
|
|
19
|
+
/** The site's title, used in templates and metadata */
|
|
20
|
+
readonly title: string;
|
|
21
|
+
/** Base URL for the site, used for absolute URL generation */
|
|
22
|
+
readonly baseUrl: string;
|
|
23
|
+
/** Default locale for internationalization (optional) */
|
|
24
|
+
readonly defaultLocale?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Main configuration interface for Stati static site generator.
|
|
28
|
+
* Defines all options for site generation, including directories, templates, and features.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const config: StatiConfig = {
|
|
33
|
+
* srcDir: 'site',
|
|
34
|
+
* outDir: 'dist',
|
|
35
|
+
* staticDir: 'public',
|
|
36
|
+
* site: {
|
|
37
|
+
* title: 'My Blog',
|
|
38
|
+
* baseUrl: 'https://example.com'
|
|
39
|
+
* },
|
|
40
|
+
* markdown: {
|
|
41
|
+
* configure: (md) => md.use(somePlugin)
|
|
42
|
+
* }
|
|
43
|
+
* };
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export interface StatiConfig {
|
|
47
|
+
/** Source directory for content files (default: 'site') */
|
|
48
|
+
srcDir?: string;
|
|
49
|
+
/** Output directory for generated site (default: 'dist') */
|
|
50
|
+
outDir?: string;
|
|
51
|
+
/** Directory for static assets (default: 'public') */
|
|
52
|
+
staticDir?: string;
|
|
53
|
+
/** Site-wide configuration */
|
|
54
|
+
site: SiteConfig;
|
|
55
|
+
/** Markdown processing configuration */
|
|
56
|
+
markdown?: {
|
|
57
|
+
/** Array of plugins to load - each item can be a string (plugin name) or [string, options] tuple */
|
|
58
|
+
plugins?: (string | [string, unknown])[];
|
|
59
|
+
/** Function to configure the MarkdownIt instance */
|
|
60
|
+
configure?: (md: MarkdownIt) => void;
|
|
61
|
+
};
|
|
62
|
+
/** Eta template engine configuration */
|
|
63
|
+
eta?: {
|
|
64
|
+
/** Custom template filters */
|
|
65
|
+
filters?: Record<string, (x: unknown) => unknown>;
|
|
66
|
+
};
|
|
67
|
+
/** Incremental Static Generation configuration */
|
|
68
|
+
isg?: import('./isg.js').ISGConfig;
|
|
69
|
+
/** Development server configuration */
|
|
70
|
+
dev?: {
|
|
71
|
+
/** Port for development server (default: 3000) */
|
|
72
|
+
port?: number;
|
|
73
|
+
/** Host for development server (default: 'localhost') */
|
|
74
|
+
host?: string;
|
|
75
|
+
/** Whether to open browser automatically (default: false) */
|
|
76
|
+
open?: boolean;
|
|
77
|
+
};
|
|
78
|
+
/** Build lifecycle hooks */
|
|
79
|
+
hooks?: BuildHooks;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build context passed to build lifecycle hooks.
|
|
83
|
+
* Contains the full configuration and all loaded pages.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* const buildHook = async (ctx: BuildContext) => {
|
|
88
|
+
* console.log(`Building ${ctx.pages.length} pages`);
|
|
89
|
+
* console.log(`Output directory: ${ctx.config.outDir}`);
|
|
90
|
+
* };
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export interface BuildContext {
|
|
94
|
+
/** The resolved Stati configuration */
|
|
95
|
+
config: StatiConfig;
|
|
96
|
+
/** Array of all loaded page models */
|
|
97
|
+
pages: import('./content.js').PageModel[];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Page context passed to page-specific lifecycle hooks.
|
|
101
|
+
* Contains the current page being processed and site configuration.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const pageHook = async (ctx: PageContext) => {
|
|
106
|
+
* console.log(`Rendering page: ${ctx.page.slug}`);
|
|
107
|
+
* // Modify page content or metadata
|
|
108
|
+
* ctx.page.frontMatter.customField = 'processed';
|
|
109
|
+
* };
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export interface PageContext {
|
|
113
|
+
/** The page model being processed */
|
|
114
|
+
page: import('./content.js').PageModel;
|
|
115
|
+
/** The resolved Stati configuration */
|
|
116
|
+
config: StatiConfig;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Build lifecycle hooks for customizing the site generation process.
|
|
120
|
+
* Allows developers to inject custom logic at various stages of the build.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* const hooks: BuildHooks = {
|
|
125
|
+
* beforeAll: async (ctx) => {
|
|
126
|
+
* console.log('Starting build...');
|
|
127
|
+
* },
|
|
128
|
+
* beforeRender: async (ctx) => {
|
|
129
|
+
* // Add custom data to page context
|
|
130
|
+
* ctx.page.frontMatter.buildTime = new Date().toISOString();
|
|
131
|
+
* },
|
|
132
|
+
* afterAll: async (ctx) => {
|
|
133
|
+
* console.log(`Build complete! Generated ${ctx.pages.length} pages.`);
|
|
134
|
+
* }
|
|
135
|
+
* };
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export interface BuildHooks {
|
|
139
|
+
/** Called before starting the build process */
|
|
140
|
+
beforeAll?: (ctx: BuildContext) => Promise<void> | void;
|
|
141
|
+
/** Called after completing the build process */
|
|
142
|
+
afterAll?: (ctx: BuildContext) => Promise<void> | void;
|
|
143
|
+
/** Called before rendering each individual page */
|
|
144
|
+
beforeRender?: (ctx: PageContext) => Promise<void> | void;
|
|
145
|
+
/** Called after rendering each individual page */
|
|
146
|
+
afterRender?: (ctx: PageContext) => Promise<void> | void;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Statistics collected during the build process.
|
|
150
|
+
* Provides useful metrics about the site generation.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* const stats: BuildStats = {
|
|
155
|
+
* totalPages: 15,
|
|
156
|
+
* assetsCount: 8,
|
|
157
|
+
* buildTimeMs: 1250,
|
|
158
|
+
* outputSizeBytes: 2048576,
|
|
159
|
+
* cacheHits: 5,
|
|
160
|
+
* cacheMisses: 10
|
|
161
|
+
* };
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export interface BuildStats {
|
|
165
|
+
/** Total number of pages processed */
|
|
166
|
+
totalPages: number;
|
|
167
|
+
/** Number of static assets copied */
|
|
168
|
+
assetsCount: number;
|
|
169
|
+
/** Total build time in milliseconds */
|
|
170
|
+
buildTimeMs: number;
|
|
171
|
+
/** Total size of output directory in bytes */
|
|
172
|
+
outputSizeBytes: number;
|
|
173
|
+
/** Number of cache hits (if caching enabled) */
|
|
174
|
+
cacheHits?: number;
|
|
175
|
+
/** Number of cache misses (if caching enabled) */
|
|
176
|
+
cacheMisses?: number;
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,aAAa,CAAC;AAE1C;;GAEG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,wCAAwC;IACxC,QAAQ,CAAC,EAAE;QACT,oGAAoG;QACpG,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;QACzC,oDAAoD;QACpD,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,KAAK,IAAI,CAAC;KACtC,CAAC;IACF,wCAAwC;IACxC,GAAG,CAAC,EAAE;QACJ,8BAA8B;QAC9B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;KACnD,CAAC;IACF,kDAAkD;IAClD,GAAG,CAAC,EAAE,OAAO,UAAU,EAAE,SAAS,CAAC;IACnC,uCAAuC;IACvC,GAAG,CAAC,EAAE;QACJ,kDAAkD;QAClD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,yDAAyD;QACzD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,6DAA6D;QAC7D,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,4BAA4B;IAC5B,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,MAAM,EAAE,WAAW,CAAC;IACpB,sCAAsC;IACtC,KAAK,EAAE,OAAO,cAAc,EAAE,SAAS,EAAE,CAAC;CAC3C;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,IAAI,EAAE,OAAO,cAAc,EAAE,SAAS,CAAC;IACvC,uCAAuC;IACvC,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACxD,gDAAgD;IAChD,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvD,mDAAmD;IACnD,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,kDAAkD;IAClD,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1D;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,eAAe,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content related type definitions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Front matter metadata extracted from content files.
|
|
6
|
+
* Contains page-specific configuration and metadata in YAML format.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const frontMatter: FrontMatter = {
|
|
11
|
+
* title: 'Getting Started with Stati',
|
|
12
|
+
* description: 'A comprehensive guide to static site generation',
|
|
13
|
+
* tags: ['tutorial', 'documentation'],
|
|
14
|
+
* layout: 'post',
|
|
15
|
+
* order: 1,
|
|
16
|
+
* publishedAt: '2024-01-01',
|
|
17
|
+
* ttlSeconds: 3600,
|
|
18
|
+
* draft: false
|
|
19
|
+
* };
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export interface FrontMatter {
|
|
23
|
+
/** Page title for SEO and display */
|
|
24
|
+
title?: string;
|
|
25
|
+
/** Page description for SEO and meta tags */
|
|
26
|
+
description?: string;
|
|
27
|
+
/** Array of tags for categorization */
|
|
28
|
+
tags?: readonly string[];
|
|
29
|
+
/** Template layout to use for rendering */
|
|
30
|
+
layout?: string;
|
|
31
|
+
/** Numeric order for sorting (useful for navigation) */
|
|
32
|
+
order?: number;
|
|
33
|
+
/** Publication date as ISO string */
|
|
34
|
+
publishedAt?: string;
|
|
35
|
+
/** Custom cache TTL in seconds (overrides global ISG settings) */
|
|
36
|
+
ttlSeconds?: number;
|
|
37
|
+
/** Custom max age cap in days (overrides global ISG settings) */
|
|
38
|
+
maxAgeCapDays?: number;
|
|
39
|
+
/** Whether the page is a draft (excludes from build) */
|
|
40
|
+
draft?: boolean;
|
|
41
|
+
/** Additional custom properties */
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Represents a single page in the static site.
|
|
46
|
+
* Contains all metadata, content, and URL information for a page.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const page: PageModel = {
|
|
51
|
+
* slug: 'my-first-post',
|
|
52
|
+
* url: '/blog/my-first-post',
|
|
53
|
+
* sourcePath: '/content/blog/my-first-post.md',
|
|
54
|
+
* frontMatter: {
|
|
55
|
+
* title: 'My First Post',
|
|
56
|
+
* tags: ['intro', 'blog']
|
|
57
|
+
* },
|
|
58
|
+
* content: '<p>Hello world!</p>',
|
|
59
|
+
* publishedAt: new Date('2024-01-01')
|
|
60
|
+
* };
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export interface PageModel {
|
|
64
|
+
/** URL-friendly identifier for the page */
|
|
65
|
+
slug: string;
|
|
66
|
+
/** Full URL path for the page */
|
|
67
|
+
url: string;
|
|
68
|
+
/** Absolute path to the source content file */
|
|
69
|
+
sourcePath: string;
|
|
70
|
+
/** Parsed front matter metadata */
|
|
71
|
+
frontMatter: FrontMatter;
|
|
72
|
+
/** Rendered HTML content */
|
|
73
|
+
content: string;
|
|
74
|
+
/** Publication date (parsed from front matter or file stats) */
|
|
75
|
+
publishedAt?: Date;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Collection aggregation data available to index page templates.
|
|
79
|
+
* Provides access to child pages and collection metadata for content listing.
|
|
80
|
+
*/
|
|
81
|
+
export interface CollectionData {
|
|
82
|
+
/** All pages in the current collection */
|
|
83
|
+
pages: PageModel[];
|
|
84
|
+
/** Direct child pages of the collection */
|
|
85
|
+
children: PageModel[];
|
|
86
|
+
/** Recent pages sorted by publishedAt (most recent first) */
|
|
87
|
+
recentPages: PageModel[];
|
|
88
|
+
/** Pages grouped by tags for aggregation */
|
|
89
|
+
pagesByTag: Record<string, PageModel[]>;
|
|
90
|
+
/** Collection metadata */
|
|
91
|
+
metadata: {
|
|
92
|
+
/** Total number of pages in collection */
|
|
93
|
+
totalPages: number;
|
|
94
|
+
/** Whether collection has child pages */
|
|
95
|
+
hasChildren: boolean;
|
|
96
|
+
/** Path of the collection */
|
|
97
|
+
collectionPath: string;
|
|
98
|
+
/** Name of the collection (derived from path) */
|
|
99
|
+
collectionName: string;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Template rendering context passed to Eta layouts.
|
|
104
|
+
* Contains all data available to templates during rendering.
|
|
105
|
+
*/
|
|
106
|
+
export interface TemplateContext {
|
|
107
|
+
/** Site configuration and metadata */
|
|
108
|
+
site: import('./config.js').SiteConfig;
|
|
109
|
+
/** Current page data including frontmatter and content */
|
|
110
|
+
page: {
|
|
111
|
+
path: string;
|
|
112
|
+
content: string;
|
|
113
|
+
[key: string]: unknown;
|
|
114
|
+
};
|
|
115
|
+
/** Rendered markdown content */
|
|
116
|
+
content: string;
|
|
117
|
+
/** Site navigation tree */
|
|
118
|
+
navigation: import('./navigation.js').NavNode[];
|
|
119
|
+
/** Discovered partials from underscore folders in hierarchy */
|
|
120
|
+
partials: Record<string, string>;
|
|
121
|
+
/** Collection data for index pages (only available on collection index pages) */
|
|
122
|
+
collection?: CollectionData;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/types/content.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,mCAAmC;IACnC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,SAAS;IACxB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,2CAA2C;IAC3C,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,6DAA6D;IAC7D,WAAW,EAAE,SAAS,EAAE,CAAC;IACzB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACxC,0BAA0B;IAC1B,QAAQ,EAAE;QACR,0CAA0C;QAC1C,UAAU,EAAE,MAAM,CAAC;QACnB,yCAAyC;QACzC,WAAW,EAAE,OAAO,CAAC;QACrB,6BAA6B;QAC7B,cAAc,EAAE,MAAM,CAAC;QACvB,iDAAiD;QACjD,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,IAAI,EAAE,OAAO,aAAa,EAAE,UAAU,CAAC;IACvC,0DAA0D;IAC1D,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,UAAU,EAAE,OAAO,iBAAiB,EAAE,OAAO,EAAE,CAAC;IAChD,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,iFAAiF;IACjF,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B"}
|