@f5-sales-demo/docs-theme 4.4.6 → 4.4.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@f5-sales-demo/docs-theme",
3
- "version": "4.4.6",
3
+ "version": "4.4.8",
4
4
  "description": "F5 Distributed Cloud branded Starlight documentation theme",
5
5
  "type": "module",
6
6
  "engines": {
@@ -0,0 +1,20 @@
1
+ import { readdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ export async function compactProviderScopes(root) {
4
+ const files = (await readdir(root, { recursive: true })).filter((name) => /\.(html|css|js)$/.test(name));
5
+ const names = new Set();
6
+ for (const file of files) {
7
+ const text = await readFile(join(root, file), 'utf8');
8
+ for (const match of text.matchAll(/\bastro-[a-z0-9]{8}\b/g)) names.add(match[0]);
9
+ }
10
+ const aliases = new Map([...names].sort().map((name, index) => [name, `f5p${index.toString(36)}`]));
11
+ let savedBytes = 0;
12
+ for (const file of files) {
13
+ const path = join(root, file);
14
+ const text = await readFile(path, 'utf8');
15
+ const compact = text.replace(/\bastro-[a-z0-9]{8}\b/g, (name) => aliases.get(name));
16
+ savedBytes += Buffer.byteLength(text) - Buffer.byteLength(compact);
17
+ if (text !== compact) await writeFile(path, compact);
18
+ }
19
+ return { aliases: aliases.size, savedBytes };
20
+ }
@@ -0,0 +1,22 @@
1
+ import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { expect, it } from 'vitest';
5
+ import { compactProviderScopes } from './compact-scopes.mjs';
6
+
7
+ it('keeps generated scope selectors consistent across HTML CSS and JS', async () => {
8
+ const root = await mkdtemp(join(tmpdir(), 'provider-scope-'));
9
+ try {
10
+ await writeFile(join(root, 'page.html'), '<div class="astro-abcdefgh">Reference</div>');
11
+ await writeFile(join(root, 'page.css'), '.astro-abcdefgh{color:red}');
12
+ await writeFile(join(root, 'page.js'), 'document.querySelector(".astro-abcdefgh")');
13
+ const result = await compactProviderScopes(root);
14
+ expect(result.aliases).toBe(1);
15
+ expect(await readFile(join(root, 'page.html'), 'utf8')).toBe('<div class="f5p0">Reference</div>');
16
+ expect(await readFile(join(root, 'page.css'), 'utf8')).toBe('.f5p0{color:red}');
17
+ expect(await readFile(join(root, 'page.js'), 'utf8')).toContain('.f5p0');
18
+ expect((await compactProviderScopes(root)).savedBytes).toBe(0);
19
+ } finally {
20
+ await rm(root, { recursive: true, force: true });
21
+ }
22
+ });
@@ -2,6 +2,7 @@ import { createHash } from 'node:crypto';
2
2
  import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
3
3
  import { join, posix } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
+ import { compactProviderScopes } from './compact-scopes.mjs';
5
6
 
6
7
  const hash = (value) => createHash('sha256').update(value).digest('hex').slice(0, 24);
7
8
  // Input is Astro-generated HTML. Keep each asset's original execution position
@@ -30,7 +31,10 @@ export async function shareProviderAssets(root, base = '/') {
30
31
  tokenStyles.set(name, style);
31
32
  return `<span class="${name}"`;
32
33
  });
33
- html = html.replace(/href="https:\/\/f5-sales-demo.github.io(\/terraform-provider-xcsh\/[^"#]*)/g, 'href="$1');
34
+ html = html.replace(
35
+ /<a\b([^>]*?)href="https:\/\/f5-sales-demo.github.io(\/terraform-provider-xcsh\/[^"#]*)/g,
36
+ '<a$1href="$2',
37
+ );
34
38
  if (tokenStyles.size) html = html.replace('</head>', `<link rel="stylesheet" href="${prefix}tokens.css"></head>`);
35
39
  const islands = [];
36
40
  html = html.replace(/<astro-island\b[\s\S]*?<\/astro-island>/g, (island) => {
@@ -66,7 +70,8 @@ export async function shareProviderAssets(root, base = '/') {
66
70
  await writeFile(join(assetRoot, name), body);
67
71
  assetBytes += Buffer.byteLength(body);
68
72
  }
69
- return { pages: files.length, assets: assets.size, savedBytes: saved - assetBytes };
73
+ const scopes = await compactProviderScopes(root);
74
+ return { pages: files.length, assets: assets.size, savedBytes: saved - assetBytes + scopes.savedBytes };
70
75
  }
71
76
 
72
77
  export default function providerSharedAssets() {
@@ -71,3 +71,17 @@ it('resolves file-route links from their containing directory', async () => {
71
71
  await rm(root, { recursive: true, force: true });
72
72
  }
73
73
  });
74
+
75
+ it('preserves absolute canonical metadata while shortening anchor links', async () => {
76
+ const root = await mkdtemp(join(tmpdir(), 'provider-canonical-'));
77
+ try {
78
+ const url = 'https://f5-sales-demo.github.io/terraform-provider-xcsh/resources/';
79
+ await writeFile(join(root, 'index.html'), `<link rel="canonical" href="${url}"><a href="${url}">Resources</a>`);
80
+ await shareProviderAssets(root, '/terraform-provider-xcsh/');
81
+ const html = await readFile(join(root, 'index.html'), 'utf8');
82
+ expect(html).toContain(`<link rel="canonical" href="${url}">`);
83
+ expect(html).toContain('<a href="resources/">');
84
+ } finally {
85
+ await rm(root, { recursive: true, force: true });
86
+ }
87
+ });