-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1329c52
commit 84e9ed7
Showing
87 changed files
with
3,881 additions
and
3,052 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<!-- IMPORTANT! Read [the contributing guide](../blob/master/CONTRIBUTING.md) before opening the PR for review. --> | ||
|
||
## Context and Summary | ||
|
||
<!-- Document the context, summary or any other information relating to this PR. The purpose is to provide with the reviewer a clear technical overview/headsup for this PR. This can also be any technical explanation to why the original issues or specs is implemented this way. --> | ||
|
||
<!-- For Bug fixes, document how/why bugs happened and how the fix actually fix the bug. --> | ||
|
||
## Link to Issues | ||
|
||
<!-- Links to github issues. If there is a spec append spec links here too. --> | ||
|
||
## Verification and Test Notes | ||
|
||
<!-- Document unit tests added, cases covered, proposed end to end testing (if needed), and manual verification steps taken, including links to Amplitude dashboards when Analytics are affected. --> | ||
|
||
## PR Checklist | ||
|
||
- [ ] Context and Summary about the why and what | ||
- [ ] Document how/why bug happened and fixed | ||
- [ ] Code matches coding standards (call out any exceptions) | ||
- [ ] Unit tests have been added/updated to provide complete coverage for the code in this PR | ||
- [ ] Documentation has been updated appropriately | ||
- [ ] Are all test passing (`npm run test`) | ||
|
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 |
---|---|---|
|
@@ -42,4 +42,4 @@ Thumbs.db | |
.eslintcache | ||
.testInput | ||
.testOutput | ||
.assetpack | ||
.asset-pack |
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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 was deleted.
Oops, something went wrong.
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,105 +1,37 @@ | ||
import type { Plugin, PluginOptions } from '@assetpack/core'; | ||
import { hasTag } from '@assetpack/core'; | ||
import type { AssetPipe, PluginOptions } from '@assetpack/core'; | ||
import { multiPipe } from '@assetpack/core'; | ||
import type { WebpOptions, PngOptions, AvifOptions, JpegOptions } from 'sharp'; | ||
import { compression } from './compressions'; | ||
import { webpDefaults } from './webp'; | ||
import { pngDefaults } from './png'; | ||
import { avifDefaults } from './avif'; | ||
import { jpgDefaults } from './jpg'; | ||
import { compressAvif } from './compressAvif'; | ||
import { compressJpg } from './compressJpg'; | ||
import { compressWebp } from './compressWebp'; | ||
import { compressPng } from './compressPng'; | ||
|
||
export interface CompressOptions extends PluginOptions<'nc'> | ||
{ | ||
webp: Omit<WebpOptions, 'force'> | false | ||
png: Omit<PngOptions, 'force'> | false | ||
avif: Omit<AvifOptions, 'force'> | false | ||
jpg: Omit<JpegOptions, 'force'> | false | ||
webp?: Omit<WebpOptions, 'force'> | false | ||
png?: Omit<PngOptions, 'force'> | false | ||
avif?: Omit<AvifOptions, 'force'> | false | ||
jpg?: Omit<JpegOptions, 'force'> | false | ||
} | ||
|
||
// converts png, jpg, jpeg | ||
export function compress(options?: Partial<CompressOptions>): Plugin<CompressOptions> | ||
export function compress(options: Partial<CompressOptions> = {}): AssetPipe | ||
{ | ||
const combineOptions = (type: keyof CompressOptions, defaults: WebpOptions | PngOptions | AvifOptions | JpegOptions) => | ||
{ | ||
if (options?.[type] === false) return false; | ||
|
||
return { | ||
...defaults, | ||
...options?.[type] | ||
}; | ||
}; | ||
|
||
const defaultOptions: Required<CompressOptions> = { | ||
webp: combineOptions('webp', webpDefaults), | ||
png: combineOptions('png', pngDefaults), | ||
avif: combineOptions('avif', avifDefaults), | ||
jpg: combineOptions('jpg', jpgDefaults), | ||
tags: { | ||
nc: 'nc', | ||
...options?.tags | ||
} | ||
const tags = { | ||
nc: 'nc', | ||
...options?.tags | ||
}; | ||
|
||
return { | ||
folder: false, | ||
test(tree, _p, opts) | ||
{ | ||
const tags = { ...defaultOptions.tags, ...opts.tags } as Required<CompressOptions['tags']>; | ||
const nc = hasTag(tree, 'path', tags.nc); | ||
|
||
if (nc) return false; | ||
|
||
for (const key in compression.test) | ||
{ | ||
// skip if the plugin is disabled | ||
if ( | ||
opts[key as keyof typeof opts] === false | ||
|| defaultOptions[key as keyof typeof defaultOptions] === false | ||
) continue; | ||
|
||
const testFn = compression.test[key as keyof typeof compression.test]; | ||
|
||
if (testFn(tree.path)) return true; | ||
} | ||
|
||
return false; | ||
}, | ||
async post(tree, processor, options) | ||
{ | ||
const promises: Promise<void>[] = []; | ||
|
||
for (const key in compression.test) | ||
{ | ||
// skip if the plugin is disabled | ||
if ( | ||
options[key as keyof typeof options] === false | ||
|| defaultOptions[key as keyof typeof defaultOptions] === false | ||
) continue; | ||
|
||
const testFn = compression.test[key as keyof typeof compression.test]; | ||
|
||
if (testFn(tree.path)) | ||
{ | ||
// now we convert the file | ||
const opts = { | ||
...defaultOptions[key as keyof typeof defaultOptions], | ||
...options[key as keyof typeof options] | ||
}; | ||
|
||
promises.push(new Promise(async (resolve) => | ||
{ | ||
const res = await compression.compress.to[ | ||
key as keyof typeof compression.compress.to | ||
](tree.path, opts); | ||
// now we save the file | ||
|
||
compression.save.to[key as keyof typeof compression.save.to](tree.path, res, processor, tree); | ||
|
||
resolve(); | ||
})); | ||
} | ||
} | ||
|
||
await Promise.all(promises); | ||
} | ||
}; | ||
const compressionPipes = [ | ||
...(options.png === false ? [] : [compressPng({ compression: options.png, tags })]), | ||
...(options.jpg === false ? [] : [compressJpg({ compression: options.jpg, tags })]), | ||
...(options.webp === false ? [] : [compressWebp({ compression: options.webp, tags })]), | ||
...(options.avif === false ? [] : [compressAvif({ compression: options.avif, tags })]) | ||
]; | ||
|
||
return multiPipe({ | ||
pipes: compressionPipes, | ||
name: 'compress' | ||
}); | ||
} | ||
|
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,47 @@ | ||
import type { AssetPipe, Asset, PluginOptions } from '@assetpack/core'; | ||
import { checkExt, createNewAssetAt } from '@assetpack/core'; | ||
import type { AvifOptions } from 'sharp'; | ||
import sharp from 'sharp'; | ||
import { writeFile } from 'fs-extra'; | ||
|
||
interface CompressAvifOptions extends PluginOptions<'nc'> | ||
{ | ||
compression?: Omit<AvifOptions, 'force'>; | ||
} | ||
|
||
export function compressAvif(_options: CompressAvifOptions = {}): AssetPipe | ||
{ | ||
const defaultOptions = { | ||
compression: { | ||
..._options?.compression | ||
}, | ||
|
||
tags: { | ||
nc: 'nc', | ||
..._options?.tags | ||
} | ||
}; | ||
|
||
return { | ||
name: 'avif', | ||
folder: false, | ||
defaultOptions, | ||
test: (asset: Asset, options) => | ||
!asset.allMetaData[options.tags.nc] && checkExt(asset.path, '.png', '.jpg', '.jpeg'), | ||
|
||
transform: async (asset: Asset, options) => | ||
{ | ||
const newFileName = asset.filename.replace(/\.(png|jpg|jpeg)$/i, '.avif'); | ||
|
||
const newAsset = createNewAssetAt(asset, newFileName); | ||
|
||
const buffer = await sharp(asset.path) | ||
.avif({ ...options.compression, force: true }) | ||
.toBuffer(); | ||
|
||
await writeFile(newAsset.path, buffer); | ||
|
||
return [newAsset]; | ||
} | ||
}; | ||
} |
Oops, something went wrong.