@f5-sales-demo/docs-theme 4.9.9 → 4.11.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/config.ts CHANGED
@@ -38,6 +38,7 @@ import { stagedProviderSections } from './src/utils/provider-sections.ts';
38
38
  import { publicationSidebar, repositoryPublicationProfile } from './src/utils/publication-profiles.ts';
39
39
  import { resolveMegaMenuIcon } from './src/utils/resolve-icon.ts';
40
40
  import providerSharedAssets from './src/utils/share-provider-assets.mjs';
41
+ import { statisticsScriptMarkdown } from './src/utils/statistics-script-markdown.mjs';
41
42
  import { buildSubcategorySidebar } from './src/utils/subcategory-sidebar.ts';
42
43
 
43
44
  export type { LocaleConfig } from './src/i18n/locales.ts';
@@ -942,6 +943,7 @@ export function createF5xcDocsConfig(options: F5xcDocsConfigOptions = {}) {
942
943
  ...(canonicalProvider
943
944
  ? [providerSharedAssets(), canonicalLlms({ contentRoot: canonicalProvider.contentRoot, base, title })]
944
945
  : []),
946
+ ...(githubRepository === 'f5-sales-demo/statistics' ? [statisticsScriptMarkdown()] : []),
945
947
  ...additionalIntegrations,
946
948
  ],
947
949
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@f5-sales-demo/docs-theme",
3
- "version": "4.9.9",
3
+ "version": "4.11.0",
4
4
  "description": "F5 Distributed Cloud branded Starlight documentation theme",
5
5
  "type": "module",
6
6
  "engines": {
@@ -57,3 +57,51 @@ describe('publication profile sidebar', () => {
57
57
  expect(publicationSidebar('f5-sales-demo/canada', fallback)).not.toBe(fallback);
58
58
  });
59
59
  });
60
+
61
+ describe('Statistics publication', () => {
62
+ it('keeps English publication and the existing F5 branding', () => {
63
+ expect(repositoryPublicationProfile('f5-sales-demo/statistics')).toMatchObject({
64
+ locales: { en: { label: 'English', lang: 'en' } },
65
+ defaultLocale: 'en',
66
+ });
67
+ expect(repositoryPublicationProfile('statistics')?.favicon).toBeUndefined();
68
+ });
69
+ it('preserves 13 existing routes and places Shell Scripts before Infrastructure', () => {
70
+ const sidebar = publicationSidebar('f5-sales-demo/statistics', []);
71
+ expect(sidebar?.slice(0, 11)).toEqual([
72
+ { slug: 'index' },
73
+ { slug: 'access-logs' },
74
+ { slug: 'service-graph' },
75
+ { slug: 'origin-performance' },
76
+ { slug: 'application-health' },
77
+ { slug: 'api-discovery' },
78
+ { slug: 'firewall-metrics' },
79
+ { slug: 'security-events' },
80
+ { slug: 'troubleshooting' },
81
+ { slug: 'api-catalog' },
82
+ { slug: 'setup' },
83
+ ]);
84
+ expect(sidebar?.[11]).toEqual({ slug: 'shell-scripts' });
85
+ expect(sidebar?.[12]).toEqual({
86
+ label: 'Infrastructure',
87
+ collapsed: true,
88
+ items: [{ slug: 'deployment' }, { slug: 'verification' }],
89
+ });
90
+ expect(sidebar).toHaveLength(13);
91
+ const routes = sidebar?.flatMap((item) =>
92
+ 'slug' in item
93
+ ? [item.slug]
94
+ : 'items' in item
95
+ ? item.items.map((child) => ('slug' in child ? child.slug : ''))
96
+ : [],
97
+ );
98
+ expect(routes).toHaveLength(14);
99
+ expect(new Set(routes).size).toBe(14);
100
+ });
101
+ it('preserves supplied fallback navigation for other repositories', () => {
102
+ const fallback = [{ slug: 'index' }, { label: 'Existing', items: [{ slug: 'existing' }] }];
103
+ for (const repo of ['observability', 'multi-cloud-networking', 'docs-theme', 'statistics-extra']) {
104
+ expect(publicationSidebar(`f5-sales-demo/${repo}`, fallback)).toBe(fallback);
105
+ }
106
+ });
107
+ });
@@ -5,12 +5,35 @@ type Sidebar = NonNullable<Parameters<typeof starlight>[0]['sidebar']>;
5
5
  interface PublicationProfile {
6
6
  locales: Record<string, { label: string; lang: string }>;
7
7
  defaultLocale: string;
8
- favicon: string;
8
+ favicon?: string;
9
9
  sidebar?: Sidebar;
10
10
  }
