diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bae999..4845494 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0 + +- Introduces filters + ## 1.0.5 - Switches ownership diff --git a/README.md b/README.md index c7bcbd0..7560f53 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,27 @@ export default { }; ``` +You can provide a filter to exclude files in your build. A filter can be an +array of regexes or a single match. You can use functions, as well to match on +file names. + +**`astro.config.ts`** + +```ts +import critters from "astro-critters"; + +export default { + integrations: [ + critters({ + exclude: [ + "my-awesome.html", + (file: string) => file === "./dist/index.html", + ], + }), + ], +}; +``` + [astro-critters]: https://npmjs.org/astro-critters [critters]: https://github.com/GoogleChromeLabs/critters [astro-integration]: https://docs.astro.build/en/guides/integrations-guide/ diff --git a/dist/lib/parse.d.ts b/dist/lib/parse.d.ts index 409b484..4ba34fe 100644 --- a/dist/lib/parse.d.ts +++ b/dist/lib/parse.d.ts @@ -1,2 +1,3 @@ -declare const _default: (glob: string, debug?: number, type?: string, write?: (data: string) => any, read?: (file: string) => any) => Promise; +import type { Options } from "../options/index.js"; +declare const _default: (glob: string, debug: number | undefined, type: string | undefined, exclude: Options["exclude"], write?: (data: string) => any, read?: (file: string) => any) => Promise; export default _default; diff --git a/dist/lib/parse.js b/dist/lib/parse.js index cd2b285..db246a6 100644 --- a/dist/lib/parse.js +++ b/dist/lib/parse.js @@ -1 +1 @@ -import c from"fast-glob";import o from"fs";var p=async(n,a=2,f="",l=async i=>i,r=async i=>await o.promises.readFile(i,"utf-8"))=>{const i=await c(n),e={files:0,total:0};for(const t of i)try{const s=await l(await r(t));if(!s)continue;await o.promises.writeFile(t,s,"utf-8"),e.files++}catch{console.log("Error: Cannot inline file "+t+"!")}a>0&&e.files>0&&console.info("\x1B[32mSuccessfully inlined a total of "+e.files+" "+f.toUpperCase()+" "+(e.files===1?"file":"files")+".\x1B[39m")};export{p as default}; +import d from"fast-glob";import s from"fs";var u=async(r,l=2,a="",e,c=async i=>i,p=async i=>await s.promises.readFile(i,"utf-8"))=>{const i=await d(r),o={files:0,total:0};let n=new Set;if(typeof e<"u")if(e instanceof Array)for(const f of e)n.add(f);else n.add(e);for(const f of n){if(typeof f=="string")for(const t of i)t.match(f)&&i.splice(i.indexOf(t),1);if(typeof f=="function")for(const t of i)f(t)&&i.splice(i.indexOf(t),1)}for(const f of i)try{const t=await c(await p(f));if(!t)continue;await s.promises.writeFile(f,t,"utf-8"),o.files++}catch{console.log(`Error: Cannot inline file ${f}!`)}l>0&&o.files>0&&console.info(`\x1B[32mSuccessfully inlined a total of ${o.files} ${a.toUpperCase()} ${o.files===1?"file":"files"}.\x1B[39m`)};export{u as default}; diff --git a/dist/lib/pipe-all.js b/dist/lib/pipe-all.js index beb93e2..722f872 100644 --- a/dist/lib/pipe-all.js +++ b/dist/lib/pipe-all.js @@ -1 +1 @@ -import e from"critters";import i from"./parse.js";var f=async(t,o=2)=>{for(const a in t)if(Object.prototype.hasOwnProperty.call(t,a)){const r=t[a];if(!r)continue;switch(a){case"critters":await i(`${t.path}**/*.html`,o,"html",async p=>(r.path=r.path?r.path:t.path,await new e(r).process(p)));break;default:break}}};export{f as default}; +import p from"critters";import i from"./parse.js";var f=async(t,o=2)=>{for(const a in t)if(Object.prototype.hasOwnProperty.call(t,a)){const r=t[a];if(!r)continue;switch(a){case"critters":{await i(`${t.path}**/*.html`,o,"html",t?.exclude,async e=>(r.path=r.path?r.path:t.path,await new p(r).process(e)));break}default:break}}};export{f as default}; diff --git a/dist/options/index.d.ts b/dist/options/index.d.ts index c9d79e5..be544c8 100644 --- a/dist/options/index.d.ts +++ b/dist/options/index.d.ts @@ -1,7 +1,9 @@ import type { Options as CrittersOptions } from "critters"; +export declare type excludeFn = (file: string) => boolean; export interface Options { [key: string]: any; path?: string; + exclude?: string | RegExp | excludeFn | [string] | [RegExp] | [excludeFn]; critters?: boolean | CrittersOptions; logger?: number; } diff --git a/dist/options/index.js b/dist/options/index.js index a35bcd9..10f3d20 100644 --- a/dist/options/index.js +++ b/dist/options/index.js @@ -1 +1 @@ -var t=()=>({path:"./dist/",critters:{preload:"swap",inlineFonts:!0,compress:!0,pruneSource:!0},logger:2});export{t as default}; +var e=()=>({path:"./dist/",critters:{preload:"swap",inlineFonts:!0,compress:!0,pruneSource:!0},logger:2});export{e as default}; diff --git a/package.json b/package.json index 09059b4..f1b1b6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "astro-critters", - "version": "1.0.5", + "version": "1.1.0", "type": "module", "description": "🦔 AstroJS GoogleChromeLabs critters integration. Inline your critical CSS with Astro.", "repository": { diff --git a/src/index.ts b/src/index.ts index de820b4..654912f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,9 +24,9 @@ export default (options: Options = {}): AstroIntegration => { name: "astro-critters", hooks: { "astro:config:done": async (options) => { - _options.path = !_options.path - ? options.config.outDir.toString() - : _options.path; + _options.path = _options.path + ? _options.path + : options.config.outDir.toString(); }, "astro:build:done": async () => { await pipeAll(_options, _options.logger); diff --git a/src/lib/parse.ts b/src/lib/parse.ts index b64d1ed..e5a278f 100644 --- a/src/lib/parse.ts +++ b/src/lib/parse.ts @@ -1,10 +1,12 @@ import FastGlob from "fast-glob"; import fs from "fs"; +import type { Options } from "../options/index.js"; export default async ( glob: string, debug: number = 2, type: string = "", + exclude: Options["exclude"], write: (data: string) => any = async (data) => data, read: (file: string) => any = async (file) => await fs.promises.readFile(file, "utf-8") @@ -16,6 +18,36 @@ export default async ( total: 0, }; + let filters = new Set(); + + if (typeof exclude !== "undefined") { + if (exclude instanceof Array) { + for (const excludes of exclude) { + filters.add(excludes); + } + } else { + filters.add(exclude); + } + } + + for (const filter of filters) { + if (typeof filter === "string") { + for (const file of files) { + if (file.match(filter)) { + files.splice(files.indexOf(file), 1); + } + } + } + + if (typeof filter === "function") { + for (const file of files) { + if (filter(file)) { + files.splice(files.indexOf(file), 1); + } + } + } + } + for (const file of files) { try { const writeBuffer = await write(await read(file)); @@ -28,19 +60,17 @@ export default async ( inlines.files++; } catch (error) { - console.log("Error: Cannot inline file " + file + "!"); + console.log(`Error: Cannot inline file ${file}!`); } } if (debug > 0 && inlines.files > 0) { console.info( - "\u001b[32mSuccessfully inlined a total of " + - inlines.files + - " " + - type.toUpperCase() + - " " + - (inlines.files === 1 ? "file" : "files") + - ".\u001b[39m" + `\u001b[32mSuccessfully inlined a total of ${ + inlines.files + } ${type.toUpperCase()} ${ + inlines.files === 1 ? "file" : "files" + }.\u001b[39m` ); } }; diff --git a/src/lib/pipe-all.ts b/src/lib/pipe-all.ts index 7721f42..a538168 100644 --- a/src/lib/pipe-all.ts +++ b/src/lib/pipe-all.ts @@ -13,20 +13,22 @@ export default async (settings: Options, debug: number = 2) => { } switch (files) { - case "critters": + case "critters": { await parse( `${settings.path}**/*.html`, debug, "html", - async (data) => { - setting.path = !setting.path - ? settings.path - : setting.path; + settings?.exclude, + async (data: any) => { + setting.path = setting.path + ? setting.path + : settings.path; return await new Critters(setting).process(data); } ); break; + } default: break; diff --git a/src/options/index.ts b/src/options/index.ts index 145d376..11fff2e 100644 --- a/src/options/index.ts +++ b/src/options/index.ts @@ -1,9 +1,14 @@ import type { Options as CrittersOptions } from "critters"; +export type excludeFn = (file: string) => boolean; export interface Options { [key: string]: any; path?: string; + + exclude?: string | RegExp | excludeFn | [string] | [RegExp] | [excludeFn]; + critters?: boolean | CrittersOptions; + logger?: number; }