1+ const fs = require ( 'fs' ) ;
2+ const path = require ( 'path' ) ;
3+ const cheerio = require ( 'cheerio' ) ;
4+
5+ // Read and parse the original entries.js file to get the metadata
6+ function getOriginalEntries ( ) {
7+ try {
8+ const entriesContent = fs . readFileSync ( 'entries.js' , 'utf8' ) ;
9+
10+ // Extract the entries array using regex
11+ const entriesMatch = entriesContent . match ( / c o n s t \s + e n t r i e s \s * = \s * ( \[ [ \s \S ] * ?\] ) ; / ) ;
12+ if ( ! entriesMatch ) {
13+ throw new Error ( 'Could not find entries array in entries.js' ) ;
14+ }
15+
16+ // Use Function constructor to safely evaluate the array
17+ const entriesArrayString = entriesMatch [ 1 ] ;
18+ const entries = new Function ( 'return ' + entriesArrayString ) ( ) ;
19+
20+ return entries ;
21+ } catch ( error ) {
22+ console . error ( 'Error reading entries.js:' , error . message ) ;
23+ return [ ] ;
24+ }
25+ }
26+
27+ // Add meta tags to HTML content using surgical string manipulation
28+ function addMetaTags ( content , entry ) {
29+ // First check what's missing using cheerio for parsing only
30+ const $ = cheerio . load ( content ) ;
31+
32+ const hasTitle = $ ( 'title' ) . length > 0 ;
33+ const hasMetaTitle = $ ( 'meta[name="title"]' ) . length > 0 ;
34+ const hasDescription = $ ( 'meta[name="description"]' ) . length > 0 ;
35+ const hasAuthor = $ ( 'meta[name="author"]' ) . length > 0 ;
36+ const hasGithub = $ ( 'meta[name="github"]' ) . length > 0 ;
37+ const hasCompatibleBrowsers = $ ( 'meta[name="compatible-browsers"]' ) . length > 0 ;
38+ const hasViewport = $ ( 'meta[name="viewport"]' ) . length > 0 ;
39+ const hasHead = $ ( 'head' ) . length > 0 ;
40+
41+ // Build list of meta tags to add
42+ const metaTags = [ ] ;
43+
44+ // Add comment explaining the addition
45+ metaTags . push ( ' <!-- Meta tags added due to entries.js deprecation on July 8th, 2025 -->' ) ;
46+
47+ // Add viewport if missing (best practice)
48+ if ( ! hasViewport ) {
49+ metaTags . push ( ' <meta name="viewport" content="width=device-width, initial-scale=1.0">' ) ;
50+ }
51+
52+ // Don't add title meta tag if title element exists
53+ if ( entry . title && ! hasTitle && ! hasMetaTitle ) {
54+ metaTags . push ( ` <meta name="title" content="${ escapeHtml ( entry . title ) } ">` ) ;
55+ }
56+
57+ // Add description if missing
58+ if ( entry . description && ! hasDescription ) {
59+ metaTags . push ( ` <meta name="description" content="${ escapeHtml ( entry . description ) } ">` ) ;
60+ }
61+
62+ // Add author if missing
63+ if ( entry . author && ! hasAuthor ) {
64+ metaTags . push ( ` <meta name="author" content="${ escapeHtml ( entry . author ) } ">` ) ;
65+ }
66+
67+ // Add github if missing
68+ if ( entry . github && ! hasGithub ) {
69+ metaTags . push ( ` <meta name="github" content="${ escapeHtml ( entry . github ) } ">` ) ;
70+ }
71+
72+ // Add compatible browsers if missing
73+ if ( entry . compatibleBrowsers && entry . compatibleBrowsers . length > 0 && ! hasCompatibleBrowsers ) {
74+ const browsers = entry . compatibleBrowsers . join ( ', ' ) ;
75+ metaTags . push ( ` <meta name="compatible-browsers" content="${ escapeHtml ( browsers ) } ">` ) ;
76+ }
77+
78+ // If nothing to add, return original content
79+ if ( metaTags . length <= 1 ) { // Only comment, no actual meta tags
80+ return content ;
81+ }
82+
83+ let updatedContent = content ;
84+
85+ if ( ! hasHead ) {
86+ // Create head section after opening html tag or at the beginning
87+ const htmlTagMatch = updatedContent . match ( / ( < h t m l [ ^ > ] * > ) / i) ;
88+ if ( htmlTagMatch ) {
89+ const insertPos = htmlTagMatch . index + htmlTagMatch [ 0 ] . length ;
90+ const headSection = `\n<head>\n${ metaTags . join ( '\n' ) } \n</head>` ;
91+ updatedContent = updatedContent . slice ( 0 , insertPos ) + headSection + updatedContent . slice ( insertPos ) ;
92+ } else {
93+ // No html tag, add head at the beginning
94+ const headSection = `<head>\n${ metaTags . join ( '\n' ) } \n</head>\n` ;
95+ updatedContent = headSection + updatedContent ;
96+ }
97+ } else {
98+ // Find head tag and insert after it
99+ const headTagMatch = updatedContent . match ( / ( < h e a d [ ^ > ] * > ) / i) ;
100+ if ( headTagMatch ) {
101+ const insertPos = headTagMatch . index + headTagMatch [ 0 ] . length ;
102+ const insertion = `\n${ metaTags . join ( '\n' ) } ` ;
103+ updatedContent = updatedContent . slice ( 0 , insertPos ) + insertion + updatedContent . slice ( insertPos ) ;
104+ }
105+ }
106+
107+ return updatedContent ;
108+ }
109+
110+ // Simple HTML escape function
111+ function escapeHtml ( text ) {
112+ const map = {
113+ '&' : '&' ,
114+ '<' : '<' ,
115+ '>' : '>' ,
116+ '"' : '"' ,
117+ "'" : '''
118+ } ;
119+
120+ return text . replace ( / [ & < > " ' ] / g, function ( m ) { return map [ m ] ; } ) ;
121+ }
122+
123+ // Update all entry files with meta tags
124+ function updateAllEntries ( ) {
125+ const originalEntries = getOriginalEntries ( ) ;
126+ if ( originalEntries . length === 0 ) {
127+ console . error ( 'No entries found in entries.js' ) ;
128+ return ;
129+ }
130+
131+ console . log ( `Found ${ originalEntries . length } entries in entries.js` ) ;
132+
133+ let updatedCount = 0 ;
134+ let skippedCount = 0 ;
135+
136+ for ( const entry of originalEntries ) {
137+ const filePath = path . join ( 'entries' , entry . filename ) ;
138+
139+ if ( ! fs . existsSync ( filePath ) ) {
140+ console . log ( `❌ File not found: ${ entry . filename } ` ) ;
141+ continue ;
142+ }
143+
144+ try {
145+ const originalContent = fs . readFileSync ( filePath , 'utf8' ) ;
146+ const updatedContent = addMetaTags ( originalContent , entry ) ;
147+
148+ // Only write if content changed
149+ if ( originalContent !== updatedContent ) {
150+ fs . writeFileSync ( filePath , updatedContent , 'utf8' ) ;
151+ console . log ( `✅ Updated: ${ entry . filename } ` ) ;
152+ updatedCount ++ ;
153+ } else {
154+ console . log ( `⏭️ Skipped: ${ entry . filename } (already has meta tags)` ) ;
155+ skippedCount ++ ;
156+ }
157+ } catch ( error ) {
158+ console . error ( `❌ Error updating ${ entry . filename } :` , error . message ) ;
159+ }
160+ }
161+
162+ console . log ( `\n📊 Summary:` ) ;
163+ console . log ( ` Updated: ${ updatedCount } files` ) ;
164+ console . log ( ` Skipped: ${ skippedCount } files` ) ;
165+ console . log ( ` Total: ${ originalEntries . length } files` ) ;
166+ }
167+
168+ // Run the update
169+ updateAllEntries ( ) ;
0 commit comments