11
11
 
12
12
  /** Repository publication decisions shared by navigation and site configuration. */
13
13
  export const publicationProfiles: Record<string, PublicationProfile> = {
14
+ statistics: {
15
+ locales: { en: { label: 'English', lang: 'en' } },
16
+ defaultLocale: 'en',
17
+ sidebar: [
18
+ { slug: 'index' },
19
+ { slug: 'access-logs' },
20
+ { slug: 'service-graph' },
21
+ { slug: 'origin-performance' },
22
+ { slug: 'application-health' },
23
+ { slug: 'api-discovery' },
24
+ { slug: 'firewall-metrics' },
25
+ { slug: 'security-events' },
26
+ { slug: 'troubleshooting' },
27
+ { slug: 'api-catalog' },
28
+ { slug: 'setup' },
29
+ { slug: 'shell-scripts' },
30
+ {
31
+ label: 'Infrastructure',
32
+ collapsed: true,
33
+ items: [{ slug: 'deployment' }, { slug: 'verification' }],
34
+ },
35
+ ],
36
+ },
14
37
  canada: {
15
38
  locales: { en: { label: 'English', lang: 'en' } },
16
39
  defaultLocale: 'en',
@@ -0,0 +1,31 @@
1
+ import { readFile, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+
5
+ /** Keep the Statistics page-action Markdown export equal to its imported script source. */
6
+ export function statisticsScriptMarkdown() {
7
+ let root;
8
+ return {
9
+ name: 'statistics-script-markdown',
10
+ hooks: {
11
+ 'astro:config:done': ({ config }) => {
12
+ root = fileURLToPath(config.root);
13
+ },
14
+ 'astro:build:done': async ({ dir }) => {
15
+ await expandStatisticsScriptMarkdown(root, fileURLToPath(dir));
16
+ },
17
+ },
18
+ };
19
+ }
20
+
21
+ export async function expandStatisticsScriptMarkdown(root, output) {
22
+ const path = join(output, 'en/shell-scripts.md');
23
+ let markdown = await readFile(path, 'utf8');
24
+ for (const name of ['simple-stats.sh', 'get-stats.sh']) {
25
+ const source = await readFile(join(root, 'src/content/docs/assets/scripts', name), 'utf8');
26
+ const fence = `\x60\x60\x60bash file=../assets/scripts/${name}\n\x60\x60\x60`;
27
+ if (!markdown.includes(fence)) throw new Error(`Missing script import in Statistics Markdown: ${name}`);
28
+ markdown = markdown.replace(fence, () => `\x60\x60\x60bash\n${source}\x60\x60\x60`);
29
+ }
30
+ await writeFile(path, markdown);
31
+ }
@@ -0,0 +1,31 @@
1
+ import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { describe, expect, it } from 'vitest';
5
+ import { expandStatisticsScriptMarkdown } from './statistics-script-markdown.mjs';
6
+
7
+ describe('Statistics script Markdown export', () => {
8
+ it('expands both complete sources without interpreting replacement characters', async () => {
9
+ const root = await mkdtemp(join(tmpdir(), 'statistics-export-'));
10
+ try {
11
+ await mkdir(join(root, 'src/content/docs/assets/scripts'), { recursive: true });
12
+ await mkdir(join(root, 'output/en'), { recursive: true });
13
+ const source = '#!/usr/bin/env bash\nprintf "%s" "$&"\n';
14
+ for (const name of ['simple-stats.sh', 'get-stats.sh']) {
15
+ await writeFile(join(root, 'src/content/docs/assets/scripts', name), source);
16
+ }
17
+ await writeFile(
18
+ join(root, 'output/en/shell-scripts.md'),
19
+ ['simple-stats.sh', 'get-stats.sh']
20
+ .map((name) => `\x60\x60\x60bash file=../assets/scripts/${name}\n\x60\x60\x60`)
21
+ .join('\n'),
22
+ );
23
+ await expandStatisticsScriptMarkdown(root, join(root, 'output'));
24
+ expect(await readFile(join(root, 'output/en/shell-scripts.md'), 'utf8')).toBe(
25
+ `\x60\x60\x60bash\n${source}\x60\x60\x60\n\x60\x60\x60bash\n${source}\x60\x60\x60`,
26
+ );
27
+ } finally {
28
+ await rm(root, { recursive: true, force: true });
29
+ }
30
+ });
31
+ });