@@ -4,11 +4,10 @@ import { resolve, basename, extname } from 'path';
44import execa from 'execa' ;
55import { unixEOL } from '@sap-cloud-sdk/util' ;
66import { transformFile } from './util' ;
7- import { gunzip , gzip } from 'zlib' ;
7+ import { deflate } from 'zlib' ;
88import { promisify } from 'util' ;
99
10- const gunzipP = promisify ( gunzip ) ;
11- const gzipP = promisify ( gzip ) ;
10+ const deflateP = promisify ( deflate ) ;
1211
1312const docPath = resolve (
1413 JSON . parse ( readFileSync ( 'tsconfig.typedoc.json' , 'utf8' ) ) . typedocOptions . out
@@ -36,8 +35,8 @@ const isNavigationJs = fileName => basename(fileName) === 'navigation.js';
3635
3736const pipe =
3837 ( ...fns ) =>
39- start =>
40- fns . reduce ( ( state , fn ) => fn ( state ) , start ) ;
38+ start =>
39+ fns . reduce ( ( state , fn ) => fn ( state ) , start ) ;
4140
4241async function adjustForGitHubPages ( ) {
4342 const documentationFilePaths = flatten ( readDir ( resolve ( docPath ) ) ) ;
@@ -57,6 +56,34 @@ async function adjustForGitHubPages() {
5756 htmlPaths . forEach ( filePath => removeUnderlinePrefixFromFileName ( filePath ) ) ;
5857}
5958
59+ /**
60+ * Decompresses Base64-encoded deflate compressed data and parses it into a JSON object.
61+ * @link https://github.com/TypeStrong/typedoc/blob/82449253188582f6b63695fecf608d9887ba1761/src/lib/output/themes/default/assets/typedoc/utils/decompress.ts
62+ *
63+ * @param base64 - The Base64-encoded string representing the deflate-compressed JSON string.
64+ * @returns A promise that resolves to the parsed JSON object.
65+ */
66+ export async function decompressJson ( base64 : string ) {
67+ const binaryData = Uint8Array . from ( atob ( base64 ) , ( c ) => c . charCodeAt ( 0 ) ) ;
68+ const blob = new Blob ( [ binaryData ] ) ;
69+ const decompressedStream = blob
70+ . stream ( )
71+ . pipeThrough ( new DecompressionStream ( "deflate" ) ) ;
72+ const decompressedText = await new Response ( decompressedStream ) . text ( ) ;
73+ return JSON . parse ( decompressedText ) ;
74+ }
75+
76+ /**
77+ * Compresses a JSON-serializable object into a Base64-encoded deflate string.
78+ * @link https://github.com/TypeStrong/typedoc/blob/82449253188582f6b63695fecf608d9887ba1761/src/lib/utils/compress.ts
79+ * @param data - The JSON-serializable object to compress.
80+ * @returns A promise that resolves to a Base64-encoded string of the deflate-compressed data.
81+ */
82+ export async function compressJson ( data : any ) {
83+ const gz = await deflateP ( Buffer . from ( JSON . stringify ( data ) ) ) ;
84+ return gz . toString ( "base64" ) ;
85+ }
86+
6087async function adjustSearchJs ( paths ) {
6188 const filtered = paths . filter ( isSearchJs ) ;
6289 if ( filtered . length !== 1 ) {
@@ -65,31 +92,22 @@ async function adjustSearchJs(paths) {
6592
6693 await transformFile ( filtered [ 0 ] , async file => {
6794 const dataRegexResult =
68- / w i n d o w .s e a r c h D a t a = " d a t a : a p p l i c a t i o n \/ o c t e t - s t r e a m ; b a s e 6 4 , ( .* ) " / . exec (
95+ / w i n d o w .s e a r c h D a t a = " ( .* ) " ; / . exec (
6996 file
7097 ) ;
71-
7298 if ( ! dataRegexResult ) {
7399 throw Error (
74100 `Cannot adjust links in 'search.js'. File content did not match expected pattern.`
75101 ) ;
76102 }
77103
78- const encodedData = dataRegexResult [ 1 ] ;
79-
80- const ungzipped = (
81- await gunzipP ( Buffer . from ( encodedData , 'base64' ) )
82- ) . toString ( 'utf8' ) ;
83- const searchItems = JSON . parse ( ungzipped ) ;
84-
104+ const searchItems = await decompressJson ( dataRegexResult [ 1 ] ) ;
85105 searchItems . rows . forEach ( s => {
86106 s . url = removeUnderlinePrefix ( s . url ) ;
87107 } ) ;
88108
89- const encodedAdjustedData = (
90- await gzipP ( JSON . stringify ( searchItems ) )
91- ) . toString ( 'base64' ) ;
92- return `window.searchData = "data:application/octet-stream;base64,${ encodedAdjustedData } "` ;
109+ const encodedAdjustedData = await compressJson ( searchItems ) ;
110+ return `window.searchData = "${ encodedAdjustedData } "` ;
93111 } ) ;
94112}
95113
@@ -101,23 +119,16 @@ async function adjustNavigationJs(paths) {
101119
102120 await transformFile ( filtered [ 0 ] , async file => {
103121 const dataRegexResult =
104- / w i n d o w .n a v i g a t i o n D a t a = " d a t a : a p p l i c a t i o n \/ o c t e t - s t r e a m ; b a s e 6 4 , ( .* ) " / . exec (
122+ / w i n d o w .n a v i g a t i o n D a t a = " ( .* ) " / . exec (
105123 file
106124 ) ;
107-
108125 if ( ! dataRegexResult ) {
109126 throw Error (
110127 `Cannot adjust links in 'navigation.js'. File content did not match expected pattern.`
111128 ) ;
112129 }
113130
114- const encodedData = dataRegexResult [ 1 ] ;
115-
116- const ungzipped = (
117- await gunzipP ( Buffer . from ( encodedData , 'base64' ) )
118- ) . toString ( 'utf8' ) ;
119- const navigationItems = JSON . parse ( ungzipped ) ;
120-
131+ const navigationItems = await decompressJson ( dataRegexResult [ 1 ] ) ;
121132 navigationItems
122133 . filter ( n => n . path )
123134 . forEach ( n => {
@@ -127,10 +138,8 @@ async function adjustNavigationJs(paths) {
127138 } ) ;
128139 } ) ;
129140
130- const encodedAdjustedData = (
131- await gzipP ( JSON . stringify ( navigationItems ) )
132- ) . toString ( 'base64' ) ;
133- return `window.navigationData = "data:application/octet-stream;base64,${ encodedAdjustedData } "` ;
141+ const encodedAdjustedData = await compressJson ( navigationItems ) ;
142+ return `window.navigationData = "${ encodedAdjustedData } "` ;
134143 } ) ;
135144}
136145
0 commit comments