@stati/core 1.9.0 → 1.10.1
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/README.md +6 -6
- package/dist/core/build.d.ts.map +1 -1
- package/dist/core/build.js +39 -4
- package/dist/core/dev.d.ts.map +1 -1
- package/dist/core/dev.js +70 -2
- package/dist/core/isg/hash.d.ts +14 -0
- package/dist/core/isg/hash.d.ts.map +1 -1
- package/dist/core/isg/hash.js +32 -1
- package/dist/core/isg/index.d.ts +1 -1
- package/dist/core/isg/index.d.ts.map +1 -1
- package/dist/core/isg/index.js +1 -1
- package/dist/core/isg/manifest.d.ts.map +1 -1
- package/dist/core/isg/manifest.js +7 -1
- package/dist/core/templates.d.ts.map +1 -1
- package/dist/core/templates.js +37 -6
- package/dist/core/utils/index.d.ts +2 -0
- package/dist/core/utils/index.d.ts.map +1 -1
- package/dist/core/utils/index.js +4 -0
- package/dist/core/utils/navigation-helpers.d.ts +124 -0
- package/dist/core/utils/navigation-helpers.d.ts.map +1 -0
- package/dist/core/utils/navigation-helpers.js +219 -0
- package/dist/core/utils/server.d.ts +1 -1
- package/dist/core/utils/server.d.ts.map +1 -1
- package/dist/core/utils/server.js +14 -1
- package/dist/core/utils/tailwind-inventory.d.ts +91 -0
- package/dist/core/utils/tailwind-inventory.d.ts.map +1 -0
- package/dist/core/utils/tailwind-inventory.js +228 -0
- package/dist/core/utils/template-utils.d.ts +3 -0
- package/dist/core/utils/template-utils.d.ts.map +1 -1
- package/dist/core/utils/template-utils.js +27 -3
- package/dist/types/content.d.ts +24 -3
- package/dist/types/content.d.ts.map +1 -1
- package/dist/types/isg.d.ts +4 -1
- package/dist/types/isg.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -327,7 +327,7 @@ export default defineConfig({
|
|
|
327
327
|
});
|
|
328
328
|
```
|
|
329
329
|
|
|
330
|
-
> **For the complete configuration reference** including all options, advanced features, and detailed explanations, see the [Configuration Guide](https://docs.stati.build/configuration/).
|
|
330
|
+
> **For the complete configuration reference** including all options, advanced features, and detailed explanations, see the [Configuration Guide](https://docs.stati.build/configuration/file/).
|
|
331
331
|
|
|
332
332
|
---
|
|
333
333
|
|
|
@@ -621,14 +621,14 @@ Automatic navigation hierarchy based on your file structure:
|
|
|
621
621
|
```html
|
|
622
622
|
<!-- Show breadcrumbs -->
|
|
623
623
|
<nav>
|
|
624
|
-
<% stati.
|
|
624
|
+
<% stati.nav.getBreadcrumbs().forEach(crumb => { %>
|
|
625
625
|
<a href="<%= crumb.url %>"><%= crumb.title %></a>
|
|
626
626
|
<% }) %>
|
|
627
627
|
</nav>
|
|
628
628
|
|
|
629
629
|
<!-- Show navigation tree -->
|
|
630
630
|
<ul>
|
|
631
|
-
<% stati.
|
|
631
|
+
<% stati.nav.tree.forEach(item => { %>
|
|
632
632
|
<li><a href="<%= item.url %>"><%= item.title %></a></li>
|
|
633
633
|
<% }) %>
|
|
634
634
|
</ul>
|
|
@@ -739,9 +739,9 @@ export default defineConfig({
|
|
|
739
739
|
## Learn More
|
|
740
740
|
|
|
741
741
|
- [**Full Documentation**](https://docs.stati.build) — Complete guides and tutorials
|
|
742
|
-
- [**Configuration Guide**](https://docs.stati.build/configuration/) — All options explained
|
|
743
|
-
- [**API Reference**](https://docs.stati.build/api/) — Detailed API docs
|
|
744
|
-
- [**Examples**](https://docs.stati.build/examples/) — Real-world projects
|
|
742
|
+
- [**Configuration Guide**](https://docs.stati.build/configuration/file/) — All options explained
|
|
743
|
+
- [**API Reference**](https://docs.stati.build/api/reference/) — Detailed API docs
|
|
744
|
+
- [**Examples**](https://docs.stati.build/examples/list/) — Real-world projects
|
|
745
745
|
- [**Contributing**](https://github.com/ianchak/stati/blob/main/CONTRIBUTING.md) — Help improve Stati
|
|
746
746
|
|
|
747
747
|
---
|
package/dist/core/build.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/core/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/core/build.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAEV,UAAU,EACV,MAAM,EAKP,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iDAAiD;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA4FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAW3E"}
|
package/dist/core/build.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ensureDir, writeFile, remove, pathExists, stat, readdir, copyFile, resolveOutDir, resolveStaticDir, resolveCacheDir, } from './utils/index.js';
|
|
1
|
+
import { ensureDir, writeFile, remove, pathExists, stat, readdir, copyFile, resolveOutDir, resolveStaticDir, resolveCacheDir, enableInventoryTracking, disableInventoryTracking, clearInventory, writeTailwindClassInventory, getInventorySize, isTailwindUsed, loadPreviousInventory, } from './utils/index.js';
|
|
2
2
|
import { join, dirname, relative } from 'path';
|
|
3
3
|
import { posix } from 'path';
|
|
4
4
|
import { loadConfig } from '../config/loader.js';
|
|
@@ -6,7 +6,7 @@ import { loadContent } from './content.js';
|
|
|
6
6
|
import { createMarkdownProcessor, renderMarkdown } from './markdown.js';
|
|
7
7
|
import { createTemplateEngine, renderPage } from './templates.js';
|
|
8
8
|
import { buildNavigation } from './navigation.js';
|
|
9
|
-
import { loadCacheManifest, saveCacheManifest, shouldRebuildPage, createCacheEntry, updateCacheEntry, withBuildLock, } from './isg/index.js';
|
|
9
|
+
import { loadCacheManifest, saveCacheManifest, shouldRebuildPage, createCacheEntry, updateCacheEntry, withBuildLock, computeNavigationHash, } from './isg/index.js';
|
|
10
10
|
import { generateSitemap, generateRobotsTxtFromConfig, autoInjectSEO, } from '../seo/index.js';
|
|
11
11
|
/**
|
|
12
12
|
* Recursively calculates the total size of a directory in bytes.
|
|
@@ -172,10 +172,12 @@ async function loadContentAndBuildNavigation(config, options, logger) {
|
|
|
172
172
|
if (logger.navigationTree) {
|
|
173
173
|
logger.navigationTree(navigation);
|
|
174
174
|
}
|
|
175
|
+
// Compute navigation hash for change detection in dev server
|
|
176
|
+
const navigationHash = computeNavigationHash(navigation);
|
|
175
177
|
// Create processors
|
|
176
178
|
const md = await createMarkdownProcessor(config);
|
|
177
179
|
const eta = createTemplateEngine(config);
|
|
178
|
-
return { pages, navigation, md, eta };
|
|
180
|
+
return { pages, navigation, md, eta, navigationHash };
|
|
179
181
|
}
|
|
180
182
|
/**
|
|
181
183
|
* Processes pages with ISG caching logic.
|
|
@@ -362,17 +364,50 @@ async function buildInternal(options = {}) {
|
|
|
362
364
|
await remove(cacheDir);
|
|
363
365
|
}
|
|
364
366
|
await ensureDir(outDir);
|
|
367
|
+
// Enable Tailwind class inventory tracking only if Tailwind is detected
|
|
368
|
+
const hasTailwind = await isTailwindUsed();
|
|
369
|
+
if (hasTailwind) {
|
|
370
|
+
enableInventoryTracking();
|
|
371
|
+
clearInventory(); // Clear any previous inventory
|
|
372
|
+
// Try to load from existing inventory file
|
|
373
|
+
const loadedCount = await loadPreviousInventory(cacheDir);
|
|
374
|
+
if (loadedCount > 0) {
|
|
375
|
+
// Write the initial inventory file immediately so Tailwind can scan it
|
|
376
|
+
// This is critical for dev server where Tailwind starts watching before template rendering
|
|
377
|
+
await writeTailwindClassInventory(cacheDir);
|
|
378
|
+
logger.info(`📦 Loaded ${loadedCount} classes from previous build for Tailwind scanner`);
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
// No previous inventory found - write an empty placeholder file
|
|
382
|
+
// This ensures Tailwind has a file to scan even on first build
|
|
383
|
+
// It will be populated with actual classes after template rendering
|
|
384
|
+
await writeTailwindClassInventory(cacheDir);
|
|
385
|
+
logger.info(`📦 Created inventory file for Tailwind scanner (will be populated after rendering)`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
365
388
|
// Load cache manifest for ISG (after potential clean operation)
|
|
366
389
|
const { manifest } = await setupCacheAndManifest(cacheDir);
|
|
367
390
|
// Load content and build navigation
|
|
368
391
|
console.log(); // Add spacing before content loading
|
|
369
|
-
const { pages, navigation, md, eta } = await loadContentAndBuildNavigation(config, options, logger);
|
|
392
|
+
const { pages, navigation, md, eta, navigationHash } = await loadContentAndBuildNavigation(config, options, logger);
|
|
393
|
+
// Store navigation hash in manifest for change detection in dev server
|
|
394
|
+
manifest.navigationHash = navigationHash;
|
|
370
395
|
// Process pages with ISG caching logic
|
|
371
396
|
console.log(); // Add spacing before page processing
|
|
372
397
|
const buildTime = new Date();
|
|
373
398
|
const pageProcessingResult = await processPagesWithCache(pages, manifest, config, outDir, md, eta, navigation, buildTime, options, logger);
|
|
374
399
|
cacheHits = pageProcessingResult.cacheHits;
|
|
375
400
|
cacheMisses = pageProcessingResult.cacheMisses;
|
|
401
|
+
// Write Tailwind class inventory after all templates have been rendered (if Tailwind is used)
|
|
402
|
+
if (hasTailwind) {
|
|
403
|
+
const inventorySize = getInventorySize();
|
|
404
|
+
if (inventorySize > 0) {
|
|
405
|
+
await writeTailwindClassInventory(cacheDir);
|
|
406
|
+
logger.info(`📝 Generated Tailwind class inventory (${inventorySize} classes tracked)`);
|
|
407
|
+
}
|
|
408
|
+
// Disable inventory tracking after build
|
|
409
|
+
disableInventoryTracking();
|
|
410
|
+
}
|
|
376
411
|
// Save updated cache manifest
|
|
377
412
|
await saveCacheManifest(cacheDir, manifest);
|
|
378
413
|
// Copy static assets and count them
|
package/dist/core/dev.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/core/dev.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAe,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/core/dev.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAe,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAmB7D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;CACb;AA4SD,wBAAsB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,CAAC,CA2XxF"}
|
package/dist/core/dev.js
CHANGED
|
@@ -7,7 +7,9 @@ import chokidar from 'chokidar';
|
|
|
7
7
|
import { build } from './build.js';
|
|
8
8
|
import { invalidate } from './invalidate.js';
|
|
9
9
|
import { loadConfig } from '../config/loader.js';
|
|
10
|
-
import { loadCacheManifest, saveCacheManifest } from './isg/index.js';
|
|
10
|
+
import { loadCacheManifest, saveCacheManifest, computeNavigationHash } from './isg/index.js';
|
|
11
|
+
import { loadContent } from './content.js';
|
|
12
|
+
import { buildNavigation } from './navigation.js';
|
|
11
13
|
import { resolveDevPaths, resolveCacheDir, resolvePrettyUrl, createErrorOverlay, parseErrorDetails, TemplateError, } from './utils/index.js';
|
|
12
14
|
import { setEnv, getEnv } from '../env.js';
|
|
13
15
|
import { DEFAULT_DEV_PORT, DEFAULT_DEV_HOST, TEMPLATE_EXTENSION } from '../constants.js';
|
|
@@ -88,8 +90,11 @@ async function performIncrementalRebuild(changedPath, configPath, logger, wsServ
|
|
|
88
90
|
if (changedPath.endsWith(TEMPLATE_EXTENSION) || changedPath.includes('_partials')) {
|
|
89
91
|
await handleTemplateChange(changedPath, configPath, devLogger);
|
|
90
92
|
}
|
|
93
|
+
else if (changedPath.endsWith('.md')) {
|
|
94
|
+
await handleMarkdownChange(changedPath, configPath, devLogger);
|
|
95
|
+
}
|
|
91
96
|
else {
|
|
92
|
-
//
|
|
97
|
+
// Static file changed - use normal rebuild
|
|
93
98
|
await build({
|
|
94
99
|
logger: devLogger,
|
|
95
100
|
force: false,
|
|
@@ -198,6 +203,69 @@ async function handleTemplateChange(templatePath, configPath, logger) {
|
|
|
198
203
|
}
|
|
199
204
|
}
|
|
200
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Handles markdown file changes by comparing navigation hashes.
|
|
208
|
+
* Only performs a full rebuild if navigation structure actually changed.
|
|
209
|
+
* Navigation changes come from frontmatter modifications (title, order, description).
|
|
210
|
+
* Content-only changes use incremental rebuilds.
|
|
211
|
+
*/
|
|
212
|
+
async function handleMarkdownChange(_markdownPath, configPath, logger) {
|
|
213
|
+
const cacheDir = resolveCacheDir();
|
|
214
|
+
try {
|
|
215
|
+
// Load existing cache manifest
|
|
216
|
+
const cacheManifest = await loadCacheManifest(cacheDir);
|
|
217
|
+
if (!cacheManifest || !cacheManifest.navigationHash) {
|
|
218
|
+
// No cache or no navigation hash exists, perform full rebuild
|
|
219
|
+
await build({
|
|
220
|
+
logger,
|
|
221
|
+
force: false,
|
|
222
|
+
clean: false,
|
|
223
|
+
...(configPath && { configPath }),
|
|
224
|
+
});
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
// Load config and content to rebuild navigation tree
|
|
228
|
+
const config = await loadConfig(configPath);
|
|
229
|
+
const pages = await loadContent(config);
|
|
230
|
+
const newNavigation = buildNavigation(pages);
|
|
231
|
+
const newNavigationHash = computeNavigationHash(newNavigation);
|
|
232
|
+
// Compare navigation hashes
|
|
233
|
+
if (newNavigationHash !== cacheManifest.navigationHash) {
|
|
234
|
+
// Navigation structure changed - clear cache and force full rebuild
|
|
235
|
+
logger.info?.('📊 Navigation structure changed, performing full rebuild...');
|
|
236
|
+
// Force rebuild bypasses ISG cache entirely
|
|
237
|
+
await build({
|
|
238
|
+
logger,
|
|
239
|
+
force: true, // Force rebuild to bypass cache
|
|
240
|
+
clean: false,
|
|
241
|
+
...(configPath && { configPath }),
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// Navigation unchanged - use incremental rebuild for content changes
|
|
246
|
+
await build({
|
|
247
|
+
logger,
|
|
248
|
+
force: false,
|
|
249
|
+
clean: false,
|
|
250
|
+
...(configPath && { configPath }),
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch (_error) {
|
|
255
|
+
try {
|
|
256
|
+
// Fallback to full rebuild
|
|
257
|
+
await build({
|
|
258
|
+
logger,
|
|
259
|
+
force: false,
|
|
260
|
+
clean: false,
|
|
261
|
+
...(configPath && { configPath }),
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
catch (fallbackError) {
|
|
265
|
+
throw fallbackError instanceof Error ? fallbackError : new Error(String(fallbackError));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
201
269
|
export async function createDevServer(options = {}) {
|
|
202
270
|
const { port = DEFAULT_DEV_PORT, host = DEFAULT_DEV_HOST, open = false, configPath, logger = {
|
|
203
271
|
info: (msg) => console.log(msg),
|
package/dist/core/isg/hash.d.ts
CHANGED
|
@@ -45,4 +45,18 @@ export declare function computeFileHash(filePath: string): Promise<string | null
|
|
|
45
45
|
* ```
|
|
46
46
|
*/
|
|
47
47
|
export declare function computeInputsHash(contentHash: string, depsHashes: string[]): string;
|
|
48
|
+
/**
|
|
49
|
+
* Computes a hash of the navigation tree structure.
|
|
50
|
+
* Used to detect when navigation has changed (title, url, order, children structure).
|
|
51
|
+
*
|
|
52
|
+
* @param navigation - The navigation tree to hash
|
|
53
|
+
* @returns SHA-256 hash as a hex string
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const hash = computeNavigationHash(navigationTree);
|
|
58
|
+
* console.log(hash); // "sha256-abc123..."
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function computeNavigationHash(navigation: unknown[]): string;
|
|
48
62
|
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../src/core/isg/hash.ts"],"names":[],"mappings":"AAwBA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAiBhG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiB9E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAKnF"}
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../src/core/isg/hash.ts"],"names":[],"mappings":"AAwBA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAiBhG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiB9E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAKnF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,CAqCnE"}
|
package/dist/core/isg/hash.js
CHANGED
|
@@ -97,7 +97,38 @@ export async function computeFileHash(filePath) {
|
|
|
97
97
|
* ```
|
|
98
98
|
*/
|
|
99
99
|
export function computeInputsHash(contentHash, depsHashes) {
|
|
100
|
-
//
|
|
100
|
+
// Sort dependency hashes for consistency
|
|
101
101
|
const sortedDepsHashes = [...depsHashes].sort();
|
|
102
102
|
return createSha256Hash([contentHash, ...sortedDepsHashes]);
|
|
103
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Computes a hash of the navigation tree structure.
|
|
106
|
+
* Used to detect when navigation has changed (title, url, order, children structure).
|
|
107
|
+
*
|
|
108
|
+
* @param navigation - The navigation tree to hash
|
|
109
|
+
* @returns SHA-256 hash as a hex string
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const hash = computeNavigationHash(navigationTree);
|
|
114
|
+
* console.log(hash); // "sha256-abc123..."
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export function computeNavigationHash(navigation) {
|
|
118
|
+
const normalizeNavNode = (node) => {
|
|
119
|
+
const normalized = {
|
|
120
|
+
title: String(node.title ?? ''),
|
|
121
|
+
url: String(node.url ?? ''),
|
|
122
|
+
};
|
|
123
|
+
if (node.order !== undefined && typeof node.order === 'number') {
|
|
124
|
+
normalized.order = node.order;
|
|
125
|
+
}
|
|
126
|
+
if (node.children && Array.isArray(node.children) && node.children.length > 0) {
|
|
127
|
+
normalized.children = node.children.map((child) => normalizeNavNode(child));
|
|
128
|
+
}
|
|
129
|
+
return normalized;
|
|
130
|
+
};
|
|
131
|
+
const normalizedNav = navigation.map((node) => normalizeNavNode(node));
|
|
132
|
+
const navJson = JSON.stringify(normalizedNav);
|
|
133
|
+
return createSha256Hash(navJson);
|
|
134
|
+
}
|
package/dist/core/isg/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export { loadCacheManifest, saveCacheManifest, createEmptyManifest } from './man
|
|
|
10
10
|
export { shouldRebuildPage, createCacheEntry, updateCacheEntry } from './builder.js';
|
|
11
11
|
export { BuildLockManager, withBuildLock } from './build-lock.js';
|
|
12
12
|
export { CircularDependencyError, trackTemplateDependencies, findPartialDependencies, resolveTemplatePath, } from './deps.js';
|
|
13
|
-
export { computeContentHash, computeFileHash, computeInputsHash } from './hash.js';
|
|
13
|
+
export { computeContentHash, computeFileHash, computeInputsHash, computeNavigationHash, } from './hash.js';
|
|
14
14
|
export { getSafeCurrentTime, parseSafeDate, computeEffectiveTTL, computeNextRebuildAt, isPageFrozen, applyAgingRules, } from './ttl.js';
|
|
15
15
|
export { ISGConfigurationError, validateISGConfig, validatePageISGOverrides, extractNumericOverride, } from './validation.js';
|
|
16
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/isg/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAG1F,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrF,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AAGnB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/isg/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAG1F,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrF,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,eAAe,GAChB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC"}
|
package/dist/core/isg/index.js
CHANGED
|
@@ -15,7 +15,7 @@ export { BuildLockManager, withBuildLock } from './build-lock.js';
|
|
|
15
15
|
// Dependency tracking
|
|
16
16
|
export { CircularDependencyError, trackTemplateDependencies, findPartialDependencies, resolveTemplatePath, } from './deps.js';
|
|
17
17
|
// Hash computation
|
|
18
|
-
export { computeContentHash, computeFileHash, computeInputsHash } from './hash.js';
|
|
18
|
+
export { computeContentHash, computeFileHash, computeInputsHash, computeNavigationHash, } from './hash.js';
|
|
19
19
|
// TTL and aging
|
|
20
20
|
export { getSafeCurrentTime, parseSafeDate, computeEffectiveTTL, computeNextRebuildAt, isPageFrozen, applyAgingRules, } from './ttl.js';
|
|
21
21
|
// Validation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/core/isg/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,sBAAsB,CAAC;AAUtE;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/core/isg/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,sBAAsB,CAAC;AAUtE;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAsGvF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAmEhG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CAInD"}
|
|
@@ -71,7 +71,13 @@ export async function loadCacheManifest(cacheDir) {
|
|
|
71
71
|
if (invalidEntryCount > 0) {
|
|
72
72
|
console.warn(`Removed ${invalidEntryCount} invalid cache entries`);
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
// Return manifest with entries AND navigationHash (if present)
|
|
75
|
+
const resultManifest = { entries: validatedEntries };
|
|
76
|
+
// Preserve navigationHash if it exists
|
|
77
|
+
if (typeof manifestObj.navigationHash === 'string') {
|
|
78
|
+
resultManifest.navigationHash = manifestObj.navigationHash;
|
|
79
|
+
}
|
|
80
|
+
return resultManifest;
|
|
75
81
|
}
|
|
76
82
|
catch (error) {
|
|
77
83
|
const nodeError = error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/core/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAG1B,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAkB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/core/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAG1B,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAkB,MAAM,mBAAmB,CAAC;AAmNzF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG,CAW7D;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,GAAG,EACR,UAAU,CAAC,EAAE,OAAO,EAAE,EACtB,QAAQ,CAAC,EAAE,SAAS,EAAE,GACrB,OAAO,CAAC,MAAM,CAAC,CAsLjB"}
|
package/dist/core/templates.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Eta } from 'eta';
|
|
|
2
2
|
import { join, dirname, relative, basename, posix } from 'path';
|
|
3
3
|
import glob from 'fast-glob';
|
|
4
4
|
import { TEMPLATE_EXTENSION } from '../constants.js';
|
|
5
|
-
import { getStatiVersion, isCollectionIndexPage, discoverLayout, getCollectionPathForPage, resolveSrcDir, createTemplateError, createValidatingPartialsProxy, propValue, wrapPartialsAsCallable, } from './utils/index.js';
|
|
5
|
+
import { getStatiVersion, isCollectionIndexPage, discoverLayout, getCollectionPathForPage, resolveSrcDir, createTemplateError, createValidatingPartialsProxy, propValue, wrapPartialsAsCallable, createNavigationHelpers, } from './utils/index.js';
|
|
6
6
|
import { getEnv } from '../env.js';
|
|
7
7
|
import { generateSEO } from '../seo/index.js';
|
|
8
8
|
/**
|
|
@@ -100,6 +100,25 @@ function buildCollectionData(currentPage, allPages) {
|
|
|
100
100
|
},
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Builds collection data for a child page (showing parent collection data).
|
|
105
|
+
* Finds the parent collection and returns its data.
|
|
106
|
+
*
|
|
107
|
+
* @param currentPage - The current page being rendered
|
|
108
|
+
* @param allPages - All pages in the site
|
|
109
|
+
* @returns Collection data for the parent collection or undefined
|
|
110
|
+
*/
|
|
111
|
+
function buildParentCollectionData(currentPage, allPages) {
|
|
112
|
+
// Get the parent collection path
|
|
113
|
+
const parentPath = getCollectionPathForPage(currentPage.url);
|
|
114
|
+
// Find the index page for the parent collection
|
|
115
|
+
const parentIndexPage = allPages.find((p) => p.url === parentPath);
|
|
116
|
+
if (parentIndexPage) {
|
|
117
|
+
// Build collection data for the parent
|
|
118
|
+
return buildCollectionData(parentIndexPage, allPages);
|
|
119
|
+
}
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
103
122
|
/**
|
|
104
123
|
* Discovers partials in the hierarchy for a given page path.
|
|
105
124
|
* Scans all parent directories for folders starting with underscore.
|
|
@@ -168,15 +187,26 @@ export async function renderPage(page, body, config, eta, navigation, allPages)
|
|
|
168
187
|
const srcDir = resolveSrcDir(config);
|
|
169
188
|
const relativePath = relative(srcDir, page.sourcePath);
|
|
170
189
|
const partialPaths = await discoverPartials(relativePath, config);
|
|
171
|
-
// Build collection data
|
|
190
|
+
// Build collection data based on page type
|
|
172
191
|
let collectionData;
|
|
173
192
|
const isIndexPage = allPages && isCollectionIndexPage(page, allPages);
|
|
174
|
-
if (
|
|
175
|
-
|
|
193
|
+
if (allPages) {
|
|
194
|
+
if (isIndexPage) {
|
|
195
|
+
// For index pages, show their own collection data
|
|
196
|
+
collectionData = buildCollectionData(page, allPages);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
// For child pages, show parent collection data
|
|
200
|
+
collectionData = buildParentCollectionData(page, allPages);
|
|
201
|
+
}
|
|
176
202
|
}
|
|
177
203
|
// Discover the appropriate layout using hierarchical layout.eta convention
|
|
178
204
|
// Pass isIndexPage flag to enable index.eta lookup for aggregation pages
|
|
179
205
|
const layoutPath = await discoverLayout(relativePath, config, page.frontMatter.layout, isIndexPage);
|
|
206
|
+
// Create navigation helpers
|
|
207
|
+
const navTree = navigation || [];
|
|
208
|
+
const navHelpers = createNavigationHelpers(navTree, page);
|
|
209
|
+
const currentNavNode = navHelpers.getCurrentNode();
|
|
180
210
|
// Create base context for partial rendering
|
|
181
211
|
const baseContext = {
|
|
182
212
|
site: config.site,
|
|
@@ -185,10 +215,11 @@ export async function renderPage(page, body, config, eta, navigation, allPages)
|
|
|
185
215
|
path: page.url,
|
|
186
216
|
url: page.url, // Add url property for compatibility
|
|
187
217
|
content: body,
|
|
218
|
+
navNode: currentNavNode, // Add current page's navigation node
|
|
188
219
|
},
|
|
189
220
|
content: body,
|
|
190
|
-
|
|
191
|
-
collection: collectionData, // Add collection data
|
|
221
|
+
nav: navHelpers, // Replace navigation with nav helpers
|
|
222
|
+
collection: collectionData, // Add collection data
|
|
192
223
|
// Add custom filters to context
|
|
193
224
|
...(config.eta?.filters || {}),
|
|
194
225
|
generator: {
|
|
@@ -6,10 +6,12 @@ export { readFile, writeFile, pathExists, ensureDir, remove, copyFile, readdir,
|
|
|
6
6
|
export { resolveSrcDir, resolveOutDir, resolveStaticDir, resolveCacheDir, resolveDevPaths, normalizeTemplatePath, resolveSrcPath, resolveOutPath, resolveStaticPath, } from './paths.js';
|
|
7
7
|
export { discoverLayout, isCollectionIndexPage, getCollectionPathForPage, } from './template-discovery.js';
|
|
8
8
|
export { propValue } from './template-utils.js';
|
|
9
|
+
export { trackTailwindClass, enableInventoryTracking, disableInventoryTracking, clearInventory, getInventory, getInventorySize, isTrackingEnabled, writeTailwindClassInventory, isTailwindUsed, resetTailwindDetection, loadPreviousInventory, } from './tailwind-inventory.js';
|
|
9
10
|
export { createValidatingPartialsProxy } from './partial-validation.js';
|
|
10
11
|
export { makeCallablePartial, wrapPartialsAsCallable } from './callable-partials.js';
|
|
11
12
|
export type { CallablePartial } from './callable-partials.js';
|
|
12
13
|
export { TemplateError, parseEtaError, createTemplateError } from './template-errors.js';
|
|
14
|
+
export { createNavigationHelpers } from './navigation-helpers.js';
|
|
13
15
|
export { resolvePrettyUrl } from './server.js';
|
|
14
16
|
export type { PrettyUrlResult } from './server.js';
|
|
15
17
|
export { createErrorOverlay, parseErrorDetails } from './error-overlay.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,QAAQ,EACR,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAI,GACL,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAGxE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrF,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAGzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,QAAQ,EACR,SAAS,EACT,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAI,GACL,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAGxE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrF,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAGzF,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/core/utils/index.js
CHANGED
|
@@ -10,12 +10,16 @@ export { resolveSrcDir, resolveOutDir, resolveStaticDir, resolveCacheDir, resolv
|
|
|
10
10
|
export { discoverLayout, isCollectionIndexPage, getCollectionPathForPage, } from './template-discovery.js';
|
|
11
11
|
// Template utilities
|
|
12
12
|
export { propValue } from './template-utils.js';
|
|
13
|
+
// Tailwind inventory utilities
|
|
14
|
+
export { trackTailwindClass, enableInventoryTracking, disableInventoryTracking, clearInventory, getInventory, getInventorySize, isTrackingEnabled, writeTailwindClassInventory, isTailwindUsed, resetTailwindDetection, loadPreviousInventory, } from './tailwind-inventory.js';
|
|
13
15
|
// Partial validation utilities
|
|
14
16
|
export { createValidatingPartialsProxy } from './partial-validation.js';
|
|
15
17
|
// Callable partial utilities
|
|
16
18
|
export { makeCallablePartial, wrapPartialsAsCallable } from './callable-partials.js';
|
|
17
19
|
// Template error utilities
|
|
18
20
|
export { TemplateError, parseEtaError, createTemplateError } from './template-errors.js';
|
|
21
|
+
// Navigation helper utilities
|
|
22
|
+
export { createNavigationHelpers } from './navigation-helpers.js';
|
|
19
23
|
// Server utilities
|
|
20
24
|
export { resolvePrettyUrl } from './server.js';
|
|
21
25
|
// Error overlay utilities
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { NavNode, PageModel } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Navigation helper utilities for template context.
|
|
4
|
+
* Provides methods for querying and traversing the navigation tree.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Finds a navigation node by its path or URL.
|
|
8
|
+
*
|
|
9
|
+
* @param tree - Navigation tree to search
|
|
10
|
+
* @param path - Path or URL to find
|
|
11
|
+
* @returns The found node or undefined
|
|
12
|
+
*/
|
|
13
|
+
export declare function findNode(tree: NavNode[], path: string): NavNode | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Gets the children of a specific navigation node by path.
|
|
16
|
+
*
|
|
17
|
+
* @param tree - Navigation tree to search
|
|
18
|
+
* @param path - Path of the parent node
|
|
19
|
+
* @returns Array of child nodes or empty array if not found or no children
|
|
20
|
+
*/
|
|
21
|
+
export declare function getChildren(tree: NavNode[], path: string): NavNode[];
|
|
22
|
+
/**
|
|
23
|
+
* Gets the parent node of a specific path.
|
|
24
|
+
*
|
|
25
|
+
* @param tree - Navigation tree to search
|
|
26
|
+
* @param path - Path to find parent for
|
|
27
|
+
* @returns The parent node or undefined
|
|
28
|
+
*/
|
|
29
|
+
export declare function getParent(tree: NavNode[], path: string): NavNode | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Gets the siblings of a specific path (nodes at the same level).
|
|
32
|
+
*
|
|
33
|
+
* @param tree - Navigation tree to search
|
|
34
|
+
* @param path - Path to find siblings for
|
|
35
|
+
* @param includeSelf - Whether to include the node itself in the results
|
|
36
|
+
* @returns Array of sibling nodes or empty array
|
|
37
|
+
*/
|
|
38
|
+
export declare function getSiblings(tree: NavNode[], path: string, includeSelf?: boolean): NavNode[];
|
|
39
|
+
/**
|
|
40
|
+
* Gets a subtree starting from a specific path.
|
|
41
|
+
*
|
|
42
|
+
* @param tree - Navigation tree to search
|
|
43
|
+
* @param path - Root path for the subtree
|
|
44
|
+
* @returns The subtree as an array (single node with its children) or empty array
|
|
45
|
+
*/
|
|
46
|
+
export declare function getSubtree(tree: NavNode[], path: string): NavNode[];
|
|
47
|
+
/**
|
|
48
|
+
* Gets the breadcrumb trail from root to a specific path.
|
|
49
|
+
*
|
|
50
|
+
* @param tree - Navigation tree to search
|
|
51
|
+
* @param path - Path to get breadcrumbs for
|
|
52
|
+
* @returns Array of nodes from root to the target path
|
|
53
|
+
*/
|
|
54
|
+
export declare function getBreadcrumbs(tree: NavNode[], path: string): NavNode[];
|
|
55
|
+
/**
|
|
56
|
+
* Finds the current page's navigation node.
|
|
57
|
+
*
|
|
58
|
+
* @param tree - Navigation tree to search
|
|
59
|
+
* @param currentPage - Current page model
|
|
60
|
+
* @returns The navigation node for the current page or undefined
|
|
61
|
+
*/
|
|
62
|
+
export declare function getCurrentNode(tree: NavNode[], currentPage: PageModel): NavNode | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Creates a navigation helpers object for template context.
|
|
65
|
+
*
|
|
66
|
+
* @param tree - The full navigation tree
|
|
67
|
+
* @param currentPage - The current page being rendered
|
|
68
|
+
* @returns Object with navigation helper methods
|
|
69
|
+
*/
|
|
70
|
+
export declare function createNavigationHelpers(tree: NavNode[], currentPage: PageModel): {
|
|
71
|
+
/**
|
|
72
|
+
* The full navigation tree.
|
|
73
|
+
* Use stati.nav.tree to access the global navigation.
|
|
74
|
+
*/
|
|
75
|
+
tree: NavNode[];
|
|
76
|
+
/**
|
|
77
|
+
* Gets the full navigation tree.
|
|
78
|
+
* @returns The complete navigation tree
|
|
79
|
+
*/
|
|
80
|
+
getTree: () => NavNode[];
|
|
81
|
+
/**
|
|
82
|
+
* Finds a navigation node by path or URL.
|
|
83
|
+
* @param path - The path or URL to find
|
|
84
|
+
* @returns The found node or undefined
|
|
85
|
+
*/
|
|
86
|
+
findNode: (path: string) => NavNode | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Gets the children of a navigation node.
|
|
89
|
+
* @param path - The path of the parent node
|
|
90
|
+
* @returns Array of child navigation nodes
|
|
91
|
+
*/
|
|
92
|
+
getChildren: (path: string) => NavNode[];
|
|
93
|
+
/**
|
|
94
|
+
* Gets the parent of a navigation node.
|
|
95
|
+
* @param path - The path to find the parent for (defaults to current page)
|
|
96
|
+
* @returns The parent node or undefined
|
|
97
|
+
*/
|
|
98
|
+
getParent: (path?: string) => NavNode | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Gets the siblings of a navigation node.
|
|
101
|
+
* @param path - The path to find siblings for (defaults to current page)
|
|
102
|
+
* @param includeSelf - Whether to include the node itself
|
|
103
|
+
* @returns Array of sibling nodes
|
|
104
|
+
*/
|
|
105
|
+
getSiblings: (path?: string, includeSelf?: boolean) => NavNode[];
|
|
106
|
+
/**
|
|
107
|
+
* Gets a subtree starting from a specific path.
|
|
108
|
+
* @param path - The root path for the subtree
|
|
109
|
+
* @returns Array containing the subtree
|
|
110
|
+
*/
|
|
111
|
+
getSubtree: (path: string) => NavNode[];
|
|
112
|
+
/**
|
|
113
|
+
* Gets the breadcrumb trail for a path.
|
|
114
|
+
* @param path - The path to get breadcrumbs for (defaults to current page)
|
|
115
|
+
* @returns Array of nodes from root to the target
|
|
116
|
+
*/
|
|
117
|
+
getBreadcrumbs: (path?: string) => NavNode[];
|
|
118
|
+
/**
|
|
119
|
+
* Gets the current page's navigation node.
|
|
120
|
+
* @returns The navigation node for the current page or undefined
|
|
121
|
+
*/
|
|
122
|
+
getCurrentNode: () => NavNode | undefined;
|
|
123
|
+
};
|
|
124
|
+
//# sourceMappingURL=navigation-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-helpers.d.ts","sourceRoot":"","sources":["../../../src/core/utils/navigation-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE/D;;;GAGG;AAEH;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAiB3E;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAGpE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAE5E;AAiCD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,UAAQ,GAAG,OAAO,EAAE,CAiBzF;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAGnE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAIvE;AAkCD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAE3F;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS;IAE3E;;;OAGG;;IAGH;;;OAGG;;IAGH;;;;OAIG;qBACc,MAAM;IAEvB;;;;OAIG;wBACiB,MAAM;IAE1B;;;;OAIG;uBACgB,MAAM;IAEzB;;;;;OAKG;yBACkB,MAAM;IAG3B;;;;OAIG;uBACgB,MAAM;IAEzB;;;;OAIG;4BACqB,MAAM;IAE9B;;;OAGG;;EAGN"}
|