-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* initial commit. boilerplate * startup commits * make copy of offline snooty and build * fix syntax * run format * biome check --write * test upload to S3 * remove jsdom for now * remove jsdom. write comments for todo with 5167 * update build command * remove jsdom * add logic to derive filename and bucket from previous extension * merge conflicts * run lint * update package lock * new extension format * run format * add logic for updating html * remove directory filepaths that are empty * add logs * add logs * add logs * test without converting * test upload without converting * testing * test * update logs * fix promise awaits * clean logs * remove recursive log * recursive readdir * keep log of dirs * close happy dom before returning * fix parent pathing since we are using new filename * fix relative path since not recursive * address comments * address comments
- Loading branch information
Showing
10 changed files
with
1,124 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
extensions/offline-snooty/src/convertGatsbyToHtml/fileHandler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { HTMLAnchorElement, HTMLImageElement, Node, Window } from 'happy-dom'; | ||
import { promises as fsPromises } from 'node:fs'; | ||
|
||
function updateToRelativePaths(nodeList: Node[], prefix: string) { | ||
// for links: href = relativePath + href + index.html | ||
// for images: src = relativePath + src | ||
for (const node of nodeList) { | ||
if (node instanceof HTMLAnchorElement && node['href'].startsWith('/')) { | ||
// TODO: strip hash and query portions | ||
const targetHref = (prefix + node['href'] + '/index.html').replaceAll( | ||
/\/+/g, | ||
'/', | ||
); | ||
node.setAttribute('href', targetHref); | ||
} else if ( | ||
node instanceof HTMLImageElement && | ||
node['src'].startsWith('/') | ||
) { | ||
node['src'] = (prefix + node['src']).replace(/\/+/, '/'); | ||
} | ||
} | ||
} | ||
|
||
export const handleHtmlFile = async ( | ||
filepath: string, | ||
relativePath: string, | ||
) => { | ||
console.log('handlehtmlfile ', filepath); | ||
// update the DOM. change paths for links and images | ||
// first open the file. as a DOM string. | ||
const html = (await fsPromises.readFile(filepath)).toString(); | ||
const window = new Window(); | ||
const document = window.document; | ||
document.write(html); | ||
|
||
const links = document.querySelectorAll('a'); | ||
const images = document.querySelectorAll('img'); | ||
// TODO: should handle background-image url as well | ||
updateToRelativePaths([...links, ...images], relativePath ?? './'); | ||
|
||
console.log('writing file html ', filepath); | ||
|
||
await fsPromises.writeFile(filepath, document.documentElement.innerHTML); | ||
|
||
await window.happyDOM.close(); | ||
}; |
125 changes: 125 additions & 0 deletions
125
extensions/offline-snooty/src/convertGatsbyToHtml/imageExtensions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
export const IMAGE_EXT = new Set<string>([ | ||
'ase', | ||
'art', | ||
'bmp', | ||
'blp', | ||
'cd5', | ||
'cit', | ||
'cpt', | ||
'cr2', | ||
'cut', | ||
'dds', | ||
'dib', | ||
'djvu', | ||
'egt', | ||
'exif', | ||
'gif', | ||
'gpl', | ||
'grf', | ||
'icns', | ||
'ico', | ||
'iff', | ||
'jng', | ||
'jpeg', | ||
'jpg', | ||
'jfif', | ||
'jp2', | ||
'jps', | ||
'lbm', | ||
'max', | ||
'miff', | ||
'mng', | ||
'msp', | ||
'nef', | ||
'nitf', | ||
'ota', | ||
'pbm', | ||
'pc1', | ||
'pc2', | ||
'pc3', | ||
'pcf', | ||
'pcx', | ||
'pdn', | ||
'pgm', | ||
'PI1', | ||
'PI2', | ||
'PI3', | ||
'pict', | ||
'pct', | ||
'pnm', | ||
'pns', | ||
'ppm', | ||
'psb', | ||
'psd', | ||
'pdd', | ||
'psp', | ||
'px', | ||
'pxm', | ||
'pxr', | ||
'qfx', | ||
'raw', | ||
'rle', | ||
'sct', | ||
'sgi', | ||
'rgb', | ||
'int', | ||
'bw', | ||
'tga', | ||
'tiff', | ||
'tif', | ||
'vtf', | ||
'xbm', | ||
'xcf', | ||
'xpm', | ||
'3dv', | ||
'amf', | ||
'ai', | ||
'awg', | ||
'cgm', | ||
'cdr', | ||
'cmx', | ||
'dxf', | ||
'e2d', | ||
'egt', | ||
'eps', | ||
'fs', | ||
'gbr', | ||
'odg', | ||
'svg', | ||
'stl', | ||
'vrml', | ||
'x3d', | ||
'sxd', | ||
'v2d', | ||
'vnd', | ||
'wmf', | ||
'emf', | ||
'art', | ||
'xar', | ||
'png', | ||
'webp', | ||
'jxr', | ||
'hdp', | ||
'wdp', | ||
'cur', | ||
'ecw', | ||
'iff', | ||
'lbm', | ||
'liff', | ||
'nrrd', | ||
'pam', | ||
'pcx', | ||
'pgf', | ||
'sgi', | ||
'rgb', | ||
'rgba', | ||
'bw', | ||
'int', | ||
'inta', | ||
'sid', | ||
'ras', | ||
'sun', | ||
'tga', | ||
'heic', | ||
'heif', | ||
]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import type { NetlifyPluginUtils } from '@netlify/build'; | ||
|
||
export const createSnootyCopy = async ( | ||
run: NetlifyPluginUtils['run'], | ||
targetPath: string, | ||
) => { | ||
await run.command( | ||
`rsync -av ${process.cwd()}/snooty ${targetPath} --exclude public --exclude node_modules`, | ||
); | ||
|
||
const offlineSnootyPath = `${targetPath}/snooty`; | ||
|
||
await run.command('npm ci --legacy-peer-deps', { | ||
cwd: offlineSnootyPath, | ||
}); | ||
|
||
await run.command('npm run clean', { | ||
cwd: offlineSnootyPath, | ||
}); | ||
|
||
await run.command('npm run build:no-prefix', { | ||
cwd: offlineSnootyPath, | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,55 @@ | ||
// Documentation: https://sdk.netlify.com | ||
import { envVarToBool, Extension } from 'util/extension'; | ||
const extension = new Extension({ | ||
isEnabled: envVarToBool(process.env.OFFLINE_SNOOTY_ENABLED), | ||
}); | ||
|
||
extension.addBuildEventHandler('onPreBuild', () => { | ||
// If the build event handler is not enabled, return early | ||
if (!process.env.OFFLINE_SNOOTY_ENABLED) { | ||
return; | ||
} | ||
console.log('Hello there.'); | ||
}); | ||
import { NetlifyExtension } from '@netlify/sdk'; | ||
import { convertGatsbyToHtml } from './convertGatsbyToHtml'; | ||
import { createSnootyCopy } from './createSnootyCopy'; | ||
import { destroyClient, uploadToS3 } from './uploadToS3'; | ||
import { | ||
type BranchEntry, | ||
type DocsetsDocument, | ||
type ReposBranchesDocument, | ||
readEnvConfigs, | ||
} from './uploadToS3/utils'; | ||
|
||
const extension = new NetlifyExtension(); | ||
const NEW_SNOOTY_PATH = `${process.cwd()}/snooty-offline`; | ||
export const PUBLIC_OUTPUT_PATH = `${NEW_SNOOTY_PATH}/snooty/public`; | ||
|
||
// run this extension after the build and deploy are successful | ||
extension.addBuildEventHandler( | ||
'onSuccess', | ||
async ({ netlifyConfig, utils: { run } }) => { | ||
// If the build event handler is not enabled, return early | ||
if (!process.env.OFFLINE_SNOOTY_ENABLED) { | ||
return; | ||
} | ||
|
||
const environment = netlifyConfig.build.environment as Record< | ||
string, | ||
string | DocsetsDocument | ReposBranchesDocument | BranchEntry | ||
>; | ||
const { bucketName, fileName } = readEnvConfigs({ | ||
env: (environment.ENV as string) ?? '', | ||
docsetEntry: (environment.DOCSET_ENTRY as DocsetsDocument) ?? {}, | ||
repoEntry: (environment.REPO_ENTRY as ReposBranchesDocument) ?? {}, | ||
branchEntry: (environment.BRANCH_ENTRY as BranchEntry) ?? {}, | ||
}); | ||
|
||
try { | ||
console.log('... creating snooty copy'); | ||
await createSnootyCopy(run, NEW_SNOOTY_PATH); | ||
console.log('... converting gatsby to html'); | ||
await convertGatsbyToHtml(PUBLIC_OUTPUT_PATH, fileName); | ||
console.log('... uploading to AWS S3 ', bucketName, fileName); | ||
await uploadToS3(`${process.cwd()}/${fileName}`, bucketName, fileName); | ||
console.log('... uploaded to AWS S3'); | ||
// TODO: update atlas collection repos_branches to signal offline availability | ||
} catch (e) { | ||
console.error(e); | ||
throw e; | ||
} finally { | ||
destroyClient(); | ||
} | ||
}, | ||
); | ||
|
||
export { extension }; |
Oops, something went wrong.