From 697db6df22e408b8a8099cd77a36303b03170b12 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:13:08 +0000 Subject: [PATCH 01/17] fix: proper hash fingerprint of static file --- src/generate.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/generate.ts b/src/generate.ts index b7b562f52..f116d64fc 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -1,15 +1,27 @@ -import { createWriteStream } from 'fs' +import { createWriteStream, existsSync } from 'fs' import { promisify } from 'util' import stream from 'stream' +import path from 'path' import { mkdirp } from 'fs-extra' import { dirname, join, relative, basename, trimExt } from 'upath' import { fetch } from 'node-fetch-native' import { joinURL, hasProtocol, parseURL, withoutTrailingSlash } from 'ufo' +import hasha from 'hasha' import pLimit from 'p-limit' import { ModuleOptions, MapToStatic, ResolvedImage } from './types' import { hash, logger, guessExt } from './utils' +function getHash (input: string, url: string) { + const staticFile = path.join(process.cwd(), 'static', input) + + if (existsSync(staticFile)) { + return hasha.fromFileSync(staticFile) + } + + return hash(url) +} + export function setupStaticGeneration (nuxt: any, options: ModuleOptions) { const staticImages: Record = {} // url ~> hashed file name @@ -21,7 +33,7 @@ export function setupStaticGeneration (nuxt: any, options: ModuleOptions) { const params: any = { name: trimExt(basename(pathname)), ext: (format && `.${format}`) || guessExt(input), - hash: hash(url), + hash: getHash(input, url), // TODO: pass from runtimeConfig to mapStatic as param publicPath: nuxt.options.app.cdnURL ? '/' : withoutTrailingSlash(nuxt.options.build.publicPath) } From 8ffec3518fab50fc76d849d9abb7885048f18b95 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:20:13 +0000 Subject: [PATCH 02/17] chore(release): 0.8.0 --- CHANGELOG.md | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- 2 files changed, 190 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bbe98d22..89896ffb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,193 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## 0.8.0 (2023-01-20) + + +### ⚠ BREAKING CHANGES + +* **pkg:** add engines field to require `node>=14.16` +* switch to unbuild +* update dependencies +* update ipx to 0.8.x +* prepend router base (#339) +* remove nuxt-picture wrapper +* screen based responsive (#182) +* improved $img interface (#169) + +### Features + +* `staticFilename` option to customize static image filenames ([#220](https://github.com/nuxt/image/issues/220)) ([975b1a2](https://github.com/nuxt/image/commit/975b1a2c72a60172b0b373036dfa197980b1c32a)) +* $img.getSources and better srcset for `` ([36e039b](https://github.com/nuxt/image/commit/36e039b5ada9d917cfb6eea225b188b56b00768f)) +* a11y ([1732d62](https://github.com/nuxt/image/commit/1732d6228b10ecb3b7ca1939ec37f706739b2180)) +* add `cacheDir` options ([449a005](https://github.com/nuxt/image/commit/449a00561080c6b654eccf07c7db43ef6c8a8e24)) +* add `imgAttrs` property to `` ([#445](https://github.com/nuxt/image/issues/445)) ([448d9ef](https://github.com/nuxt/image/commit/448d9efd5b80deb37d0bf544208357663c2795cf)) +* add background prop ([ec8d1ce](https://github.com/nuxt/image/commit/ec8d1ce68bfde46e819311b5e62fe5fb9af097a1)) +* add click listener ([cbe2351](https://github.com/nuxt/image/commit/cbe2351b9da0ac5d021942455e99c7db474aacb6)) +* add component aliases ([845579b](https://github.com/nuxt/image/commit/845579bf9d7b324712bf11f54d89a205853fd7a3)) +* add contentful provider ([#398](https://github.com/nuxt/image/issues/398)) ([3eccba6](https://github.com/nuxt/image/commit/3eccba645fb7cc8d04a835a8559e8b9ee1d53103)) +* add fastly provider ([#15](https://github.com/nuxt/image/issues/15)) ([34ceb3c](https://github.com/nuxt/image/commit/34ceb3c4180b7765f87729ed5ae548ac4b3aa114)) +* add ImageEngine provider ([#456](https://github.com/nuxt/image/issues/456)) ([3f00cf3](https://github.com/nuxt/image/commit/3f00cf33a4f255cb2501d1fa7ec9fdc2b315e0ed)) +* add module option to modify `IntersectionObserver` options ([#41](https://github.com/nuxt/image/issues/41)) ([9f9b920](https://github.com/nuxt/image/commit/9f9b920c18c76227d15981be5f465b46da8183d8)) +* add netlify provider ([#299](https://github.com/nuxt/image/issues/299)) ([003e144](https://github.com/nuxt/image/commit/003e14404789ca17688939104537fab7eee15f0e)) +* add preload functionality ([#444](https://github.com/nuxt/image/issues/444)) ([6f245c6](https://github.com/nuxt/image/commit/6f245c67fc51179ae6abd6395571be036eaa9c79)) +* add prismic provider ([#269](https://github.com/nuxt/image/issues/269)) ([306064b](https://github.com/nuxt/image/commit/306064bc2b330ba38d20a575bdcae5e832959311)) +* add sanity provider ([#164](https://github.com/nuxt/image/issues/164)) ([6483c34](https://github.com/nuxt/image/commit/6483c341e6c62c2871a56404904ec8a17b2df676)) +* add storyblok provider ([#133](https://github.com/nuxt/image/issues/133)) ([cf04f1f](https://github.com/nuxt/image/commit/cf04f1f1c00e6aec3ad23821865788b3c8b4fe86)) +* allow overiding sharp options ([7df04ca](https://github.com/nuxt/image/commit/7df04ca11eca53ef60074a2fb4aa94ac84870d13)) +* allow sizes key to be screen width ([6624440](https://github.com/nuxt/image/commit/6624440ef84588c48f86c217157863b5ffd52706)) +* allow top level provider options ([7b47d6e](https://github.com/nuxt/image/commit/7b47d6e8ded1e3f78522b300b4543a44f98fbb87)) +* allow/disallow remote urls ([0856343](https://github.com/nuxt/image/commit/08563435ab8606409d68c1e214442f201ee88cd8)) +* auto detect image ratio ([#37](https://github.com/nuxt/image/issues/37)) ([0f6e17e](https://github.com/nuxt/image/commit/0f6e17ea986925f7a5728a0e098c526bc9d7a137)) +* cloudflare provider ([#359](https://github.com/nuxt/image/issues/359)) ([94625ce](https://github.com/nuxt/image/commit/94625ce94a398471312010d7af4f02e52a4ec57c)) +* cloudimage provider ([#523](https://github.com/nuxt/image/issues/523)) ([33b36bc](https://github.com/nuxt/image/commit/33b36bcba339d6ebfd83397c90b5f48824eb7523)) +* **cloudinary:** add types for options and modifiers ([#511](https://github.com/nuxt/image/issues/511)) ([79c1580](https://github.com/nuxt/image/commit/79c1580d3f2a3a8dba37d54ff67b55b849c9935f)) +* **componets:** introduce `no-script` prop ([eb522b7](https://github.com/nuxt/image/commit/eb522b7e78ddd96ef6eea264cca665ead2ddfeec)) +* emit native `` events ([#416](https://github.com/nuxt/image/issues/416)) ([f22ae01](https://github.com/nuxt/image/commit/f22ae016912470c083c7b565fd67947a8f441093)) +* expose vetur helpers ([#195](https://github.com/nuxt/image/issues/195)) ([543e7cf](https://github.com/nuxt/image/commit/543e7cf00c8383e12ba68739ef919aed009d2084)) +* fix full static support ([caaff86](https://github.com/nuxt/image/commit/caaff86daea8adc540524e2deed8cb832893cf6f)) +* **generate:** generate local file on static generation ([0f46395](https://github.com/nuxt/image/commit/0f463953a27514407060334cd8c60e3216892320)) +* glide provider ([#328](https://github.com/nuxt/image/issues/328)) ([1d85042](https://github.com/nuxt/image/commit/1d8504297e9917efbd7c6df0391507e5e79ead3f)) +* gumlet image provider ([#489](https://github.com/nuxt/image/issues/489)) ([8aaab14](https://github.com/nuxt/image/commit/8aaab1466f6591e78b9a1eb28fe8cfbb607c0fb8)) +* imagekit provider implementation and tests ([#109](https://github.com/nuxt/image/issues/109)) ([fa8be15](https://github.com/nuxt/image/commit/fa8be154f76194a38afa0ced75e529736a39b95b)) +* **imagekit:** add modifiers and improve docs ([#336](https://github.com/nuxt/image/issues/336)) ([d53fda5](https://github.com/nuxt/image/commit/d53fda53df829fd8f5d9c5cd41e0747d2e04b52b)) +* **imgix:** additional documentation and modifiers ([#316](https://github.com/nuxt/image/issues/316)) ([c90b484](https://github.com/nuxt/image/commit/c90b484208c478823f21368f0626fc253ec31250)) +* **imgix:** format keys ([#364](https://github.com/nuxt/image/issues/364)) ([ce66fa7](https://github.com/nuxt/image/commit/ce66fa770c0a02381eb17b5e38b62fa08f318210)) +* **img:** support `` attributes ([9ed71da](https://github.com/nuxt/image/commit/9ed71dae8f61b5fcae3276329dbb17408ef37c60)) +* improved $img interface ([#169](https://github.com/nuxt/image/issues/169)) ([40ab562](https://github.com/nuxt/image/commit/40ab5624f733631298975d76e673923916dd46c6)) +* inline styles ([#67](https://github.com/nuxt/image/issues/67)) ([6909267](https://github.com/nuxt/image/commit/690926736cd7cc7e7ffbe362bee5cbd25346f328)) +* ipx production support ([#257](https://github.com/nuxt/image/issues/257)) ([f625c92](https://github.com/nuxt/image/commit/f625c9246b90a1aea5ea0175dad025c7ebc5c204)) +* **ipx:** compatible with 0.7.x ([017c335](https://github.com/nuxt/image/commit/017c33514df00267dfa5f05429a573bca39ecc7a)) +* keep internal provider enable ([#60](https://github.com/nuxt/image/issues/60)) ([349b40a](https://github.com/nuxt/image/commit/349b40aea54d2d99274892bb0f261f34ee47a612)) +* layer0 provider ([#501](https://github.com/nuxt/image/issues/501)) ([5de4eb6](https://github.com/nuxt/image/commit/5de4eb6bf0f094ef206902b119669d78bbcb8909)) +* load all images on print ([#66](https://github.com/nuxt/image/issues/66)) ([2c034de](https://github.com/nuxt/image/commit/2c034de136780c82f1330205248f1ac95640b7f4)) +* **nuxt-img:** handle loading=lazy with observer ([abb32a1](https://github.com/nuxt/image/commit/abb32a1e6e814daefe7fd7e7a145405f7687fd7b)) +* **nuxt-img:** responsive prop ([#155](https://github.com/nuxt/image/issues/155)) ([3dcee93](https://github.com/nuxt/image/commit/3dcee9322663a10e1e16a7de373c5a483ec2d7b1)) +* **picture:** init nuxt-picture ([bce1645](https://github.com/nuxt/image/commit/bce164532a555764947bac898839f0b2add42387)) +* **pkg:** add engines field to require `node>=14.16` ([38d77f1](https://github.com/nuxt/image/commit/38d77f125ade661dca369babc2e6bc881da2a553)) +* preserve images name on generation ([3f789fc](https://github.com/nuxt/image/commit/3f789fc504fd88187424c6961bb384c4dbbdd9ec)) +* **provider:** unsplash ([#357](https://github.com/nuxt/image/issues/357)) ([ad6c1ae](https://github.com/nuxt/image/commit/ad6c1ae3bcff9e9c4096bfab70de195abcb4601d)) +* remove nuxt-picture wrapper ([8d7d84b](https://github.com/nuxt/image/commit/8d7d84b0bf2b8bdf9be5c73d5b968b9a827545f3)) +* **runtime:** add imgix provider ([#29](https://github.com/nuxt/image/issues/29)) ([3f4a6a5](https://github.com/nuxt/image/commit/3f4a6a5dd0bca5d16d7a69e66f20cd13c97291e7)) +* **runtime:** catch image exceptions and prevent page crash ([#43](https://github.com/nuxt/image/issues/43)) ([e5190c1](https://github.com/nuxt/image/commit/e5190c18fea142db5e41176a669b00c358a740b8)) +* **sanity:** sanity provider enhancements ([#301](https://github.com/nuxt/image/issues/301)) ([288997b](https://github.com/nuxt/image/commit/288997bd5aa7a8bc4a8284ad08e6a3b04f733fe8)) +* screen based responsive ([#182](https://github.com/nuxt/image/issues/182)) ([51e2e0a](https://github.com/nuxt/image/commit/51e2e0aa34a46fe7713f6a96db8ba933182ded05)) +* **srcset:** introduce `sets` props to create srcset ([e330900](https://github.com/nuxt/image/commit/e330900b002c02a5b2fde960a99e9366dc1cb67d)) +* **storyblok:** update to the new service ([#497](https://github.com/nuxt/image/issues/497)) ([3edbd22](https://github.com/nuxt/image/commit/3edbd22f647c77b8d7c92ab8fccd47155c3178a1)) +* strapi provider ([#406](https://github.com/nuxt/image/issues/406)) ([8245c22](https://github.com/nuxt/image/commit/8245c22119dc14809b66ef08140951879bf54cf1)) +* support `clearCache` on local provider ([ba239a4](https://github.com/nuxt/image/commit/ba239a4eb8f3fdcfef0d11e1e7cdf89d5cf31465)) +* support `NUXT_IMAGE_PROVIDER` environment variable ([1385eb8](https://github.com/nuxt/image/commit/1385eb8d3304c1c821bb4154519b7e253e177090)) +* support alias ([#348](https://github.com/nuxt/image/issues/348)) ([3d11b87](https://github.com/nuxt/image/commit/3d11b8781bc01667b1b6394ac34f36c57d461f16)) +* support assets using remote adapter ([acff75c](https://github.com/nuxt/image/commit/acff75ca54501aa74e12191538ab07bb75f65e7b)) +* support cloudinary fetch base url ([#218](https://github.com/nuxt/image/issues/218)) ([31bef1e](https://github.com/nuxt/image/commit/31bef1eb56c2ef5905c209d8000a7cde8597c16d)) +* support modifiers prop for components ([#154](https://github.com/nuxt/image/issues/154)) ([6fe9e8f](https://github.com/nuxt/image/commit/6fe9e8fa87a7f3b905b3bf3f7c20ebc36b027050)) +* support placeholder ([#477](https://github.com/nuxt/image/issues/477)) ([fc7e3d5](https://github.com/nuxt/image/commit/fc7e3d57f0f713c8d089f811640cb3d16b287da4)) +* support providers and presets with props ([189cfb9](https://github.com/nuxt/image/commit/189cfb9d9496d52b184f314c2c10881108fe00aa)) +* support remote urls ([fd4184b](https://github.com/nuxt/image/commit/fd4184beefd71a926113917b6f370401db559cd8)) +* support responsive prop to generate sizes ([7e3f80b](https://github.com/nuxt/image/commit/7e3f80ba798eee2c267d77fb68b8b4cd16704866)) +* support types for config ([4d7bf06](https://github.com/nuxt/image/commit/4d7bf065cda9365c88e7485d8d6f5c7d9cac6793)) +* **twicpics:** fix modifiers and improve documentation ([#503](https://github.com/nuxt/image/issues/503)) ([7942232](https://github.com/nuxt/image/commit/7942232bfa2cd60e27ac63bffe011f2f7a15f716)) +* type improvements ([#222](https://github.com/nuxt/image/issues/222)) ([6dc8aa0](https://github.com/nuxt/image/commit/6dc8aa059b6f12139301cb0c7732743565a877ea)) +* universal meta resolving ([#55](https://github.com/nuxt/image/issues/55)) ([45bbbe9](https://github.com/nuxt/image/commit/45bbbe9858da7f16c6f95c499dcb144874505e97)) +* update dependencies ([d4de9d3](https://github.com/nuxt/image/commit/d4de9d3502a89470f32da67d264715efb118239e)) +* use ipx@0.5.x ([fe92ecf](https://github.com/nuxt/image/commit/fe92ecf0e47d579478123bb777ba07785c184fd0)) +* user-defined presets ([3e7b1cf](https://github.com/nuxt/image/commit/3e7b1cf3521c60fbe12c7a160c9c82cfd044b382)) +* validate external domains ([#343](https://github.com/nuxt/image/issues/343)) ([bee0040](https://github.com/nuxt/image/commit/bee00400837b4276bacf73731d56374e3f5ce3a0)) +* vercel image provider ([#210](https://github.com/nuxt/image/issues/210)) ([69e4af7](https://github.com/nuxt/image/commit/69e4af749103e730d758f7636ddfce1fee4d55c7)) +* **vercel:** remove protocol from vercel domains ([086227c](https://github.com/nuxt/image/commit/086227ca5d3c1ea2d6dc424fbcf68b85e48318ce)), closes [#242](https://github.com/nuxt/image/issues/242) + + +### Bug Fixes + +* add guard for `ssrContext` existence ([d8aa3a1](https://github.com/nuxt/image/commit/d8aa3a10668786b56b32b9acc2ae4b03e0653d44)), closes [#258](https://github.com/nuxt/image/issues/258) [#249](https://github.com/nuxt/image/issues/249) +* add types for pick utility and fix issues with imageOptions ([#156](https://github.com/nuxt/image/issues/156)) ([63aaa8a](https://github.com/nuxt/image/commit/63aaa8ae0c4b5bf0786f5a809f194a4d0eb91b02)) +* allow full usage of $img in plugins ([#284](https://github.com/nuxt/image/issues/284)) ([b80f791](https://github.com/nuxt/image/commit/b80f79114fd14c0c7b36e38c867ee8db3e7d6711)) +* avoid dynamic import of `lru-cache` (resolves [#481](https://github.com/nuxt/image/issues/481)) ([61bcb90](https://github.com/nuxt/image/commit/61bcb90f0403df804506ccbecebfe13605ae56b4)) +* clean up `undefined` values ([bf9e040](https://github.com/nuxt/image/commit/bf9e0408f4af2b291ed9c7254bf0c7f46f85f6d4)) +* cleanup double slashes outside of provider runtime ([d71b03a](https://github.com/nuxt/image/commit/d71b03aa575264170c79548cd9b6d2b915b73565)) +* **cloudinary:** fit types, auto format & quality ([#76](https://github.com/nuxt/image/issues/76)) ([74ef445](https://github.com/nuxt/image/commit/74ef445b5ffd740e28722fd68a45192234fc52cc)) +* **cloudinary:** use `jpg` instead of `jpeg` ([#255](https://github.com/nuxt/image/issues/255)) ([7d49fa8](https://github.com/nuxt/image/commit/7d49fa8de9e5a5437068991b19659558b5db850c)), closes [#254](https://github.com/nuxt/image/issues/254) +* **deps:** add missing lru-cache ([0af0bf3](https://github.com/nuxt/image/commit/0af0bf39644c179f7c1cd664f60cdbb3e9aae2ea)) +* disable blur filter on custom placeholder ([3f277a3](https://github.com/nuxt/image/commit/3f277a3ea20491dfe13a5e0a85039f95ec34e384)) +* do not generate multiple sizes for SVG files ([7e385c3](https://github.com/nuxt/image/commit/7e385c3369ec3b3171f88c51be4437d0e1e75233)) +* do not render image without src ([cbeada1](https://github.com/nuxt/image/commit/cbeada1d77244fc234b2a17e1fd2060c72ac3628)) +* do not sent data urls to provider ([565445f](https://github.com/nuxt/image/commit/565445f27f03198fd876cdf7916cc0f81dbe02c8)) +* domain normalization when no protocol and port are provided ([c6c7085](https://github.com/nuxt/image/commit/c6c70855b5eaf302614bdfb5b4d611a4aca42781)) +* don't allow undefined values to override defaults ([#274](https://github.com/nuxt/image/issues/274)) ([d2e65f9](https://github.com/nuxt/image/commit/d2e65f904b722b380ff9c1aa6d1617051625c654)), closes [#273](https://github.com/nuxt/image/issues/273) +* enable default provider for resolving ([18ed241](https://github.com/nuxt/image/commit/18ed241109c0064ddacff9dc6877ce5f4e42139e)) +* ensure component needs placeholder ([029f2cf](https://github.com/nuxt/image/commit/029f2cfaf40c654cd924324c19b473c1b5229fd7)) +* ensure payload includes up-to-date _img ([#303](https://github.com/nuxt/image/issues/303)) ([03ea6fe](https://github.com/nuxt/image/commit/03ea6fe2e7d214550a91ea312b0a79557dc50c60)) +* ensure static image map is available on first load ([#236](https://github.com/nuxt/image/issues/236)) ([466d5a8](https://github.com/nuxt/image/commit/466d5a8e4e3146631090455bed9d9952cf34f86e)) +* fix typo regression for height modifier (fixes [#262](https://github.com/nuxt/image/issues/262)) ([9a93f19](https://github.com/nuxt/image/commit/9a93f19363e68421771496085ec0d3e441bb86d2)) +* **full-static:** find hashed images from page payload ([f7512c7](https://github.com/nuxt/image/commit/f7512c7e8c0c5c381d67e8288a57040182d1a827)) +* generate static images even if lazy loaded ([#233](https://github.com/nuxt/image/issues/233)) ([5be72a5](https://github.com/nuxt/image/commit/5be72a563e13bbceccfbbc889fb4d4f60bcee68d)), closes [#232](https://github.com/nuxt/image/issues/232) +* **glide:** prevent adding duplicate base url ([#362](https://github.com/nuxt/image/issues/362)) ([d792e1e](https://github.com/nuxt/image/commit/d792e1eba3b9345dce733fe7b339c2004f929d53)) +* image ratio calculation ([b88bb9c](https://github.com/nuxt/image/commit/b88bb9c8e29d8064420ac1277649a0a7e5f6661a)) +* **image:** ratio calc regression (fixes [#238](https://github.com/nuxt/image/issues/238)) ([5e28edd](https://github.com/nuxt/image/commit/5e28edd005b76fc4872efc15b9ba9fb7cb75b66d)) +* **image:** use defu for options and fix default format ([#166](https://github.com/nuxt/image/issues/166)) ([cf2e9c1](https://github.com/nuxt/image/commit/cf2e9c13755f8eb440df1881b84145693e180f61)) +* **img:** handle ststic images in with prod server target ([95dd0c6](https://github.com/nuxt/image/commit/95dd0c6848e14c93e2a6e0d983548044c6d87067)) +* improve error readability ([#79](https://github.com/nuxt/image/issues/79)) ([763f215](https://github.com/nuxt/image/commit/763f2152654986d8976f8cefe33364f591ada540)) +* improvements to make it work with Nuxt content ([46cc0e2](https://github.com/nuxt/image/commit/46cc0e21e853ad98db185da37375311963ec7716)) +* **ipx:** `nuxtContext` is optional ([37f09b0](https://github.com/nuxt/image/commit/37f09b0f04d1f6c15378c792d2447887907f5a4c)) +* **ipx:** allow overriding `baseURL` regardless of router base ([#484](https://github.com/nuxt/image/issues/484)) ([2720956](https://github.com/nuxt/image/commit/2720956035416191df71642822b8bf9c1b5e97bd)) +* **ipx:** default modifiers to _ ([3c18ad8](https://github.com/nuxt/image/commit/3c18ad8bd8d54d1b82ef68538f28cef79b7f54f9)) +* limit static download concurrency ([#217](https://github.com/nuxt/image/issues/217)) ([bb4af1a](https://github.com/nuxt/image/commit/bb4af1a46929bc5a0260b53ffcb0b3dab4aeecc1)) +* **local-provider:** resolve input dir alias ([0a612d5](https://github.com/nuxt/image/commit/0a612d5dd4f98c3e87625e964762c7a398a0fd62)), closes [#47](https://github.com/nuxt/image/issues/47) +* **local:** remove baseUrl from provider options ([e0ec956](https://github.com/nuxt/image/commit/e0ec9561a360880e6c3cf1662998e4bf98a0570e)) +* merge merge presets with inline modifiers ([164af06](https://github.com/nuxt/image/commit/164af0621556bd4fd106b230ed92c4de69199574)) +* **module:** add package name to transpile list as well ([f97b34a](https://github.com/nuxt/image/commit/f97b34aaaaf8ed519d661c19c952e94e21e82d30)) +* move `ipx` to optional dependencies ([#403](https://github.com/nuxt/image/issues/403)) ([0affa9d](https://github.com/nuxt/image/commit/0affa9dbab1c582f27cce9133479517c2a4bd43a)) +* normalize domains to hostname (resolves [#486](https://github.com/nuxt/image/issues/486)) ([9f53d28](https://github.com/nuxt/image/commit/9f53d28067dc6dc5739754f06c2b64eb17edd500)) +* **nuxt-img, nuxt-picture:** return empty object from `head` when preload is disabled ([#528](https://github.com/nuxt/image/issues/528)) ([86088e4](https://github.com/nuxt/image/commit/86088e4f43e9f9e351e15afb8d9da4bb6e10b436)) +* **nuxt-img:** set key to allow making transitions ([20ed72b](https://github.com/nuxt/image/commit/20ed72b376b6845e6e5fd5fa14f698403c43ea34)) +* opacity ([1220c6a](https://github.com/nuxt/image/commit/1220c6a4f726797f036fc1a469f26480a401be0a)) +* parse width and height modifiers ([dd2bf78](https://github.com/nuxt/image/commit/dd2bf786371272252a6edf518f38835be03d00d9)) +* pass `domains` to runtime options ([#333](https://github.com/nuxt/image/issues/333)) ([33ada92](https://github.com/nuxt/image/commit/33ada92b5a9cfdfdee4353ad88a3190807a6c857)), closes [#324](https://github.com/nuxt/image/issues/324) +* **picture:** call `getMeta` with current arguments ([d43daf2](https://github.com/nuxt/image/commit/d43daf2b00ebf3bf1402158126a243270fb5e45d)) +* **picture:** show image after load ([709d8e7](https://github.com/nuxt/image/commit/709d8e753410bb813886967e47de56ec295632d0)) +* **pkg:** add missing consola and semver deps ([bc34597](https://github.com/nuxt/image/commit/bc345974da179e3dd7e4c068f59f77720c37c837)) +* **pkg:** use --ext js to avoid issues with mjs ([a483e14](https://github.com/nuxt/image/commit/a483e14514385b9ddc7cceef2fb8c982c3c6e362)) +* **plugin:** create static manifest for client hydration ([#162](https://github.com/nuxt/image/issues/162)) ([0b10c22](https://github.com/nuxt/image/commit/0b10c22f1661e6013b1f364365e0e4dd04dfc423)) +* prepend router base ([#339](https://github.com/nuxt/image/issues/339)) ([2d7a04d](https://github.com/nuxt/image/commit/2d7a04daefdc00abf692d7b8efb27c7f30e24e15)) +* proper hash fingerprint of static file ([697db6d](https://github.com/nuxt/image/commit/697db6df22e408b8a8099cd77a36303b03170b12)) +* **provider:** normalize runtime paths to support windows ([df9470f](https://github.com/nuxt/image/commit/df9470f8cbaf738df428761ac473f0c6d791be5a)) +* **provider:** use resolvePath to resolve aliases as well ([#161](https://github.com/nuxt/image/issues/161)) ([930e192](https://github.com/nuxt/image/commit/930e192f99a5bf2b00c7fb66316d67a062d81417)) +* reduce placeholders quality ([b20a8f9](https://github.com/nuxt/image/commit/b20a8f98c91ebdcf0a0f1c66bcb21ee13fc79833)) +* remove lazy loading polyfill in favour of native ([#256](https://github.com/nuxt/image/issues/256)) ([424bd44](https://github.com/nuxt/image/commit/424bd447bcc0eee52cf98a6ebcab67045a929837)), closes [#213](https://github.com/nuxt/image/issues/213) [#190](https://github.com/nuxt/image/issues/190) +* remove resolution server middleware ([fc34a73](https://github.com/nuxt/image/commit/fc34a73c71c77904133cb941425b05a790933c0b)) +* rename `nuxt-image` to `nuxt-img` ([df3b92c](https://github.com/nuxt/image/commit/df3b92c52adc5519911b1535a6c5fc64b1fae1c9)) +* rename default provider's option ([c1509fb](https://github.com/nuxt/image/commit/c1509fb45674f7a02aef10de1dbfc0a8a89be886)) +* resolve cache dir aliases ([5303699](https://github.com/nuxt/image/commit/5303699a0bd90df87796573aaac098d4cc1a169f)) +* **runtime:** fix runtime behavior ([0ed7625](https://github.com/nuxt/image/commit/0ed76251335750fb679bc1e0877de55ef908f257)) +* **runtime:** global nuxt variable to load page payload ([1869b0d](https://github.com/nuxt/image/commit/1869b0d68e49aeaf64b8998c0f6617b76c633568)) +* **runtime:** handle ssr false ([27c3445](https://github.com/nuxt/image/commit/27c3445fe39c14e7ed06873b88bfe625eaebb56d)) +* **runtime:** rename `size` prop to `fit` ([6174417](https://github.com/nuxt/image/commit/6174417935f7a2cc05a67032fb7d03909a27325b)), closes [#16](https://github.com/nuxt/image/issues/16) +* **runtime:** use file name from `src` if `alt` prop is missing ([19e6157](https://github.com/nuxt/image/commit/19e615763163c5e6c56dca5e6591bdc5adad741b)) +* sanitize backgroun modifier ([c1f3fb4](https://github.com/nuxt/image/commit/c1f3fb4afb6cb7bd1108ac6a83dc969fb06bb4ae)) +* set correct width and height for svg ([05e3bfe](https://github.com/nuxt/image/commit/05e3bfe87208132beaef3dabefde2f3ea0f273c3)) +* **sets-prop:** use width if breakpoint is missing ([d1f62df](https://github.com/nuxt/image/commit/d1f62df288cec4537b7d29a38f63f6d172bba2ab)) +* sizes as array should overwrites defaults ([339b7dd](https://github.com/nuxt/image/commit/339b7dd9756a7870b28f5c84e53f079a3220621c)) +* **static:** url encoded name included in generated ext ([#340](https://github.com/nuxt/image/issues/340)) ([58dd744](https://github.com/nuxt/image/commit/58dd744d39dc6a0e1f0c2dc89ea13f50efa7c91f)) +* tests & typo ([6f06e65](https://github.com/nuxt/image/commit/6f06e657a60816b740ca004d79a15588f229710c)) +* **twicpics:** fix minor issues and adds custom operations ([#132](https://github.com/nuxt/image/issues/132)) ([5a4e5d3](https://github.com/nuxt/image/commit/5a4e5d3fc90ac33f3c8262cdb9daa373f4187fc0)) +* use correct width and handle x2 ([97e3889](https://github.com/nuxt/image/commit/97e3889dcf47aa89d4218c959bec2268ce79a029)) +* use Math.round for generated width ([8ee9a40](https://github.com/nuxt/image/commit/8ee9a406c993a08d1cdd6ec7d6acaa68dc215fe4)) +* use ratio in getSizes ([8e5b658](https://github.com/nuxt/image/commit/8e5b658fa51132ad405ea4e09bf2c8d476d9f002)) +* use router base in generated images ([28ed0f2](https://github.com/nuxt/image/commit/28ed0f27c06fc7e10cf7e073d5eb2abd875a0c85)) +* vercel provider improvements ([#231](https://github.com/nuxt/image/issues/231)) ([9561daf](https://github.com/nuxt/image/commit/9561dafc3841d66e23123f797ea637f1f7802a8d)) +* **vercel:** add default proto for domains (fixes [#277](https://github.com/nuxt/image/issues/277)) ([f501914](https://github.com/nuxt/image/commit/f5019148cc358693817aa1d263316af424d3ef59)) +* **vercel:** fix vercel auto-detection and provide local vercel mode ([#246](https://github.com/nuxt/image/issues/246)) ([a156c66](https://github.com/nuxt/image/commit/a156c66fc52e2c27e7bf5e439ae8624f108d695d)) +* **vercel:** sort valid widths before picking largest ([#472](https://github.com/nuxt/image/issues/472)) ([f4a408f](https://github.com/nuxt/image/commit/f4a408f74e01eca50b2135bddde9b3e4be776cf5)) +* vue-loader support for PascalCase components ([#168](https://github.com/nuxt/image/issues/168)) ([8629e3f](https://github.com/nuxt/image/commit/8629e3f7ac84632992ce05f36356f1c165886e1d)) + + +* update ipx to 0.8.x ([7a75fa0](https://github.com/nuxt/image/commit/7a75fa00c43edbf9b0b9698d50a6c51f694c31fd)) + + +### build + +* switch to unbuild ([d7bb617](https://github.com/nuxt/image/commit/d7bb6178322480a176c07b57f96a580974e67a13)) + ## [0.7.0](https://github.com/nuxt/image/compare/v0.6.2...v0.7.0) (2022-06-22) diff --git a/package.json b/package.json index 71da02312..dd82a44ce 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nuxt/image", - "version": "0.7.0", + "version": "0.8.0", "description": "Nuxt Image Module", "repository": "nuxt/image", "license": "MIT", @@ -19,6 +19,7 @@ "lint": "eslint --ext .ts --ext .vue .", "prepack": "yarn build", "release": "yarn test && standard-version && git push --follow-tags && npm publish", + "release:no-test": "standard-version && git push --follow-tags && npm publish", "test": "yarn lint && yarn jest --forceExit", "test:e2e": "jest test/e2e --forceExit", "test:unit": "jest test/unit --forceExit" @@ -74,7 +75,7 @@ "ipx": "^0.9.9" }, "engines": { - "node": ">=14.16.0" + "node": ">=14.18.0" }, "publishConfig": { "access": "public" From 3756b154df590c27b443cc7edf7088b5e0005e7f Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:24:46 +0000 Subject: [PATCH 03/17] chore(release): 0.8.1 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89896ffb4..f8c16202b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.8.1](https://github.com/nuxt/image/compare/v0.8.0...v0.8.1) (2023-01-20) + ## 0.8.0 (2023-01-20) diff --git a/package.json b/package.json index dd82a44ce..859cfa78f 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nuxt/image", - "version": "0.8.0", + "version": "0.8.1", "description": "Nuxt Image Module", "repository": "nuxt/image", "license": "MIT", From 0149823b2e3fae989f223eedd135ea49fbb0a37f Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:25:15 +0000 Subject: [PATCH 04/17] chore(release): 0.8.2 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8c16202b..df28320eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.8.2](https://github.com/nuxt/image/compare/v0.8.1...v0.8.2) (2023-01-20) + ### [0.8.1](https://github.com/nuxt/image/compare/v0.8.0...v0.8.1) (2023-01-20) ## 0.8.0 (2023-01-20) diff --git a/package.json b/package.json index 859cfa78f..a23d7ebaa 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nuxt/image", - "version": "0.8.1", + "version": "0.8.2", "description": "Nuxt Image Module", "repository": "nuxt/image", "license": "MIT", From 2d74f3cd61b7609f60b6e2535498bf92706e146d Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:25:42 +0000 Subject: [PATCH 05/17] chore(release): 0.8.3 --- CHANGELOG.md | 2 ++ package.json | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df28320eb..355136075 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.8.3](https://github.com/nuxt/image/compare/v0.8.2...v0.8.3) (2023-01-20) + ### [0.8.2](https://github.com/nuxt/image/compare/v0.8.1...v0.8.2) (2023-01-20) ### [0.8.1](https://github.com/nuxt/image/compare/v0.8.0...v0.8.1) (2023-01-20) diff --git a/package.json b/package.json index a23d7ebaa..1c447ece6 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "@nuxt/image", - "version": "0.8.2", + "name": "nuxt-image", + "version": "0.8.3", "description": "Nuxt Image Module", "repository": "nuxt/image", "license": "MIT", From 502825c734776ff35c57203361e588fdc0394d22 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:28:38 +0000 Subject: [PATCH 06/17] chore(release): 0.8.4 --- CHANGELOG.md | 2 ++ package.json | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 355136075..a32d544d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.8.4](https://github.com/jthawme/nuxt-image-fork/compare/v0.8.3...v0.8.4) (2023-01-20) + ### [0.8.3](https://github.com/nuxt/image/compare/v0.8.2...v0.8.3) (2023-01-20) ### [0.8.2](https://github.com/nuxt/image/compare/v0.8.1...v0.8.2) (2023-01-20) diff --git a/package.json b/package.json index 1c447ece6..0937b4295 100755 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "nuxt-image", - "version": "0.8.3", + "name": "@jthawme/nuxt-image", + "version": "0.8.4", "description": "Nuxt Image Module", - "repository": "nuxt/image", + "repository": "https://github.com/jthawme/nuxt-image-fork", "license": "MIT", "sideEffects": false, "main": "./dist/module.cjs", From 5a441a98035b5d9c5fe79aa0bd10eb80e87b8600 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:30:33 +0000 Subject: [PATCH 07/17] fix: updated readme for context --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8b38ebd4d..2897499b0 100755 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +# HEY + +This is a fork, to fix the fingerprinting of static files. This package should in fact use the contents of the file to create the `[hash]` part of static filename. + +--- + [![@nuxt/image](./docs/public/cover.jpg "Nuxt Image")](https://image.nuxtjs.org) [![npm version][npm-version-src]][npm-version-href] @@ -8,21 +14,18 @@ - [📖  Read Documentation](https://image.nuxtjs.org) - [▶️  Play online](https://githubbox.com/nuxt/image/tree/main/example) - ### Contributing 1. Clone this repository 2. Install dependencies using `yarn install` 3. Start development server using `yarn dev` - ## 📑 License Copyright (c) Nuxt Team - - + [npm-version-src]: https://flat.badgen.net/npm/v/@nuxt/image [npm-version-href]: https://npmjs.com/package/@nuxt/image [npm-downloads-src]: https://flat.badgen.net/npm/dm/@nuxt/image From 6704ef149d724184b145a48a8d17a43331933516 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:32:43 +0000 Subject: [PATCH 08/17] fix: readjusted node version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0937b4295..54683aecd 100755 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "ipx": "^0.9.9" }, "engines": { - "node": ">=14.18.0" + "node": ">=14.16.0" }, "publishConfig": { "access": "public" From 520a945469906affc659c1bcfa0adb379e2f0b20 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:39:53 +0000 Subject: [PATCH 09/17] fix: added prepare script for local install --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 54683aecd..bd0df3018 100755 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "vetur" ], "scripts": { + "prepare": "npm run build", "build": "unbuild", "dev": "yarn nuxt playground", "docs:build": "cd docs && nuxt generate", From 2a1b4f7a87f92b86efc432a173faf0d7965017f8 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:47:34 +0000 Subject: [PATCH 10/17] chore: uh oh commiting dist --- .gitignore | 1 - README.md | 6 + dist/module.cjs | 303 ++++++++++++++++++ dist/module.d.ts | 184 +++++++++++ dist/module.mjs | 290 +++++++++++++++++ dist/runtime/components/image.mixin.d.ts | 47 +++ dist/runtime/components/image.mixin.js | 59 ++++ dist/runtime/components/nuxt-img.vue | 92 ++++++ dist/runtime/components/nuxt-img.vue.d.ts | 16 + dist/runtime/components/nuxt-picture.vue | 105 ++++++ dist/runtime/components/nuxt-picture.vue.d.ts | 16 + dist/runtime/image.d.ts | 2 + dist/runtime/image.js | 182 +++++++++++ dist/runtime/index.d.ts | 2 + dist/runtime/index.js | 2 + dist/runtime/ipx.d.ts | 3 + dist/runtime/ipx.js | 3 + dist/runtime/plugin.d.ts | 1 + dist/runtime/plugin.js | 31 ++ dist/runtime/providers/cloudflare.d.ts | 2 + dist/runtime/providers/cloudflare.js | 41 +++ dist/runtime/providers/cloudimage.d.ts | 2 + dist/runtime/providers/cloudimage.js | 34 ++ dist/runtime/providers/cloudinary.d.ts | 2 + dist/runtime/providers/cloudinary.js | 96 ++++++ dist/runtime/providers/contentful.d.ts | 3 + dist/runtime/providers/contentful.js | 36 +++ dist/runtime/providers/fastly.d.ts | 2 + dist/runtime/providers/fastly.js | 21 ++ dist/runtime/providers/glide.d.ts | 2 + dist/runtime/providers/glide.js | 49 +++ dist/runtime/providers/gumlet.d.ts | 3 + dist/runtime/providers/gumlet.js | 75 +++++ dist/runtime/providers/imageengine.d.ts | 3 + dist/runtime/providers/imageengine.js | 45 +++ dist/runtime/providers/imagekit.d.ts | 2 + dist/runtime/providers/imagekit.js | 172 ++++++++++ dist/runtime/providers/imgix.d.ts | 3 + dist/runtime/providers/imgix.js | 168 ++++++++++ dist/runtime/providers/ipx.d.ts | 4 + dist/runtime/providers/ipx.js | 31 ++ dist/runtime/providers/layer0.d.ts | 2 + dist/runtime/providers/layer0.js | 20 ++ dist/runtime/providers/netlify.d.ts | 3 + dist/runtime/providers/netlify.js | 40 +++ dist/runtime/providers/prismic.d.ts | 2 + dist/runtime/providers/prismic.js | 10 + dist/runtime/providers/sanity.d.ts | 2 + dist/runtime/providers/sanity.js | 87 +++++ dist/runtime/providers/static.d.ts | 3 + dist/runtime/providers/static.js | 6 + dist/runtime/providers/storyblok.d.ts | 2 + dist/runtime/providers/storyblok.js | 28 ++ dist/runtime/providers/strapi.d.ts | 3 + dist/runtime/providers/strapi.js | 13 + dist/runtime/providers/twicpics.d.ts | 2 + dist/runtime/providers/twicpics.js | 64 ++++ dist/runtime/providers/unsplash.d.ts | 2 + dist/runtime/providers/unsplash.js | 9 + dist/runtime/providers/vercel.d.ts | 3 + dist/runtime/providers/vercel.js | 28 ++ dist/runtime/utils/index.d.ts | 17 + dist/runtime/utils/index.js | 72 +++++ dist/runtime/utils/meta.d.ts | 2 + dist/runtime/utils/meta.js | 67 ++++ dist/runtime/utils/static-map.d.ts | 2 + dist/runtime/utils/static-map.js | 20 ++ 67 files changed, 2649 insertions(+), 1 deletion(-) create mode 100644 dist/module.cjs create mode 100644 dist/module.d.ts create mode 100644 dist/module.mjs create mode 100644 dist/runtime/components/image.mixin.d.ts create mode 100644 dist/runtime/components/image.mixin.js create mode 100644 dist/runtime/components/nuxt-img.vue create mode 100644 dist/runtime/components/nuxt-img.vue.d.ts create mode 100644 dist/runtime/components/nuxt-picture.vue create mode 100644 dist/runtime/components/nuxt-picture.vue.d.ts create mode 100644 dist/runtime/image.d.ts create mode 100644 dist/runtime/image.js create mode 100644 dist/runtime/index.d.ts create mode 100644 dist/runtime/index.js create mode 100644 dist/runtime/ipx.d.ts create mode 100644 dist/runtime/ipx.js create mode 100644 dist/runtime/plugin.d.ts create mode 100644 dist/runtime/plugin.js create mode 100644 dist/runtime/providers/cloudflare.d.ts create mode 100644 dist/runtime/providers/cloudflare.js create mode 100644 dist/runtime/providers/cloudimage.d.ts create mode 100644 dist/runtime/providers/cloudimage.js create mode 100644 dist/runtime/providers/cloudinary.d.ts create mode 100644 dist/runtime/providers/cloudinary.js create mode 100644 dist/runtime/providers/contentful.d.ts create mode 100644 dist/runtime/providers/contentful.js create mode 100644 dist/runtime/providers/fastly.d.ts create mode 100644 dist/runtime/providers/fastly.js create mode 100644 dist/runtime/providers/glide.d.ts create mode 100644 dist/runtime/providers/glide.js create mode 100644 dist/runtime/providers/gumlet.d.ts create mode 100644 dist/runtime/providers/gumlet.js create mode 100644 dist/runtime/providers/imageengine.d.ts create mode 100644 dist/runtime/providers/imageengine.js create mode 100644 dist/runtime/providers/imagekit.d.ts create mode 100644 dist/runtime/providers/imagekit.js create mode 100644 dist/runtime/providers/imgix.d.ts create mode 100644 dist/runtime/providers/imgix.js create mode 100644 dist/runtime/providers/ipx.d.ts create mode 100644 dist/runtime/providers/ipx.js create mode 100644 dist/runtime/providers/layer0.d.ts create mode 100644 dist/runtime/providers/layer0.js create mode 100644 dist/runtime/providers/netlify.d.ts create mode 100644 dist/runtime/providers/netlify.js create mode 100644 dist/runtime/providers/prismic.d.ts create mode 100644 dist/runtime/providers/prismic.js create mode 100644 dist/runtime/providers/sanity.d.ts create mode 100644 dist/runtime/providers/sanity.js create mode 100644 dist/runtime/providers/static.d.ts create mode 100644 dist/runtime/providers/static.js create mode 100644 dist/runtime/providers/storyblok.d.ts create mode 100644 dist/runtime/providers/storyblok.js create mode 100644 dist/runtime/providers/strapi.d.ts create mode 100644 dist/runtime/providers/strapi.js create mode 100644 dist/runtime/providers/twicpics.d.ts create mode 100644 dist/runtime/providers/twicpics.js create mode 100644 dist/runtime/providers/unsplash.d.ts create mode 100644 dist/runtime/providers/unsplash.js create mode 100644 dist/runtime/providers/vercel.d.ts create mode 100644 dist/runtime/providers/vercel.js create mode 100644 dist/runtime/utils/index.d.ts create mode 100644 dist/runtime/utils/index.js create mode 100644 dist/runtime/utils/meta.d.ts create mode 100644 dist/runtime/utils/meta.js create mode 100644 dist/runtime/utils/static-map.d.ts create mode 100644 dist/runtime/utils/static-map.js diff --git a/.gitignore b/.gitignore index da8a822b8..3934dfb3a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ node_modules .nuxt *.log cache/ -dist/ .DS_Store coverage sw.* diff --git a/README.md b/README.md index 2897499b0..56f139215 100755 --- a/README.md +++ b/README.md @@ -2,6 +2,12 @@ This is a fork, to fix the fingerprinting of static files. This package should in fact use the contents of the file to create the `[hash]` part of static filename. +I couldn't work out the best way to report back this change to the main module as they are preparing for a new release, so it exists here, with the `dist` folder commited, for you to: + +## Install + +`yarn add jthawme/nuxt-image-fork` + --- [![@nuxt/image](./docs/public/cover.jpg "Nuxt Image")](https://image.nuxtjs.org) diff --git a/dist/module.cjs b/dist/module.cjs new file mode 100644 index 000000000..05774a1f0 --- /dev/null +++ b/dist/module.cjs @@ -0,0 +1,303 @@ +'use strict'; + +const upath = require('upath'); +const defu = require('defu'); +const ufo = require('ufo'); +const LruCache = require('lru-cache'); +const fs = require('fs'); +const util = require('util'); +const stream = require('stream'); +const path = require('path'); +const fsExtra = require('fs-extra'); +const nodeFetchNative = require('node-fetch-native'); +const hasha$1 = require('hasha'); +const pLimit = require('p-limit'); +const consola = require('consola'); +const hasha = require('hasha/index.js'); +const rc9 = require('rc9'); +const semver = require('semver'); + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; } + +const defu__default = /*#__PURE__*/_interopDefaultLegacy(defu); +const LruCache__default = /*#__PURE__*/_interopDefaultLegacy(LruCache); +const stream__default = /*#__PURE__*/_interopDefaultLegacy(stream); +const path__default = /*#__PURE__*/_interopDefaultLegacy(path); +const hasha__default$1 = /*#__PURE__*/_interopDefaultLegacy(hasha$1); +const pLimit__default = /*#__PURE__*/_interopDefaultLegacy(pLimit); +const consola__default = /*#__PURE__*/_interopDefaultLegacy(consola); +const hasha__default = /*#__PURE__*/_interopDefaultLegacy(hasha); + +const name = "@jthawme/nuxt-image"; +const version = "0.8.4"; + +const logger = consola__default.withScope("@nuxt/image"); +const pkg = { name, version }; +function hash(value, length = 6) { + return hasha__default(value).substr(0, length); +} +function pick(obj, keys) { + const newobj = {}; + for (const key of keys) { + newobj[key] = obj[key]; + } + return newobj; +} +function guessExt(input = "") { + const ext = input.split(".").pop()?.split("?")[0]; + if (ext && /^[\w0-9]+$/.test(ext)) { + return "." + ext; + } + return ""; +} + +function getHash(input, url) { + const staticFile = path__default.join(process.cwd(), "static", input); + if (fs.existsSync(staticFile)) { + return hasha__default$1.fromFileSync(staticFile); + } + return hash(url); +} +function setupStaticGeneration(nuxt, options) { + const staticImages = {}; + nuxt.hook("vue-renderer:ssr:prepareContext", (renderContext) => { + renderContext.image = renderContext.image || {}; + renderContext.image.mapToStatic = function({ url, format }, input) { + if (!staticImages[url]) { + const { pathname } = ufo.parseURL(input); + const params = { + name: upath.trimExt(upath.basename(pathname)), + ext: format && `.${format}` || guessExt(input), + hash: getHash(input, url), + publicPath: nuxt.options.app.cdnURL ? "/" : ufo.withoutTrailingSlash(nuxt.options.build.publicPath) + }; + staticImages[url] = options.staticFilename.replace(/\[(\w+)]/g, (match, key) => params[key] || match); + } + return ufo.joinURL(nuxt.options.app.cdnURL || nuxt.options.app.basePath, staticImages[url]); + }; + }); + nuxt.hook("generate:done", async () => { + const limit = pLimit__default(8); + const downloads = Object.entries(staticImages).map(([url, name]) => { + if (!ufo.hasProtocol(url)) { + url = ufo.joinURL(options.internalUrl, url); + } + return limit(() => downloadImage({ + url, + name, + outDir: nuxt.options.generate.dir + })); + }); + await Promise.all(downloads); + }); +} +const pipeline = util.promisify(stream__default.pipeline); +async function downloadImage({ url, name, outDir }) { + try { + const response = await nodeFetchNative.fetch(url); + if (!response.ok) { + throw new Error(`Unexpected response ${response.statusText}`); + } + const dstFile = upath.join(outDir, name); + await fsExtra.mkdirp(upath.dirname(dstFile)); + await pipeline(response.body, fs.createWriteStream(dstFile)); + logger.success("Generated static image " + upath.relative(process.cwd(), dstFile)); + } catch (error) { + logger.error(error?.message); + } +} + +const ipxSetup = async (_providerOptions, moduleOptions, nuxt) => { + const isStatic = nuxt.options.target === "static"; + const runtimeDir = upath.resolve(__dirname, "runtime"); + const ipxOptions = { + dir: upath.resolve(nuxt.options.rootDir, moduleOptions.dir), + domains: moduleOptions.domains, + sharp: moduleOptions.sharp, + alias: moduleOptions.alias + }; + const hasUserProvidedIPX = !!nuxt.options.serverMiddleware.find((mw) => mw.path && mw.path.startsWith("/_ipx")); + if (!hasUserProvidedIPX) { + const { createIPX, createIPXMiddleware } = await import('ipx').catch((err) => { + console.error("[@nuxt/image] `ipx` is an optional dependency for local image optimization and is not properly installed. Please try `npm install` or `yarn install` again."); + throw new Error(err); + }); + const ipx = createIPX(ipxOptions); + nuxt.options.serverMiddleware.push({ + path: "/_ipx", + handle: createIPXMiddleware(ipx) + }); + } + const installedInModules = nuxt.options.modules.some((mod) => typeof mod === "string" && mod.includes("@nuxt/image")); + if (!isStatic && !hasUserProvidedIPX && !installedInModules && semver.lt(nuxt.constructor.version, "2.16.0")) { + console.warn("[@nuxt/image] If you would like to use the `ipx` provider at runtime.\nMake sure to follow the instructions at https://image.nuxtjs.org/providers/ipx ."); + } + if (nuxt.options.dev || hasUserProvidedIPX) { + return; + } + nuxt.hook("build:done", async () => { + const handler = await fsExtra.readFile(upath.resolve(runtimeDir, "ipx.js"), "utf-8"); + const distDir = upath.resolve(nuxt.options.buildDir, "dist"); + const apiDir = upath.resolve(distDir, "api"); + const apiFile = upath.resolve(apiDir, "ipx.js"); + const relativeApiFile = "~~/" + upath.relative(nuxt.options.rootDir, apiFile); + await fsExtra.mkdirp(apiDir); + await fsExtra.writeFile(apiFile, handler.replace(/.__IPX_OPTIONS__./, JSON.stringify(ipxOptions))); + rc9.update({ serverMiddleware: [{ path: "/_ipx", handler: relativeApiFile }] }, { dir: distDir, name: "nuxtrc" }); + }); +}; + +const BuiltInProviders = [ + "cloudflare", + "cloudinary", + "contentful", + "cloudimage", + "fastly", + "glide", + "imagekit", + "gumlet", + "imgix", + "ipx", + "netlify", + "layer0", + "prismic", + "sanity", + "static", + "twicpics", + "strapi", + "storyblok", + "unsplash", + "vercel", + "imageengine" +]; +const providerSetup = { + ipx: ipxSetup, + static: ipxSetup, + async vercel(_providerOptions, moduleOptions, nuxt) { + const imagesConfig = upath.resolve(nuxt.options.rootDir, ".vercel_build_output/config/images.json"); + await fsExtra.mkdirp(upath.dirname(imagesConfig)); + await fsExtra.writeJson(imagesConfig, { + domains: moduleOptions.domains, + sizes: Array.from(new Set(Object.values(moduleOptions.screens || {}))) + }); + } +}; +function resolveProviders(nuxt, options) { + const providers = []; + for (const key in options) { + if (BuiltInProviders.includes(key)) { + providers.push(resolveProvider(nuxt, key, { provider: key, options: options[key] })); + } + } + for (const key in options.providers) { + providers.push(resolveProvider(nuxt, key, options.providers[key])); + } + return providers; +} +function resolveProvider(nuxt, key, input) { + if (typeof input === "string") { + input = { name: input }; + } + if (!input.name) { + input.name = key; + } + if (!input.provider) { + input.provider = input.name; + } + input.provider = BuiltInProviders.includes(input.provider) ? require.resolve("./runtime/providers/" + input.provider) : nuxt.resolver.resolvePath(input.provider); + const setup = input.setup || providerSetup[input.name]; + return { + ...input, + setup, + runtime: upath.normalize(input.provider), + importName: `${key}Runtime$${hash(input.provider, 4)}`, + runtimeOptions: input.options + }; +} +function detectProvider(userInput, isStatic = false) { + if (process.env.NUXT_IMAGE_PROVIDER) { + return process.env.NUXT_IMAGE_PROVIDER; + } + if (userInput && userInput !== "auto") { + return userInput; + } + if (process.env.VERCEL || process.env.VERCEL_ENV || process.env.NOW_BUILDER) { + return "vercel"; + } + return isStatic ? "static" : "ipx"; +} + +const imageModule = async function imageModule2(moduleOptions) { + const { nuxt, addPlugin } = this; + const defaults = { + staticFilename: "[publicPath]/image/[hash][ext]", + provider: "auto", + presets: {}, + dir: upath.resolve(nuxt.options.srcDir, nuxt.options.dir.static), + domains: [], + sharp: {}, + screens: { + xs: 320, + sm: 640, + md: 768, + lg: 1024, + xl: 1280, + xxl: 1536, + "2xl": 1536 + }, + internalUrl: "", + providers: {}, + static: {}, + alias: {} + }; + const options = defu__default(moduleOptions, nuxt.options.image, defaults); + options.domains = options.domains.map((d) => { + if (!d.startsWith("http")) { + d = "http://" + d; + } + return new URL(d).hostname; + }).filter(Boolean); + options.alias = Object.fromEntries(Object.entries(options.alias).map((e) => [ufo.withLeadingSlash(e[0]), e[1]])); + options.provider = detectProvider(options.provider, nuxt.options.target === "static"); + options[options.provider] = options[options.provider] || {}; + const imageOptions = pick(options, [ + "screens", + "presets", + "provider", + "domains", + "alias" + ]); + const providers = resolveProviders(nuxt, options); + for (const p of providers) { + if (typeof p.setup === "function") { + await p.setup(p, options, nuxt); + } + } + const runtimeDir = upath.resolve(__dirname, "runtime"); + nuxt.options.alias["~image"] = runtimeDir; + nuxt.options.build.transpile.push(runtimeDir, "@nuxt/image", "allowlist", "defu", "ufo"); + addPlugin({ + fileName: "image.js", + src: upath.resolve(runtimeDir, "plugin.js"), + options: { + imageOptions, + providers + } + }); + nuxt.options.build.loaders = defu__default({ + vue: { transformAssetUrls: { "nuxt-img": "src", "nuxt-picture": "src", NuxtPicture: "src", NuxtImg: "src" } } + }, nuxt.options.build.loaders || {}); + nuxt.hook("generate:before", () => { + setupStaticGeneration(nuxt, options); + }); + const cache = new LruCache__default({ max: 1e3 }); + nuxt.hook("vue-renderer:context", (ssrContext) => { + ssrContext.cache = cache; + }); + nuxt.hook("listen", (_, listener) => { + options.internalUrl = `http://localhost:${listener.port}`; + }); +}; +imageModule.meta = pkg; + +module.exports = imageModule; diff --git a/dist/module.d.ts b/dist/module.d.ts new file mode 100644 index 000000000..84fc531a2 --- /dev/null +++ b/dist/module.d.ts @@ -0,0 +1,184 @@ +import { Module } from '@nuxt/types'; +import { IPXOptions } from 'ipx'; + +interface ImageModifiers { + width: number; + height: number; + fit: string; + format: string; + [key: string]: any; +} +interface ImageOptions { + provider?: string; + preset?: string; + modifiers?: Partial; + [key: string]: any; +} +interface ImageSizesOptions extends ImageOptions { + sizes: Record | string; +} +declare type ProviderGetImage = (src: string, options: ImageOptions, ctx: ImageCTX) => ResolvedImage; +interface ImageProvider { + defaults?: any; + getImage: ProviderGetImage; + validateDomains?: Boolean; + supportsAlias?: Boolean; +} +interface CreateImageOptions { + providers: { + [name: string]: { + defaults: any; + provider: ImageProvider; + }; + }; + presets: { + [name: string]: ImageOptions; + }; + provider: string; + screens: Record; + alias: Record; + domains: string[]; +} +interface ImageInfo { + width: number; + height: number; + placeholder?: string; +} +interface ResolvedImage { + url: string; + format?: string; + isStatic?: boolean; + getMeta?: () => Promise; +} +interface ImageSizes { + srcset: string; + sizes: string; + src: string; +} +interface Img { + (source: string, modifiers?: ImageOptions['modifiers'], options?: ImageOptions): ResolvedImage['url']; + options: CreateImageOptions; + getImage: (source: string, options?: ImageOptions) => ResolvedImage; + getSizes: (source: string, options?: ImageOptions, sizes?: string[]) => ImageSizes; + getMeta: (source: string, options?: ImageOptions) => Promise; +} +declare type $Img = Img & { + [preset: string]: $Img; +}; +interface ImageCTX { + options: CreateImageOptions; + nuxtContext: { + ssrContext: any; + cache?: any; + isDev: boolean; + isStatic: boolean; + nuxtState?: any; + base?: string; + }; + $img?: $Img; +} +interface ImageSize { + width: number; + media: string; + breakpoint: number; + format: string; + url: string; +} +interface RuntimePlaceholder extends ImageInfo { + url: string; +} +declare type OperationFormatter = (key: string, value: string) => string; +declare type OperationMapper = { + [key: string]: string | false; +} | ((key: string) => string); +interface OperationGeneratorConfig { + keyMap?: OperationMapper; + formatter?: OperationFormatter; + joinWith?: string; + valueMap?: { + [key: string]: OperationMapper; + }; +} +declare type MapToStatic = (image: ResolvedImage, input: string) => string; + +declare type ProviderSetup = (providerOptions: ImageModuleProvider, moduleOptions: ModuleOptions, nuxt: any) => void | Promise; +interface InputProvider { + name?: string; + provider?: string; + options?: T; + setup?: ProviderSetup; +} +interface CloudinaryModifiers extends ImageModifiers { + format: string; + quality: string; + background: string; + rotate: 'auto_right' | 'auto_left' | 'ignore' | 'vflip' | 'hflip' | number; + roundCorner: string; + gravity: string; + effect: string; + color: string; + flags: string; + dpr: string; + opacity: number; + overlay: string; + underlay: string; + transformation: string; + zoom: number; + colorSpace: string; + customFunc: string; + density: number; +} +interface CloudinaryOptions { + baseURL: string; + modifiers: Partial; + [key: string]: any; +} +interface ImageProviders { + cloudflare?: any; + cloudinary?: Partial; + contentful?: any; + cloudimage?: any; + fastly?: any; + glide?: any; + gumlet?: any; + imagekit?: any; + imgix?: any; + layer0?: any; + prismic?: any; + twicpics?: any; + storyblok?: any; + strapi?: any; + imageengine?: any; + ipx?: Partial; + static?: Partial; +} +interface ModuleOptions extends ImageProviders { + staticFilename: string; + provider: CreateImageOptions['provider']; + presets: { + [name: string]: ImageOptions; + }; + dir: string; + domains: string[]; + sharp: any; + alias: Record; + screens: CreateImageOptions['screens']; + internalUrl: string; + providers: { + [name: string]: InputProvider | any; + } & ImageProviders; + [key: string]: any; +} +interface ImageModuleProvider { + name: string; + importName: string; + options: any; + provider: string; + runtime: string; + runtimeOptions: any; + setup: ProviderSetup; +} + +declare const imageModule: Module; + +export { $Img, CloudinaryModifiers, CloudinaryOptions, CreateImageOptions, ImageCTX, ImageInfo, ImageModifiers, ImageModuleProvider, ImageOptions, ImageProvider, ImageProviders, ImageSize, ImageSizes, ImageSizesOptions, Img, InputProvider, MapToStatic, ModuleOptions, OperationFormatter, OperationGeneratorConfig, OperationMapper, ProviderGetImage, ProviderSetup, ResolvedImage, RuntimePlaceholder, imageModule as default }; diff --git a/dist/module.mjs b/dist/module.mjs new file mode 100644 index 000000000..a76ec845e --- /dev/null +++ b/dist/module.mjs @@ -0,0 +1,290 @@ +import { trimExt, basename, join, dirname, relative, resolve, normalize } from 'upath'; +import defu from 'defu'; +import { parseURL, withoutTrailingSlash, joinURL, hasProtocol, withLeadingSlash } from 'ufo'; +import LruCache from 'lru-cache'; +import { createWriteStream, existsSync } from 'fs'; +import { promisify } from 'util'; +import stream from 'stream'; +import path from 'path'; +import { mkdirp, readFile, writeFile, writeJson } from 'fs-extra'; +import { fetch } from 'node-fetch-native'; +import hasha$1 from 'hasha'; +import pLimit from 'p-limit'; +import consola from 'consola'; +import hasha from 'hasha/index.js'; +import { update } from 'rc9'; +import { lt } from 'semver'; + +const name = "@jthawme/nuxt-image"; +const version = "0.8.4"; + +const logger = consola.withScope("@nuxt/image"); +const pkg = { name, version }; +function hash(value, length = 6) { + return hasha(value).substr(0, length); +} +function pick(obj, keys) { + const newobj = {}; + for (const key of keys) { + newobj[key] = obj[key]; + } + return newobj; +} +function guessExt(input = "") { + const ext = input.split(".").pop()?.split("?")[0]; + if (ext && /^[\w0-9]+$/.test(ext)) { + return "." + ext; + } + return ""; +} + +function getHash(input, url) { + const staticFile = path.join(process.cwd(), "static", input); + if (existsSync(staticFile)) { + return hasha$1.fromFileSync(staticFile); + } + return hash(url); +} +function setupStaticGeneration(nuxt, options) { + const staticImages = {}; + nuxt.hook("vue-renderer:ssr:prepareContext", (renderContext) => { + renderContext.image = renderContext.image || {}; + renderContext.image.mapToStatic = function({ url, format }, input) { + if (!staticImages[url]) { + const { pathname } = parseURL(input); + const params = { + name: trimExt(basename(pathname)), + ext: format && `.${format}` || guessExt(input), + hash: getHash(input, url), + publicPath: nuxt.options.app.cdnURL ? "/" : withoutTrailingSlash(nuxt.options.build.publicPath) + }; + staticImages[url] = options.staticFilename.replace(/\[(\w+)]/g, (match, key) => params[key] || match); + } + return joinURL(nuxt.options.app.cdnURL || nuxt.options.app.basePath, staticImages[url]); + }; + }); + nuxt.hook("generate:done", async () => { + const limit = pLimit(8); + const downloads = Object.entries(staticImages).map(([url, name]) => { + if (!hasProtocol(url)) { + url = joinURL(options.internalUrl, url); + } + return limit(() => downloadImage({ + url, + name, + outDir: nuxt.options.generate.dir + })); + }); + await Promise.all(downloads); + }); +} +const pipeline = promisify(stream.pipeline); +async function downloadImage({ url, name, outDir }) { + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Unexpected response ${response.statusText}`); + } + const dstFile = join(outDir, name); + await mkdirp(dirname(dstFile)); + await pipeline(response.body, createWriteStream(dstFile)); + logger.success("Generated static image " + relative(process.cwd(), dstFile)); + } catch (error) { + logger.error(error?.message); + } +} + +const ipxSetup = async (_providerOptions, moduleOptions, nuxt) => { + const isStatic = nuxt.options.target === "static"; + const runtimeDir = resolve(__dirname, "runtime"); + const ipxOptions = { + dir: resolve(nuxt.options.rootDir, moduleOptions.dir), + domains: moduleOptions.domains, + sharp: moduleOptions.sharp, + alias: moduleOptions.alias + }; + const hasUserProvidedIPX = !!nuxt.options.serverMiddleware.find((mw) => mw.path && mw.path.startsWith("/_ipx")); + if (!hasUserProvidedIPX) { + const { createIPX, createIPXMiddleware } = await import('ipx').catch((err) => { + console.error("[@nuxt/image] `ipx` is an optional dependency for local image optimization and is not properly installed. Please try `npm install` or `yarn install` again."); + throw new Error(err); + }); + const ipx = createIPX(ipxOptions); + nuxt.options.serverMiddleware.push({ + path: "/_ipx", + handle: createIPXMiddleware(ipx) + }); + } + const installedInModules = nuxt.options.modules.some((mod) => typeof mod === "string" && mod.includes("@nuxt/image")); + if (!isStatic && !hasUserProvidedIPX && !installedInModules && lt(nuxt.constructor.version, "2.16.0")) { + console.warn("[@nuxt/image] If you would like to use the `ipx` provider at runtime.\nMake sure to follow the instructions at https://image.nuxtjs.org/providers/ipx ."); + } + if (nuxt.options.dev || hasUserProvidedIPX) { + return; + } + nuxt.hook("build:done", async () => { + const handler = await readFile(resolve(runtimeDir, "ipx.js"), "utf-8"); + const distDir = resolve(nuxt.options.buildDir, "dist"); + const apiDir = resolve(distDir, "api"); + const apiFile = resolve(apiDir, "ipx.js"); + const relativeApiFile = "~~/" + relative(nuxt.options.rootDir, apiFile); + await mkdirp(apiDir); + await writeFile(apiFile, handler.replace(/.__IPX_OPTIONS__./, JSON.stringify(ipxOptions))); + update({ serverMiddleware: [{ path: "/_ipx", handler: relativeApiFile }] }, { dir: distDir, name: "nuxtrc" }); + }); +}; + +const BuiltInProviders = [ + "cloudflare", + "cloudinary", + "contentful", + "cloudimage", + "fastly", + "glide", + "imagekit", + "gumlet", + "imgix", + "ipx", + "netlify", + "layer0", + "prismic", + "sanity", + "static", + "twicpics", + "strapi", + "storyblok", + "unsplash", + "vercel", + "imageengine" +]; +const providerSetup = { + ipx: ipxSetup, + static: ipxSetup, + async vercel(_providerOptions, moduleOptions, nuxt) { + const imagesConfig = resolve(nuxt.options.rootDir, ".vercel_build_output/config/images.json"); + await mkdirp(dirname(imagesConfig)); + await writeJson(imagesConfig, { + domains: moduleOptions.domains, + sizes: Array.from(new Set(Object.values(moduleOptions.screens || {}))) + }); + } +}; +function resolveProviders(nuxt, options) { + const providers = []; + for (const key in options) { + if (BuiltInProviders.includes(key)) { + providers.push(resolveProvider(nuxt, key, { provider: key, options: options[key] })); + } + } + for (const key in options.providers) { + providers.push(resolveProvider(nuxt, key, options.providers[key])); + } + return providers; +} +function resolveProvider(nuxt, key, input) { + if (typeof input === "string") { + input = { name: input }; + } + if (!input.name) { + input.name = key; + } + if (!input.provider) { + input.provider = input.name; + } + input.provider = BuiltInProviders.includes(input.provider) ? require.resolve("./runtime/providers/" + input.provider) : nuxt.resolver.resolvePath(input.provider); + const setup = input.setup || providerSetup[input.name]; + return { + ...input, + setup, + runtime: normalize(input.provider), + importName: `${key}Runtime$${hash(input.provider, 4)}`, + runtimeOptions: input.options + }; +} +function detectProvider(userInput, isStatic = false) { + if (process.env.NUXT_IMAGE_PROVIDER) { + return process.env.NUXT_IMAGE_PROVIDER; + } + if (userInput && userInput !== "auto") { + return userInput; + } + if (process.env.VERCEL || process.env.VERCEL_ENV || process.env.NOW_BUILDER) { + return "vercel"; + } + return isStatic ? "static" : "ipx"; +} + +const imageModule = async function imageModule2(moduleOptions) { + const { nuxt, addPlugin } = this; + const defaults = { + staticFilename: "[publicPath]/image/[hash][ext]", + provider: "auto", + presets: {}, + dir: resolve(nuxt.options.srcDir, nuxt.options.dir.static), + domains: [], + sharp: {}, + screens: { + xs: 320, + sm: 640, + md: 768, + lg: 1024, + xl: 1280, + xxl: 1536, + "2xl": 1536 + }, + internalUrl: "", + providers: {}, + static: {}, + alias: {} + }; + const options = defu(moduleOptions, nuxt.options.image, defaults); + options.domains = options.domains.map((d) => { + if (!d.startsWith("http")) { + d = "http://" + d; + } + return new URL(d).hostname; + }).filter(Boolean); + options.alias = Object.fromEntries(Object.entries(options.alias).map((e) => [withLeadingSlash(e[0]), e[1]])); + options.provider = detectProvider(options.provider, nuxt.options.target === "static"); + options[options.provider] = options[options.provider] || {}; + const imageOptions = pick(options, [ + "screens", + "presets", + "provider", + "domains", + "alias" + ]); + const providers = resolveProviders(nuxt, options); + for (const p of providers) { + if (typeof p.setup === "function") { + await p.setup(p, options, nuxt); + } + } + const runtimeDir = resolve(__dirname, "runtime"); + nuxt.options.alias["~image"] = runtimeDir; + nuxt.options.build.transpile.push(runtimeDir, "@nuxt/image", "allowlist", "defu", "ufo"); + addPlugin({ + fileName: "image.js", + src: resolve(runtimeDir, "plugin.js"), + options: { + imageOptions, + providers + } + }); + nuxt.options.build.loaders = defu({ + vue: { transformAssetUrls: { "nuxt-img": "src", "nuxt-picture": "src", NuxtPicture: "src", NuxtImg: "src" } } + }, nuxt.options.build.loaders || {}); + nuxt.hook("generate:before", () => { + setupStaticGeneration(nuxt, options); + }); + const cache = new LruCache({ max: 1e3 }); + nuxt.hook("vue-renderer:context", (ssrContext) => { + ssrContext.cache = cache; + }); + nuxt.hook("listen", (_, listener) => { + options.internalUrl = `http://localhost:${listener.port}`; + }); +}; +imageModule.meta = pkg; + +export { imageModule as default }; diff --git a/dist/runtime/components/image.mixin.d.ts b/dist/runtime/components/image.mixin.d.ts new file mode 100644 index 000000000..03d80996c --- /dev/null +++ b/dist/runtime/components/image.mixin.d.ts @@ -0,0 +1,47 @@ +export declare const imageMixin: { + nImgAttrs: { + width?: number; + height?: number; + alt?: string; + referrerpolicy?: string; + usemap?: string; + longdesc?: string; + ismap?: boolean; + crossorigin?: '' | 'anonymous' | 'use-credentials'; + loading?: string; + decoding?: 'async' | 'auto' | 'sync'; + }; + nModifiers: { + width?: number; + height?: number; + format?: string; + quality?: string | number; + background?: string; + fit?: string; + } & Record; + nOptions: { + provider?: string; + preset?: string; + }; +} & { + src: string; + format: string; + quality: string | number; + background: string; + fit: string; + modifiers: Record; + preset: string; + provider: string; + sizes: string | Record; + preload: boolean; + width: string | number; + height: string | number; + alt: string; + referrerpolicy: string; + usemap: string; + longdesc: string; + ismap: boolean; + crossorigin: boolean | "" | "anonymous" | "use-credentials"; + loading: string; + decoding: "async" | "auto" | "sync"; +} & import("vue").VueConstructor; diff --git a/dist/runtime/components/image.mixin.js b/dist/runtime/components/image.mixin.js new file mode 100644 index 000000000..1453cd629 --- /dev/null +++ b/dist/runtime/components/image.mixin.js @@ -0,0 +1,59 @@ +import { parseSize } from "../utils"; +const defineMixin = (opts) => opts; +export const imageMixin = defineMixin({ + props: { + src: { type: String, required: true }, + format: { type: String, default: void 0 }, + quality: { type: [Number, String], default: void 0 }, + background: { type: String, default: void 0 }, + fit: { type: String, default: void 0 }, + modifiers: { type: Object, default: void 0 }, + preset: { type: String, default: void 0 }, + provider: { type: String, default: void 0 }, + sizes: { type: [Object, String], default: void 0 }, + preload: { type: Boolean, default: void 0 }, + width: { type: [String, Number], default: void 0 }, + height: { type: [String, Number], default: void 0 }, + alt: { type: String, default: void 0 }, + referrerpolicy: { type: String, default: void 0 }, + usemap: { type: String, default: void 0 }, + longdesc: { type: String, default: void 0 }, + ismap: { type: Boolean, default: void 0 }, + crossorigin: { type: [Boolean, String], default: void 0, validator: (val) => ["anonymous", "use-credentials", "", true, false].includes(val) }, + loading: { type: String, default: void 0 }, + decoding: { type: String, default: void 0, validator: (val) => ["async", "auto", "sync"].includes(val) } + }, + computed: { + nImgAttrs() { + return { + width: parseSize(this.width), + height: parseSize(this.height), + alt: this.alt, + referrerpolicy: this.referrerpolicy, + usemap: this.usemap, + longdesc: this.longdesc, + ismap: this.ismap, + crossorigin: this.crossorigin === true ? "anonymous" : this.crossorigin || void 0, + loading: this.loading, + decoding: this.decoding + }; + }, + nModifiers() { + return { + ...this.modifiers, + width: parseSize(this.width), + height: parseSize(this.height), + format: this.format, + quality: this.quality, + background: this.background, + fit: this.fit + }; + }, + nOptions() { + return { + provider: this.provider, + preset: this.preset + }; + } + } +}); diff --git a/dist/runtime/components/nuxt-img.vue b/dist/runtime/components/nuxt-img.vue new file mode 100644 index 000000000..b6fc4e4dc --- /dev/null +++ b/dist/runtime/components/nuxt-img.vue @@ -0,0 +1,92 @@ + + + diff --git a/dist/runtime/components/nuxt-img.vue.d.ts b/dist/runtime/components/nuxt-img.vue.d.ts new file mode 100644 index 000000000..96acf717f --- /dev/null +++ b/dist/runtime/components/nuxt-img.vue.d.ts @@ -0,0 +1,16 @@ +import type { ImageSizes } from '../../types'; +import { imageMixin } from './image.mixin'; +declare type NAttrs = typeof imageMixin['nImgAttrs'] & { + sizes?: string; + srcset?: string; +}; +declare const _default: import("vue/types/vue").ExtendedVue; +export default _default; diff --git a/dist/runtime/components/nuxt-picture.vue b/dist/runtime/components/nuxt-picture.vue new file mode 100644 index 000000000..516bde5c0 --- /dev/null +++ b/dist/runtime/components/nuxt-picture.vue @@ -0,0 +1,105 @@ + + + diff --git a/dist/runtime/components/nuxt-picture.vue.d.ts b/dist/runtime/components/nuxt-picture.vue.d.ts new file mode 100644 index 000000000..3236333ac --- /dev/null +++ b/dist/runtime/components/nuxt-picture.vue.d.ts @@ -0,0 +1,16 @@ +declare const _default: import("vue/types/vue").ExtendedVue; +export default _default; diff --git a/dist/runtime/image.d.ts b/dist/runtime/image.d.ts new file mode 100644 index 000000000..d5b2a1227 --- /dev/null +++ b/dist/runtime/image.d.ts @@ -0,0 +1,2 @@ +import type { CreateImageOptions, $Img } from '../types/image'; +export declare function createImage(globalOptions: CreateImageOptions, nuxtContext: any): $Img; diff --git a/dist/runtime/image.js b/dist/runtime/image.js new file mode 100644 index 000000000..8397eeb2c --- /dev/null +++ b/dist/runtime/image.js @@ -0,0 +1,182 @@ +import defu from "defu"; +import { hasProtocol, parseURL, joinURL, withLeadingSlash } from "ufo"; +import { imageMeta } from "./utils/meta"; +import { parseSize } from "./utils"; +import { useStaticImageMap } from "./utils/static-map"; +export function createImage(globalOptions, nuxtContext) { + const staticImageManifest = process.client && process.static ? useStaticImageMap(nuxtContext) : {}; + const ctx = { + options: globalOptions, + nuxtContext + }; + const getImage = function(input, options = {}) { + const image = resolveImage(ctx, input, options); + if (image.isStatic) { + handleStaticImage(image, input); + } + return image; + }; + const $img = function $img2(input, modifiers = {}, options = {}) { + return getImage(input, { + ...options, + modifiers: defu(modifiers, options.modifiers || {}) + }).url; + }; + function handleStaticImage(image, input) { + if (process.static) { + if (process.client && "fetchPayload" in window.$nuxt) { + const mappedURL = staticImageManifest[image.url]; + image.url = mappedURL || input; + return image; + } + if (process.server) { + const { ssrContext } = ctx.nuxtContext; + if (ssrContext) { + const ssrState = ssrContext.nuxt || {}; + const staticImages = ssrState._img = ssrState._img || {}; + const ssrData = ssrState.data?.[0]; + if (ssrData) { + ssrData._img = staticImages; + } + const mapToStatic = ssrContext.image?.mapToStatic; + if (typeof mapToStatic === "function") { + const mappedURL = mapToStatic(image, input); + if (mappedURL) { + staticImages[image.url] = mappedURL; + image.url = mappedURL; + } + } + } + } + } else if (process.env.NODE_ENV === "production") { + image.url = input; + } + } + for (const presetName in globalOptions.presets) { + $img[presetName] = (source, modifiers, options) => $img(source, modifiers, { ...globalOptions.presets[presetName], ...options }); + } + $img.options = globalOptions; + $img.getImage = getImage; + $img.getMeta = (input, options) => getMeta(ctx, input, options); + $img.getSizes = (input, options) => getSizes(ctx, input, options); + ctx.$img = $img; + return $img; +} +async function getMeta(ctx, input, options) { + const image = resolveImage(ctx, input, { ...options }); + if (typeof image.getMeta === "function") { + return await image.getMeta(); + } else { + return await imageMeta(ctx, image.url); + } +} +function resolveImage(ctx, input, options) { + if (typeof input !== "string" || input === "") { + throw new TypeError(`input must be a string (received ${typeof input}: ${JSON.stringify(input)})`); + } + if (input.startsWith("data:")) { + return { + url: input + }; + } + const { provider, defaults } = getProvider(ctx, options.provider || ctx.options.provider); + const preset = getPreset(ctx, options.preset); + input = hasProtocol(input) ? input : withLeadingSlash(input); + if (!provider.supportsAlias) { + for (const base in ctx.options.alias) { + if (input.startsWith(base)) { + input = joinURL(ctx.options.alias[base], input.substr(base.length)); + } + } + } + if (provider.validateDomains && hasProtocol(input)) { + const inputHost = parseURL(input).host; + if (!ctx.options.domains.find((d) => d === inputHost)) { + return { + url: input + }; + } + } + const _options = defu(options, preset, defaults); + _options.modifiers = { ..._options.modifiers }; + const expectedFormat = _options.modifiers.format; + if (_options.modifiers?.width) { + _options.modifiers.width = parseSize(_options.modifiers.width); + } + if (_options.modifiers?.height) { + _options.modifiers.height = parseSize(_options.modifiers.height); + } + const image = provider.getImage(input, _options, ctx); + image.format = image.format || expectedFormat || ""; + return image; +} +function getProvider(ctx, name) { + const provider = ctx.options.providers[name]; + if (!provider) { + throw new Error("Unknown provider: " + name); + } + return provider; +} +function getPreset(ctx, name) { + if (!name) { + return {}; + } + if (!ctx.options.presets[name]) { + throw new Error("Unknown preset: " + name); + } + return ctx.options.presets[name]; +} +function getSizes(ctx, input, opts) { + const width = parseSize(opts.modifiers?.width); + const height = parseSize(opts.modifiers?.height); + const hwRatio = width && height ? height / width : 0; + const variants = []; + const sizes = {}; + if (typeof opts.sizes === "string") { + for (const entry of opts.sizes.split(/[\s,]+/).filter((e) => e)) { + const s = entry.split(":"); + if (s.length !== 2) { + continue; + } + sizes[s[0].trim()] = s[1].trim(); + } + } else { + Object.assign(sizes, opts.sizes); + } + for (const key in sizes) { + const screenMaxWidth = ctx.options.screens && ctx.options.screens[key] || parseInt(key); + let size = String(sizes[key]); + const isFluid = size.endsWith("vw"); + if (!isFluid && /^\d+$/.test(size)) { + size = size + "px"; + } + if (!isFluid && !size.endsWith("px")) { + continue; + } + let _cWidth = parseInt(size); + if (!screenMaxWidth || !_cWidth) { + continue; + } + if (isFluid) { + _cWidth = Math.round(_cWidth / 100 * screenMaxWidth); + } + const _cHeight = hwRatio ? Math.round(_cWidth * hwRatio) : height; + variants.push({ + width: _cWidth, + size, + screenMaxWidth, + media: `(max-width: ${screenMaxWidth}px)`, + src: ctx.$img(input, { ...opts.modifiers, width: _cWidth, height: _cHeight }, opts) + }); + } + variants.sort((v1, v2) => v1.screenMaxWidth - v2.screenMaxWidth); + const defaultVar = variants[variants.length - 1]; + if (defaultVar) { + defaultVar.media = ""; + } + return { + sizes: variants.map((v) => `${v.media ? v.media + " " : ""}${v.size}`).join(", "), + srcset: variants.map((v) => `${v.src} ${v.width}w`).join(", "), + src: defaultVar?.src + }; +} diff --git a/dist/runtime/index.d.ts b/dist/runtime/index.d.ts new file mode 100644 index 000000000..7f0709662 --- /dev/null +++ b/dist/runtime/index.d.ts @@ -0,0 +1,2 @@ +export * from './image'; +export * from './utils'; diff --git a/dist/runtime/index.js b/dist/runtime/index.js new file mode 100644 index 000000000..8895cfd07 --- /dev/null +++ b/dist/runtime/index.js @@ -0,0 +1,2 @@ +export * from "./image"; +export * from "./utils"; diff --git a/dist/runtime/ipx.d.ts b/dist/runtime/ipx.d.ts new file mode 100644 index 000000000..16b6ea93f --- /dev/null +++ b/dist/runtime/ipx.d.ts @@ -0,0 +1,3 @@ +/// +declare const _default: (req: import("http").IncomingMessage, res: import("http").ServerResponse) => void; +export default _default; diff --git a/dist/runtime/ipx.js b/dist/runtime/ipx.js new file mode 100644 index 000000000..5da24f0ed --- /dev/null +++ b/dist/runtime/ipx.js @@ -0,0 +1,3 @@ +import { createIPX, createIPXMiddleware } from "ipx"; +const ipx = createIPX("__IPX_OPTIONS__"); +export default createIPXMiddleware(ipx); diff --git a/dist/runtime/plugin.d.ts b/dist/runtime/plugin.d.ts new file mode 100644 index 000000000..b8c0cf786 --- /dev/null +++ b/dist/runtime/plugin.d.ts @@ -0,0 +1 @@ +export default function _default(nuxtContext: any, inject: any): void; diff --git a/dist/runtime/plugin.js b/dist/runtime/plugin.js new file mode 100644 index 000000000..4e361c6bb --- /dev/null +++ b/dist/runtime/plugin.js @@ -0,0 +1,31 @@ +import Vue from 'vue' +import { createImage} from '~image' +import NuxtImg from '~image/components/nuxt-img.vue' +import NuxtPicture from '~image/components/nuxt-picture.vue' + +<%=options.providers.map(p => `import * as ${p.importName} from '${p.runtime}'`).join('\n')%> + +const imageOptions = <%= JSON.stringify(options.imageOptions, null, 2) %> + +imageOptions.providers = { +<%=options.providers.map(p => ` ['${p.name}']: { provider: ${p.importName}, defaults: ${JSON.stringify(p.runtimeOptions)} }`).join(',\n') %> +} + + +Vue.component(NuxtImg.name, NuxtImg) +Vue.component(NuxtPicture.name, NuxtPicture) +Vue.component('NImg', NuxtImg) +Vue.component('NPicture', NuxtPicture) + +export default function (nuxtContext, inject) { + const $img = createImage(imageOptions, nuxtContext) + + if (process.static && process.server) { + nuxtContext.beforeNuxtRender(({ nuxtState }) => { + const ssrData = nuxtState.data[0] || {} + ssrData._img = nuxtState._img || {} + }) + } + + inject('img', $img) +} diff --git a/dist/runtime/providers/cloudflare.d.ts b/dist/runtime/providers/cloudflare.d.ts new file mode 100644 index 000000000..12489337f --- /dev/null +++ b/dist/runtime/providers/cloudflare.d.ts @@ -0,0 +1,2 @@ +import { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/cloudflare.js b/dist/runtime/providers/cloudflare.js new file mode 100644 index 000000000..5906ef6e7 --- /dev/null +++ b/dist/runtime/providers/cloudflare.js @@ -0,0 +1,41 @@ +import { joinURL, encodeQueryItem } from "ufo"; +import { createOperationsGenerator } from "~image"; +const operationsGenerator = createOperationsGenerator({ + keyMap: { + width: "w", + height: "h", + dpr: "dpr", + fit: "fit", + gravity: "g", + quality: "q", + format: "f", + sharpen: "sharpen" + }, + valueMap: { + fit: { + cover: "cover", + contain: "contain", + fill: "scale-down", + outside: "crop", + inside: "pad" + }, + gravity: { + auto: "auto", + side: "side" + } + }, + joinWith: ",", + formatter: (key, val) => encodeQueryItem(key, val) +}); +const defaultModifiers = {}; +export const getImage = (src, { + modifiers = {}, + baseURL = "/" +} = {}) => { + const mergeModifiers = { ...defaultModifiers, ...modifiers }; + const operations = operationsGenerator(mergeModifiers); + const url = operations ? joinURL(baseURL, "cdn-cgi/image", operations, src) : joinURL(baseURL, src); + return { + url + }; +}; diff --git a/dist/runtime/providers/cloudimage.d.ts b/dist/runtime/providers/cloudimage.d.ts new file mode 100644 index 000000000..d07bf64e2 --- /dev/null +++ b/dist/runtime/providers/cloudimage.d.ts @@ -0,0 +1,2 @@ +import type { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/cloudimage.js b/dist/runtime/providers/cloudimage.js new file mode 100644 index 000000000..4c0b4ebb1 --- /dev/null +++ b/dist/runtime/providers/cloudimage.js @@ -0,0 +1,34 @@ +import { joinURL } from "ufo"; +import { createOperationsGenerator } from "~image"; +const operationsGenerator = createOperationsGenerator({ + keyMap: { + fit: "func", + quality: "q", + format: "force_format" + }, + valueMap: { + fit: { + cover: "crop", + contain: "fit", + fill: "cover", + inside: "bound", + outside: "boundmin" + } + }, + joinWith: "&", + formatter: (key, value) => `${key}=${value}` +}); +export const getImage = (src, { + modifiers = {}, + baseURL = "", + token = "demo", + cdnURL = "" +} = {}) => { + const operations = operationsGenerator(modifiers); + if (!cdnURL) { + cdnURL = `https://${token}.cloudimg.io/v7`; + } + return { + url: joinURL(cdnURL, baseURL, src) + (operations ? "?" + operations : "") + }; +}; diff --git a/dist/runtime/providers/cloudinary.d.ts b/dist/runtime/providers/cloudinary.d.ts new file mode 100644 index 000000000..d07bf64e2 --- /dev/null +++ b/dist/runtime/providers/cloudinary.d.ts @@ -0,0 +1,2 @@ +import type { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/cloudinary.js b/dist/runtime/providers/cloudinary.js new file mode 100644 index 000000000..81437ce45 --- /dev/null +++ b/dist/runtime/providers/cloudinary.js @@ -0,0 +1,96 @@ +import { joinURL, encodePath } from "ufo"; +import defu from "defu"; +import { createOperationsGenerator } from "~image"; +const convertHextoRGBFormat = (value) => value.startsWith("#") ? value.replace("#", "rgb_") : value; +const removePathExtension = (value) => value.replace(/\.[^/.]+$/, ""); +const operationsGenerator = createOperationsGenerator({ + keyMap: { + fit: "c", + width: "w", + height: "h", + format: "f", + quality: "q", + background: "b", + rotate: "a", + roundCorner: "r", + gravity: "g", + effect: "e", + color: "co", + flags: "fl", + dpr: "dpr", + opacity: "o", + overlay: "l", + underlay: "u", + transformation: "t", + zoom: "z", + colorSpace: "cs", + customFunc: "fn", + density: "dpi" + }, + valueMap: { + fit: { + fill: "fill", + inside: "pad", + outside: "lpad", + cover: "fit", + contain: "scale", + minCover: "mfit", + minInside: "mpad", + thumbnail: "thumb", + cropping: "crop", + coverLimit: "limit" + }, + format: { + jpeg: "jpg" + }, + background(value) { + return convertHextoRGBFormat(value); + }, + color(value) { + return convertHextoRGBFormat(value); + }, + gravity: { + auto: "auto", + subject: "auto:subject", + face: "face", + sink: "sink", + faceCenter: "face:center", + multipleFaces: "faces", + multipleFacesCenter: "faces:center", + north: "north", + northEast: "north_east", + northWest: "north_west", + west: "west", + southWest: "south_west", + south: "south", + southEast: "south_east", + east: "east", + center: "center" + } + }, + joinWith: ",", + formatter: (key, value) => `${key}_${value}` +}); +const defaultModifiers = { + format: "auto", + quality: "auto" +}; +export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { + const mergeModifiers = defu(modifiers, defaultModifiers); + const operations = operationsGenerator(mergeModifiers); + const remoteFolderMapping = baseURL.match(/\/image\/upload\/(.*)/); + if (remoteFolderMapping?.length >= 1) { + const remoteFolder = remoteFolderMapping[1]; + const baseURLWithoutRemoteFolder = baseURL.replace(remoteFolder, ""); + return { + url: joinURL(baseURLWithoutRemoteFolder, operations, remoteFolder, src) + }; + } else if (/\/image\/fetch\/?/.test(baseURL)) { + src = encodePath(src); + } else { + src = removePathExtension(src); + } + return { + url: joinURL(baseURL, operations, src) + }; +}; diff --git a/dist/runtime/providers/contentful.d.ts b/dist/runtime/providers/contentful.d.ts new file mode 100644 index 000000000..e4f818101 --- /dev/null +++ b/dist/runtime/providers/contentful.d.ts @@ -0,0 +1,3 @@ +import type { ProviderGetImage } from 'src'; +export declare const operationsGenerator: any; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/contentful.js b/dist/runtime/providers/contentful.js new file mode 100644 index 000000000..c77864b14 --- /dev/null +++ b/dist/runtime/providers/contentful.js @@ -0,0 +1,36 @@ +import { withBase, parseURL } from "ufo"; +import { createOperationsGenerator } from "~image"; +const contentfulCDN = "https://images.ctfassets.net"; +export const operationsGenerator = createOperationsGenerator({ + keyMap: { + format: "fm", + width: "w", + height: "h", + focus: "f", + radius: "r", + quality: "q", + background: "bg" + }, + valueMap: { + format: { + jpeg: "jpg" + }, + fit: { + cover: "crop", + contain: "fill", + fill: "scale", + thumbnail: "thumb" + } + }, + joinWith: "&", + formatter: (key, value) => `${key}=${value}` +}); +export const getImage = (src, { modifiers = {}, baseURL = contentfulCDN } = {}) => { + const operations = operationsGenerator(modifiers); + const { pathname } = parseURL(src); + const path = pathname + (operations ? "?" + operations : ""); + const url = withBase(path, baseURL); + return { + url + }; +}; diff --git a/dist/runtime/providers/fastly.d.ts b/dist/runtime/providers/fastly.d.ts new file mode 100644 index 000000000..d07bf64e2 --- /dev/null +++ b/dist/runtime/providers/fastly.d.ts @@ -0,0 +1,2 @@ +import type { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/fastly.js b/dist/runtime/providers/fastly.js new file mode 100644 index 000000000..5e5f27ce4 --- /dev/null +++ b/dist/runtime/providers/fastly.js @@ -0,0 +1,21 @@ +import { joinURL } from "ufo"; +import { createOperationsGenerator } from "~image"; +const operationsGenerator = createOperationsGenerator({ + valueMap: { + fit: { + fill: "crop", + inside: "crop", + outside: "crop", + cover: "bounds", + contain: "bounds" + } + }, + joinWith: "&", + formatter: (key, value) => `${key}=${value}` +}); +export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { + const operations = operationsGenerator(modifiers); + return { + url: joinURL(baseURL, src + (operations ? "?" + operations : "")) + }; +}; diff --git a/dist/runtime/providers/glide.d.ts b/dist/runtime/providers/glide.d.ts new file mode 100644 index 000000000..12489337f --- /dev/null +++ b/dist/runtime/providers/glide.d.ts @@ -0,0 +1,2 @@ +import { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/glide.js b/dist/runtime/providers/glide.js new file mode 100644 index 000000000..538a701dc --- /dev/null +++ b/dist/runtime/providers/glide.js @@ -0,0 +1,49 @@ +import { joinURL, encodeQueryItem, encodePath, withBase } from "ufo"; +import { createOperationsGenerator } from "~image"; +const operationsGenerator = createOperationsGenerator({ + keyMap: { + orientation: "or", + flip: "flip", + crop: "crop", + width: "w", + height: "h", + fit: "fit", + dpr: "dpr", + bri: "bri", + con: "con", + gam: "gam", + sharp: "sharp", + blur: "blur", + pixel: "pixel", + filt: "filt", + mark: "mark", + markw: "markw", + markh: "markh", + markx: "markx", + marky: "marky", + markpad: "markpad", + markpos: "markpos", + markalpha: "markalpha", + background: "bg", + border: "border", + quality: "q", + format: "fm" + }, + valueMap: { + fit: { + fill: "fill", + inside: "max", + outside: "stretch", + cover: "crop", + contain: "contain" + } + }, + joinWith: "&", + formatter: (key, val) => encodeQueryItem(key, val) +}); +export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { + const params = operationsGenerator(modifiers); + return { + url: withBase(joinURL(encodePath(src) + (params ? "?" + params : "")), baseURL) + }; +}; diff --git a/dist/runtime/providers/gumlet.d.ts b/dist/runtime/providers/gumlet.d.ts new file mode 100644 index 000000000..e4f818101 --- /dev/null +++ b/dist/runtime/providers/gumlet.d.ts @@ -0,0 +1,3 @@ +import type { ProviderGetImage } from 'src'; +export declare const operationsGenerator: any; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/gumlet.js b/dist/runtime/providers/gumlet.js new file mode 100644 index 000000000..e1bf6ef06 --- /dev/null +++ b/dist/runtime/providers/gumlet.js @@ -0,0 +1,75 @@ +import { joinURL } from "ufo"; +import { createOperationsGenerator } from "~image"; +export const operationsGenerator = createOperationsGenerator({ + keyMap: { + width: "w", + height: "h", + format: "format", + quality: "q", + backgroundColor: "bg", + rotate: "rot", + mask: "mask", + auto: "auto", + crop: "crop", + brightness: "bri", + contrast: "con", + exposure: "exp", + gamma: "gam", + highlight: "high", + hueShift: "hue", + invert: "invert", + saturation: "sat", + sharpen: "sharp", + padding: "pad", + paletteColorCount: "colors", + colorPaletteExtraction: "palette", + cssPrefix: "prefix", + jsonFaceData: "faces", + fillMode: "fill", + fillColor: "fill-color", + transparency: "transparency", + focalPointDebug: "fp-debug", + focalPointXPosition: "fp-x", + focalPointYPosition: "fp-y", + focalPointZoom: "fp-z", + chromaSubsampling: "chromasub", + colorQuantization: "colorquant", + colorSpace: "colorspace", + dotsPerInch: "dpi", + pdfPageNumber: "page", + pixelDensity: "dpr", + aspectRatio: "ar", + sourceRectangleRegion: "rect", + monochrome: "monochrome" + }, + valueMap: { + fit: { + fill: "scale", + inside: "max", + outside: "min", + cover: "crop", + contain: "fill", + clamp: "clamp", + clip: "clip", + facearea: "facearea", + fillMax: "fillmax" + }, + format: { + gif: "gif", + jpg: "jpg", + json: "json", + png: "png", + avif: "avif", + webp: "webp", + auto: "auto" + } + }, + joinWith: "&", + formatter: (key, value) => `${key}=${value}` +}); +export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { + const operations = operationsGenerator(modifiers); + return { + url: joinURL(baseURL, src + (operations ? "?" + operations : "")) + }; +}; diff --git a/dist/runtime/providers/imageengine.d.ts b/dist/runtime/providers/imageengine.d.ts new file mode 100644 index 000000000..e4f818101 --- /dev/null +++ b/dist/runtime/providers/imageengine.d.ts @@ -0,0 +1,3 @@ +import type { ProviderGetImage } from 'src'; +export declare const operationsGenerator: any; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/imageengine.js b/dist/runtime/providers/imageengine.js new file mode 100644 index 000000000..58dc4aa5c --- /dev/null +++ b/dist/runtime/providers/imageengine.js @@ -0,0 +1,45 @@ +import { joinURL } from "ufo"; +import { createOperationsGenerator } from "~image"; +export const operationsGenerator = createOperationsGenerator({ + keyMap: { + width: "w", + height: "h", + quality: "cmpr", + format: "f", + fit: "m", + passThrough: "pass", + sharpen: "s", + rotate: "r", + screenPercent: "pc", + crop: "cr", + inline: "in", + metadata: "meta" + }, + valueMap: { + fit: { + cover: "cropbox", + contain: "letterbox", + fill: "stretch", + inside: "box", + outside: "box" + }, + format: { + jpeg: "jpg" + }, + quality(value) { + let compression = 100 - parseInt(value, 10); + if (compression === 100) { + compression = 99; + } + return compression.toString(); + } + }, + joinWith: "/", + formatter: (key, value) => `${key}_${value}` +}); +export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { + const operations = operationsGenerator(modifiers); + return { + url: joinURL(baseURL, src + (operations ? "?imgeng=/" + operations : "")) + }; +}; diff --git a/dist/runtime/providers/imagekit.d.ts b/dist/runtime/providers/imagekit.d.ts new file mode 100644 index 000000000..d07bf64e2 --- /dev/null +++ b/dist/runtime/providers/imagekit.d.ts @@ -0,0 +1,2 @@ +import type { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/imagekit.js b/dist/runtime/providers/imagekit.js new file mode 100644 index 000000000..e10a7e67e --- /dev/null +++ b/dist/runtime/providers/imagekit.js @@ -0,0 +1,172 @@ +import { joinURL } from "ufo"; +import { createOperationsGenerator } from "~image"; +const operationsGenerator = createOperationsGenerator({ + keyMap: { + fit: "c", + width: "w", + height: "h", + format: "f", + quality: "q", + bg: "bg", + background: "bg", + crop: "c", + cropMode: "cm", + aspectRatio: "ar", + x: "x", + y: "y", + xc: "xc", + yc: "yc", + oix: "oix", + oiy: "oiy", + oixc: "oixc", + oiyc: "oiyc", + focus: "fo", + radius: "r", + border: "b", + rotate: "rt", + blur: "bl", + named: "n", + overlayX: "ox", + overlayY: "oy", + overlayFocus: "ofo", + overlayHeight: "oh", + overlayWidth: "ow", + overlayImage: "oi", + overlayImageTrim: "oit", + overlayImageAspectRatio: "oiar", + overlayImageBackground: "oibg", + overlayImageBorder: "oib", + overlayImageDPR: "oidpr", + overlayImageQuality: "oiq", + overlayImageCropping: "oic", + overlayImageCropMode: "oicm", + overlayText: "ot", + overlayTextFontSize: "ots", + overlayTextFontFamily: "otf", + overlayTextColor: "otc", + overlayTextTransparency: "oa", + overlayTextTypography: "ott", + overlayBackground: "obg", + overlayTextEncoded: "ote", + overlayTextWidth: "otw", + overlayTextBackground: "otbg", + overlayTextPadding: "otp", + overlayTextInnerAlignment: "otia", + overlayRadius: "or", + progressive: "pr", + lossless: "lo", + trim: "t", + metadata: "md", + colorProfile: "cp", + defaultImage: "di", + dpr: "dpr", + effectSharpen: "e-sharpen", + effectUSM: "e-usm", + effectContrast: "e-contrast", + effectGray: "e-grayscale", + original: "orig" + }, + valueMap: { + fit: { + cover: "maintain_ratio", + contain: "pad_resize", + fill: "force", + inside: "at_max", + outside: "at_least", + extract: "extract", + pad_extract: "pad_extract" + }, + background(value) { + if (value.startsWith("#")) { + return value.replace("#", ""); + } + return value; + }, + crop: { + maintain_ratio: "maintain_ratio", + force: "force", + at_max: "at_max", + at_least: "at_least" + }, + cropMode: { + pad_resize: "pad_resize", + pad_extract: "pad_extract", + extract: "extract" + }, + format: { + auto: "auto", + jpg: "jpg", + jpeg: "jpeg", + webp: "webp", + avif: "avif", + png: "png" + }, + focus: { + left: "left", + right: "right", + top: "top", + bottom: "bottom", + custom: "custom", + center: "center", + top_left: "top_left", + top_right: "top_right", + bottom_left: "bottom_left", + bottom_right: "bottom_right", + auto: "auto", + face: "face" + }, + rotate: { + auto: "auto", + 0: "0", + 90: "90", + 180: "180", + 270: "270", + 360: "360" + }, + overlayFocus: { + left: "left", + right: "right", + top: "top", + bottom: "bottom", + custom: "custom", + center: "center", + top_left: "top_left", + top_right: "top_right", + bottom_left: "bottom_left", + bottom_right: "bottom_right", + auto: "auto", + face: "face" + }, + overlayImageCropping: { + maintain_ratio: "maintain_ratio", + force: "force", + at_max: "at_max", + at_least: "at_least" + }, + overlayImageCropMode: { + pad_resize: "pad_resize", + pad_extract: "pad_extract", + extract: "extract" + }, + overlayTextTypography: { + b: "b", + i: "i" + }, + overlayTextInnerAlignment: { + left: "left", + right: "right", + center: "center" + } + }, + joinWith: ",", + formatter: (key, value) => `${key}-${value}` +}); +export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { + let operations = operationsGenerator(modifiers); + operations = operations.replace("c-pad_resize", "cm-pad_resize"); + operations = operations.replace("c-pad_extract", "cm-pad_extract"); + operations = operations.replace("c-extract", "cm-extract"); + return { + url: joinURL(baseURL, src + (operations ? `?tr=${operations}` : "")) + }; +}; diff --git a/dist/runtime/providers/imgix.d.ts b/dist/runtime/providers/imgix.d.ts new file mode 100644 index 000000000..e4f818101 --- /dev/null +++ b/dist/runtime/providers/imgix.d.ts @@ -0,0 +1,3 @@ +import type { ProviderGetImage } from 'src'; +export declare const operationsGenerator: any; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/imgix.js b/dist/runtime/providers/imgix.js new file mode 100644 index 000000000..ba19b6e01 --- /dev/null +++ b/dist/runtime/providers/imgix.js @@ -0,0 +1,168 @@ +import { joinURL } from "ufo"; +import { createOperationsGenerator } from "~image"; +export const operationsGenerator = createOperationsGenerator({ + keyMap: { + width: "w", + height: "h", + format: "fm", + quality: "q", + backgroundColor: "bg", + rotate: "rot", + mask: "mask", + auto: "auto", + crop: "crop", + brightness: "bri", + contrast: "con", + exposure: "exp", + gamma: "gam", + highlight: "high", + hueShift: "hue", + invert: "invert", + saturation: "sat", + shadow: "shad", + sharpen: "sharp", + unsharpMask: "usm", + unsharpMaskRadius: "usmrad", + vibrance: "vib", + blend: "blend", + blendAlign: "blend-align", + blendAlpha: "blend-alpha", + blendColor: "blend-color", + blendCrop: "blend-crop", + blendFit: "blend-fit", + blendHeight: "blend-h", + blendMode: "blend-mode", + blendPadding: "blend-pad", + blendSize: "blend-size", + blendWidth: "blend-w", + blendXPosition: "blend-x", + blendYPosition: "blend-y", + padding: "pad", + borderBottom: "border-bottom", + borderLeft: "border-left", + innerBorderRadius: "border-radius-inner", + outerBorderRadius: "border-radius", + borderRight: "border-right", + borderTop: "border-top", + borderSizeColor: "border", + paddingBottom: "pad-bottom", + paddingLeft: "pad-left", + paddingRight: "pad-right", + paddingTop: "pad-top", + paletteColorCount: "colors", + colorPaletteExtraction: "palette", + cssPrefix: "prefix", + expirationTimestamp: "expires", + faceIndex: "faceindex", + facePadding: "facepad", + jsonFaceData: "faces", + fillMode: "fill", + fillColor: "fill-color", + gridColors: "grid-colors", + gridSize: "grid-size", + transparency: "transparency", + focalPointDebug: "fp-debug", + focalPointXPosition: "fp-x", + focalPointYPosition: "fp-y", + focalPointZoom: "fp-z", + clientHints: "ch", + chromaSubsampling: "chromasub", + colorQuantization: "colorquant", + colorSpace: "cs", + download: "dl", + dotsPerInch: "dpi", + losslessCompression: "lossless", + maskBackgroundColor: "mask-bg", + maskCornerRadius: "corner-radius", + noiseReductionSharp: "nrs", + noiseReductionBound: "nr", + pdfPageNumber: "page", + pdfAnnotation: "pdf-annotation", + pixelDensity: "dpr", + orientation: "orient", + flipAxis: "flip", + aspectRatio: "ar", + maximumHeight: "max-h", + maximumWidth: "max-w", + minimumHeight: "min-h", + minimumWidth: "min-w", + sourceRectangleRegion: "rect", + gaussianBlur: "blur", + duotoneAlpha: "duotone-alpha", + duotone: "duotone", + halftone: "htn", + monochrome: "monochrome", + pixellate: "px", + sepiaTone: "sepia", + textAlign: "txt-align", + textClippingMode: "txt-clip", + textColor: "txt-color", + textFitMode: "txt-fit", + textFont: "txt-font", + textLigatures: "txt-lig", + textOutlineColor: "txt-line-color", + textOutline: "txt-line", + textPadding: "txt-pad", + textShadow: "txt-shad", + textFontSize: "txt-size", + textWidth: "txt-width", + textString: "txt", + trimColor: "trim-color", + trimMeanDifference: "trim-md", + trimStandardDeviation: "trim-sd", + trimTolerance: "trim-tol", + trimImage: "trim", + textLeading: "txt-lead", + textTracking: "txt-track", + typesettingEndpoint: "~text", + watermarkAlignment: "mark-align", + watermarkAlpha: "mark-alpha", + watermarkBaseURL: "mark-base", + watermarkFitMode: "mark-fit", + watermarkHeight: "mark-h", + watermarkPadding: "mark-pad", + watermarkRotation: "mark-rot", + watermarkScale: "mark-sclae", + watermarkTile: "mark-tile", + watermarkWidth: "mark-w", + watermarkXPosition: "mark-x", + watermarkYPosition: "mark-y", + watermarkImageURL: "mark" + }, + valueMap: { + fit: { + fill: "scale", + inside: "max", + outside: "min", + cover: "crop", + contain: "fill", + clamp: "clamp", + clip: "clip", + facearea: "facearea", + fillMax: "fillmax" + }, + format: { + gif: "gif", + jp2: "jp2", + jpg: "jpg", + json: "json", + jxr: "jxr", + pjpg: "pjpg", + mp4: "mp4", + png: "png", + png8: "png8", + png32: "png32", + webm: "webm", + webp: "webp", + blurhash: "blurhash" + } + }, + joinWith: "&", + formatter: (key, value) => `${key}=${value}` +}); +export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { + const operations = operationsGenerator(modifiers); + return { + url: joinURL(baseURL, src + (operations ? "?" + operations : "")) + }; +}; diff --git a/dist/runtime/providers/ipx.d.ts b/dist/runtime/providers/ipx.d.ts new file mode 100644 index 000000000..65e2e1d38 --- /dev/null +++ b/dist/runtime/providers/ipx.d.ts @@ -0,0 +1,4 @@ +import { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; +export declare const validateDomains = true; +export declare const supportsAlias = true; diff --git a/dist/runtime/providers/ipx.js b/dist/runtime/providers/ipx.js new file mode 100644 index 000000000..f25d6030a --- /dev/null +++ b/dist/runtime/providers/ipx.js @@ -0,0 +1,31 @@ +import { joinURL, encodePath, encodeParam } from "ufo"; +import { createOperationsGenerator } from "~image"; +const operationsGenerator = createOperationsGenerator({ + keyMap: { + format: "f", + fit: "fit", + width: "w", + height: "h", + resize: "s", + quality: "q", + background: "b" + }, + joinWith: ",", + formatter: (key, val) => encodeParam(key) + "_" + encodeParam(val) +}); +export const getImage = (src, { modifiers = {}, baseURL } = {}, ctx) => { + if (modifiers.width && modifiers.height) { + modifiers.resize = `${modifiers.width}x${modifiers.height}`; + delete modifiers.width; + delete modifiers.height; + } + const params = operationsGenerator(modifiers) || "_"; + if (!baseURL) { + baseURL = joinURL(ctx.nuxtContext?.base || "/", "/_ipx"); + } + return { + url: joinURL(baseURL, params, encodePath(src)) + }; +}; +export const validateDomains = true; +export const supportsAlias = true; diff --git a/dist/runtime/providers/layer0.d.ts b/dist/runtime/providers/layer0.d.ts new file mode 100644 index 000000000..d07bf64e2 --- /dev/null +++ b/dist/runtime/providers/layer0.d.ts @@ -0,0 +1,2 @@ +import type { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/layer0.js b/dist/runtime/providers/layer0.js new file mode 100644 index 000000000..723ea91cb --- /dev/null +++ b/dist/runtime/providers/layer0.js @@ -0,0 +1,20 @@ +import { joinURL } from "ufo"; +import { createOperationsGenerator } from "~image"; +const operationsGenerator = createOperationsGenerator({ + keyMap: { + height: "height", + quality: "quality", + width: "width" + }, + joinWith: "&", + formatter: (key, value) => String(value) === "true" ? key : `${key}=${value}` +}); +export const getImage = (src, { + modifiers = {}, + baseURL = "https://opt.moovweb.net" +} = {}) => { + const operations = operationsGenerator(modifiers); + return { + url: joinURL(baseURL, "?img=" + src + (operations ? "&" + operations : "")) + }; +}; diff --git a/dist/runtime/providers/netlify.d.ts b/dist/runtime/providers/netlify.d.ts new file mode 100644 index 000000000..e4f818101 --- /dev/null +++ b/dist/runtime/providers/netlify.d.ts @@ -0,0 +1,3 @@ +import type { ProviderGetImage } from 'src'; +export declare const operationsGenerator: any; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/netlify.js b/dist/runtime/providers/netlify.js new file mode 100644 index 000000000..fffd07535 --- /dev/null +++ b/dist/runtime/providers/netlify.js @@ -0,0 +1,40 @@ +import { joinURL } from "ufo"; +import { createOperationsGenerator } from "~image"; +export const operationsGenerator = createOperationsGenerator({ + keyMap: { + height: "h", + fit: "nf_resize", + width: "w" + }, + valueMap: { + fit: { + fill: "smartcrop", + contain: "fit" + } + }, + joinWith: "&", + formatter: (key, value) => `${key}=${value}` +}); +const isDev = process.env.NODE_ENV === "development"; +export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { + if (modifiers.format) { + delete modifiers.format; + } + const hasTransformation = modifiers.height || modifiers.width; + if (!modifiers.fit && hasTransformation) { + modifiers.fit = "contain"; + } + if (hasTransformation && modifiers.fit !== "contain" && !(modifiers.height && modifiers.width)) { + if (isDev) { + console.warn(`Defaulting to fit=contain as smart cropping is only supported when providing both height and width. Warning originated from \`${src}\`.`); + } + modifiers.fit = "contain"; + } + if (isDev) { + return { url: src }; + } + const operations = operationsGenerator(modifiers); + return { + url: joinURL(baseURL, src + (operations ? "?" + operations : "")) + }; +}; diff --git a/dist/runtime/providers/prismic.d.ts b/dist/runtime/providers/prismic.d.ts new file mode 100644 index 000000000..d07bf64e2 --- /dev/null +++ b/dist/runtime/providers/prismic.d.ts @@ -0,0 +1,2 @@ +import type { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/prismic.js b/dist/runtime/providers/prismic.js new file mode 100644 index 000000000..84d1091c9 --- /dev/null +++ b/dist/runtime/providers/prismic.js @@ -0,0 +1,10 @@ +import { joinURL, parseQuery, parseURL, stringifyQuery } from "ufo"; +import { operationsGenerator } from "./imgix"; +const PRISMIC_IMGIX_BUCKET = "https://images.prismic.io"; +export const getImage = (src, { modifiers = {}, baseURL = PRISMIC_IMGIX_BUCKET } = {}) => { + const operations = operationsGenerator(modifiers); + const parsedURL = parseURL(src); + return { + url: joinURL(baseURL, parsedURL.pathname + "?" + stringifyQuery(Object.assign(parseQuery(parsedURL.search), parseQuery(operations)))) + }; +}; diff --git a/dist/runtime/providers/sanity.d.ts b/dist/runtime/providers/sanity.d.ts new file mode 100644 index 000000000..d07bf64e2 --- /dev/null +++ b/dist/runtime/providers/sanity.d.ts @@ -0,0 +1,2 @@ +import type { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/sanity.js b/dist/runtime/providers/sanity.js new file mode 100644 index 000000000..9019eac54 --- /dev/null +++ b/dist/runtime/providers/sanity.js @@ -0,0 +1,87 @@ +import { joinURL } from "ufo"; +import { createOperationsGenerator } from "~image"; +const sanityCDN = "https://cdn.sanity.io/images"; +const operationsGenerator = createOperationsGenerator({ + keyMap: { + format: "fm", + height: "h", + quality: "q", + width: "w", + background: "bg", + download: "dl", + sharpen: "sharp", + orientation: "or", + "min-height": "min-h", + "max-height": "max-h", + "min-width": "min-w", + "max-width": "max-w", + minHeight: "min-h", + maxHeight: "max-h", + minWidth: "min-w", + maxWidth: "max-w", + saturation: "sat" + }, + valueMap: { + format: { + jpeg: "jpg" + }, + fit: { + cover: "crop", + contain: "fill", + fill: "scale", + inside: "min", + outside: "max" + } + }, + joinWith: "&", + formatter: (key, value) => String(value) === "true" ? key : `${key}=${value}` +}); +const isDev = process.env.NODE_ENV === "development"; +const getMetadata = (id) => { + const result = id.match(/-(?\d*)x(?\d*)-(?.*)$/); + if (!result || !result.groups) { + if (isDev) { + console.warn(`An invalid image asset ID was passed in: ${id}`); + } + return { width: void 0, height: void 0, format: void 0 }; + } + const width = Number(result.groups.width); + const height = Number(result.groups.height); + return { + width, + height, + format: result.groups.format + }; +}; +export const getImage = (src, { modifiers = {}, projectId, dataset = "production" } = {}) => { + const { height: sourceHeight, width: sourceWidth } = getMetadata(src); + if (modifiers.crop && typeof modifiers.crop !== "string" && sourceWidth && sourceHeight) { + const left = modifiers.crop.left * sourceWidth; + const top = modifiers.crop.top * sourceHeight; + const right = sourceWidth - modifiers.crop.right * sourceWidth; + const bottom = sourceHeight - modifiers.crop.bottom * sourceHeight; + modifiers.rect = [left, top, right - left, bottom - top].map((i) => i.toFixed(0)).join(","); + delete modifiers.crop; + } + if (modifiers.hotspot && typeof modifiers.hotspot !== "string") { + modifiers["fp-x"] = modifiers.hotspot.x; + modifiers["fp-y"] = modifiers.hotspot.y; + delete modifiers.hotspot; + } + if (!modifiers.format || modifiers.format === "auto") { + if (modifiers.format === "auto") { + delete modifiers.format; + } + modifiers.auto = "format"; + } + if (modifiers.fit === "contain" && !modifiers.bg) { + modifiers.bg = "ffffff"; + } + const operations = operationsGenerator(modifiers); + const parts = src.split("-").slice(1); + const format = parts.pop(); + const filenameAndQueries = parts.join("-") + "." + format + (operations ? "?" + operations : ""); + return { + url: joinURL(sanityCDN, projectId, dataset, filenameAndQueries) + }; +}; diff --git a/dist/runtime/providers/static.d.ts b/dist/runtime/providers/static.d.ts new file mode 100644 index 000000000..4bcebdd4c --- /dev/null +++ b/dist/runtime/providers/static.d.ts @@ -0,0 +1,3 @@ +import { getImage as _getImage } from './ipx'; +export declare const getImage: typeof _getImage; +export declare const supportsAlias = true; diff --git a/dist/runtime/providers/static.js b/dist/runtime/providers/static.js new file mode 100644 index 000000000..7a030d6db --- /dev/null +++ b/dist/runtime/providers/static.js @@ -0,0 +1,6 @@ +import { getImage as _getImage } from "./ipx"; +export const getImage = (src, options, ctx) => ({ + ..._getImage(src, options, ctx), + isStatic: true +}); +export const supportsAlias = true; diff --git a/dist/runtime/providers/storyblok.d.ts b/dist/runtime/providers/storyblok.d.ts new file mode 100644 index 000000000..d07bf64e2 --- /dev/null +++ b/dist/runtime/providers/storyblok.d.ts @@ -0,0 +1,2 @@ +import type { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/storyblok.js b/dist/runtime/providers/storyblok.js new file mode 100644 index 000000000..f60b8120b --- /dev/null +++ b/dist/runtime/providers/storyblok.js @@ -0,0 +1,28 @@ +import { withBase, joinURL, parseURL } from "ufo"; +const storyblockCDN = "https://a.storyblok.com"; +export const getImage = (src, { modifiers = {}, baseURL = storyblockCDN } = {}) => { + const { + fit, + smart, + width = "0", + height = "0", + filters = {}, + format, + quality + } = modifiers; + const doResize = width !== "0" || height !== "0"; + if (format) { + filters.format = format + ""; + } + if (quality) { + filters.quality = quality + ""; + } + const _filters = Object.entries(filters || {}).map((e) => `${e[0]}(${e[1]})`).join(":"); + const options = joinURL(fit ? `fit-${fit}` : "", doResize ? `${width}x${height}` : "", smart ? "smart" : "", _filters ? "filters:" + _filters : ""); + const { pathname } = parseURL(src); + const modifier = options ? "/m/" : ""; + const url = withBase(joinURL(pathname, modifier, options), baseURL); + return { + url + }; +}; diff --git a/dist/runtime/providers/strapi.d.ts b/dist/runtime/providers/strapi.d.ts new file mode 100644 index 000000000..3bfbfcade --- /dev/null +++ b/dist/runtime/providers/strapi.d.ts @@ -0,0 +1,3 @@ +import { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; +export declare const validateDomains = true; diff --git a/dist/runtime/providers/strapi.js b/dist/runtime/providers/strapi.js new file mode 100644 index 000000000..4633b12e8 --- /dev/null +++ b/dist/runtime/providers/strapi.js @@ -0,0 +1,13 @@ +import { withBase, withoutLeadingSlash } from "ufo"; +export const getImage = (src, { modifiers, baseURL = "http://localhost:1337/uploads" } = {}) => { + const breakpoint = modifiers?.breakpoint ?? ""; + if (!breakpoint) { + return { + url: withBase(src, baseURL) + }; + } + return { + url: withBase(`${breakpoint}_${withoutLeadingSlash(src)}`, baseURL) + }; +}; +export const validateDomains = true; diff --git a/dist/runtime/providers/twicpics.d.ts b/dist/runtime/providers/twicpics.d.ts new file mode 100644 index 000000000..d07bf64e2 --- /dev/null +++ b/dist/runtime/providers/twicpics.d.ts @@ -0,0 +1,2 @@ +import type { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/twicpics.js b/dist/runtime/providers/twicpics.js new file mode 100644 index 000000000..440b7d4d0 --- /dev/null +++ b/dist/runtime/providers/twicpics.js @@ -0,0 +1,64 @@ +import { joinURL } from "ufo"; +import { createMapper, createOperationsGenerator } from "~image"; +const fits = createMapper({ + fill: "resize", + inside: "contain", + outside: "contain", + cover: "cover", + contain: "inside", + missingValue: "cover" +}); +const operationsGenerator = createOperationsGenerator({ + keyMap: { + format: "output", + quality: "quality", + background: "background", + focus: "focus", + zoom: "zoom" + }, + valueMap: { + format(value) { + if (value === "jpg") { + return "jpeg"; + } + return value; + }, + background(value) { + if (value.startsWith("#")) { + return value.replace("#", ""); + } + return value; + }, + focus: { + auto: "auto", + faces: "faces", + north: "50px0p", + northEast: "100px0p", + northWest: "0px0p", + west: "0px50p", + southWest: "100px100p", + south: "50px100p", + southEast: "0px100p", + east: "100px50p", + center: "50px50p" + } + }, + joinWith: "/", + formatter: (key, value) => `${key}=${value}` +}); +export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { + const { width, height, fit, ...providerModifiers } = modifiers; + let w = width; + let h = height; + if (width || height) { + if (fit && fit === "outside") { + w = Math.max(width || 0, height || 0); + h = Math.max(width || 0, height || 0); + } + providerModifiers[fits(fit)] = `${w || "-"}x${h || "-"}`; + } + const operations = operationsGenerator(providerModifiers); + return { + url: joinURL(baseURL, src + (operations ? "?twic=v1/" + operations : "")) + }; +}; diff --git a/dist/runtime/providers/unsplash.d.ts b/dist/runtime/providers/unsplash.d.ts new file mode 100644 index 000000000..d07bf64e2 --- /dev/null +++ b/dist/runtime/providers/unsplash.d.ts @@ -0,0 +1,2 @@ +import type { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/unsplash.js b/dist/runtime/providers/unsplash.js new file mode 100644 index 000000000..328d6cd7d --- /dev/null +++ b/dist/runtime/providers/unsplash.js @@ -0,0 +1,9 @@ +import { joinURL, withBase } from "ufo"; +import { operationsGenerator } from "./imgix"; +const unsplashCDN = "https://images.unsplash.com/"; +export const getImage = (src, { modifiers = {}, baseURL = unsplashCDN } = {}) => { + const operations = operationsGenerator(modifiers); + return { + url: withBase(joinURL(src + (operations ? "?" + operations : "")), baseURL) + }; +}; diff --git a/dist/runtime/providers/vercel.d.ts b/dist/runtime/providers/vercel.d.ts new file mode 100644 index 000000000..3bfbfcade --- /dev/null +++ b/dist/runtime/providers/vercel.d.ts @@ -0,0 +1,3 @@ +import { ProviderGetImage } from 'src'; +export declare const getImage: ProviderGetImage; +export declare const validateDomains = true; diff --git a/dist/runtime/providers/vercel.js b/dist/runtime/providers/vercel.js new file mode 100644 index 000000000..613fd733d --- /dev/null +++ b/dist/runtime/providers/vercel.js @@ -0,0 +1,28 @@ +import { stringifyQuery } from "ufo"; +export const getImage = (src, { modifiers, baseURL = "/_vercel/image" } = {}, ctx) => { + const validWidths = Object.values(ctx.options.screens || {}).sort((a, b) => a - b); + const largestWidth = validWidths[validWidths.length - 1]; + let width = Number(modifiers?.width || 0); + if (!width) { + width = largestWidth; + if (process.env.NODE_ENV === "development") { + console.warn(`A defined width should be provided to use the \`vercel\` provider. Defaulting to \`${largestWidth}\`. Warning originated from \`${src}\`.`); + } + } else if (!validWidths.includes(width)) { + width = validWidths.find((validWidth) => validWidth > width) || largestWidth; + if (process.env.NODE_ENV === "development") { + console.warn(`The width being used (\`${modifiers?.width}\`) should be added to \`image.screens\`. Defaulting to \`${width}\`. Warning originated from \`${src}\`.`); + } + } + if (process.env.NODE_ENV === "development") { + return { url: src }; + } + return { + url: baseURL + "?" + stringifyQuery({ + url: src, + w: String(width), + q: String(modifiers?.quality || "100") + }) + }; +}; +export const validateDomains = true; diff --git a/dist/runtime/utils/index.d.ts b/dist/runtime/utils/index.d.ts new file mode 100644 index 000000000..131c9723d --- /dev/null +++ b/dist/runtime/utils/index.d.ts @@ -0,0 +1,17 @@ +import type { OperationGeneratorConfig } from '../../types/image'; +export default function imageFetch(url: string): Promise; +export declare function getInt(x: unknown): number | undefined; +export declare function getFileExtension(url?: string): string; +export declare function cleanDoubleSlashes(path?: string): string; +export declare function createMapper(map: any): (key?: string) => any; +export declare function createOperationsGenerator({ formatter, keyMap, joinWith, valueMap }?: OperationGeneratorConfig): (modifiers?: { + [key: string]: string; +}) => string; +declare type Attrs = { + [key: string]: string | number; +}; +export declare function renderAttributesToString(attributes?: Attrs): string; +export declare function renderTag(tag: string, attrs: Attrs, contents?: string): string; +export declare function generateAlt(src?: string): string; +export declare function parseSize(input?: string | number | undefined): number; +export {}; diff --git a/dist/runtime/utils/index.js b/dist/runtime/utils/index.js new file mode 100644 index 000000000..db9713c03 --- /dev/null +++ b/dist/runtime/utils/index.js @@ -0,0 +1,72 @@ +export default function imageFetch(url) { + return fetch(cleanDoubleSlashes(url)); +} +export function getInt(x) { + if (typeof x === "number") { + return x; + } + if (typeof x === "string") { + return parseInt(x, 10); + } + return void 0; +} +export function getFileExtension(url = "") { + const extension = url.split(/[?#]/).shift().split("/").pop().split(".").pop(); + return extension; +} +export function cleanDoubleSlashes(path = "") { + return path.replace(/(https?:\/\/)|(\/)+/g, "$1$2"); +} +export function createMapper(map) { + return (key) => { + return key ? map[key] || key : map.missingValue; + }; +} +export function createOperationsGenerator({ formatter, keyMap, joinWith = "/", valueMap } = {}) { + if (!formatter) { + formatter = (key, value) => `${key}=${value}`; + } + if (keyMap && typeof keyMap !== "function") { + keyMap = createMapper(keyMap); + } + const map = valueMap || {}; + Object.keys(map).forEach((valueKey) => { + if (typeof map[valueKey] !== "function") { + map[valueKey] = createMapper(map[valueKey]); + } + }); + return (modifiers = {}) => { + const operations = Object.entries(modifiers).filter(([_, value]) => typeof value !== "undefined").map(([key, value]) => { + const mapper = map[key]; + if (typeof mapper === "function") { + value = mapper(modifiers[key]); + } + key = typeof keyMap === "function" ? keyMap(key) : key; + return formatter(key, value); + }); + return operations.join(joinWith); + }; +} +export function renderAttributesToString(attributes = {}) { + return Object.entries(attributes).map(([key, value]) => value ? `${key}="${value}"` : "").filter(Boolean).join(" "); +} +export function renderTag(tag, attrs, contents) { + const html = `<${tag} ${renderAttributesToString(attrs)}>`; + if (!contents) { + return html; + } + return html + contents + ``; +} +export function generateAlt(src = "") { + return src.split(/[?#]/).shift().split("/").pop().split(".").shift(); +} +export function parseSize(input = "") { + if (typeof input === "number") { + return input; + } + if (typeof input === "string") { + if (input.replace("px", "").match(/^\d+$/g)) { + return parseInt(input, 10); + } + } +} diff --git a/dist/runtime/utils/meta.d.ts b/dist/runtime/utils/meta.d.ts new file mode 100644 index 000000000..9a841ba42 --- /dev/null +++ b/dist/runtime/utils/meta.d.ts @@ -0,0 +1,2 @@ +import type { ImageInfo, ImageCTX } from '../../types/image'; +export declare function imageMeta(ctx: ImageCTX, url: string): Promise; diff --git a/dist/runtime/utils/meta.js b/dist/runtime/utils/meta.js new file mode 100644 index 000000000..6b9e9aa94 --- /dev/null +++ b/dist/runtime/utils/meta.js @@ -0,0 +1,67 @@ +export async function imageMeta(ctx, url) { + const cache = getCache(ctx); + const cacheKey = "image:meta:" + url; + if (cache.has(cacheKey)) { + return cache.get(cacheKey); + } + const meta = await _imageMeta(url).catch((err) => { + console.error("Failed to get image meta for " + url, err + ""); + return { + width: 0, + height: 0, + ratio: 0 + }; + }); + cache.set(cacheKey, meta); + return meta; +} +async function _imageMeta(url) { + if (process.server) { + const imageMeta2 = await import("image-meta").then((r) => r.default || r); + const data = await fetch(url).then((res) => res.buffer()); + const metadata = imageMeta2(data); + if (!metadata) { + throw new Error(`No metadata could be extracted from the image \`${url}\`.`); + } + const { width, height } = metadata; + const meta = { + width, + height, + ratio: width && height ? width / height : void 0 + }; + return meta; + } + if (typeof Image === "undefined") { + throw new TypeError("Image not supported"); + } + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => { + const meta = { + width: img.width, + height: img.height, + ratio: img.width / img.height + }; + resolve(meta); + }; + img.onerror = (err) => reject(err); + img.src = url; + }); +} +function getCache(ctx) { + if (!ctx.nuxtContext.cache) { + if (ctx.nuxtContext.ssrContext && ctx.nuxtContext.ssrContext.cache) { + ctx.nuxtContext.cache = ctx.nuxtContext.ssrContext.cache; + } else { + const _cache = {}; + ctx.nuxtContext.cache = { + get: (id) => _cache[id], + set: (id, value) => { + _cache[id] = value; + }, + has: (id) => typeof _cache[id] !== "undefined" + }; + } + } + return ctx.nuxtContext.cache; +} diff --git a/dist/runtime/utils/static-map.d.ts b/dist/runtime/utils/static-map.d.ts new file mode 100644 index 000000000..38d417a0d --- /dev/null +++ b/dist/runtime/utils/static-map.d.ts @@ -0,0 +1,2 @@ +import type { Context } from '@nuxt/types'; +export declare function useStaticImageMap(nuxtContext?: Context): {}; diff --git a/dist/runtime/utils/static-map.js b/dist/runtime/utils/static-map.js new file mode 100644 index 000000000..e6516964b --- /dev/null +++ b/dist/runtime/utils/static-map.js @@ -0,0 +1,20 @@ +const staticImageMap = {}; +function updateImageMap() { + if (typeof window.$nuxt !== "undefined") { + const pageImages = window.$nuxt._pagePayload?.data?.[0]?._img || {}; + Object.assign(staticImageMap, pageImages); + } else if (typeof window.__NUXT__ !== "undefined") { + const pageImages = window.__NUXT__?._img || {}; + Object.assign(staticImageMap, pageImages); + } +} +export function useStaticImageMap(nuxtContext) { + updateImageMap(); + if (nuxtContext) { + nuxtContext.app.router?.afterEach(updateImageMap); + } + if (window.onNuxtReady) { + window.onNuxtReady(updateImageMap); + } + return staticImageMap; +} From 0aa502e3b67d9de596ad6c582a45bbff2382d791 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Fri, 20 Jan 2023 18:58:54 +0000 Subject: [PATCH 11/17] fix: updated readme and remove dist again in favour of npm --- .gitignore | 1 + README.md | 14 +- dist/module.cjs | 303 ------------------ dist/module.d.ts | 184 ----------- dist/module.mjs | 290 ----------------- dist/runtime/components/image.mixin.d.ts | 47 --- dist/runtime/components/image.mixin.js | 59 ---- dist/runtime/components/nuxt-img.vue | 92 ------ dist/runtime/components/nuxt-img.vue.d.ts | 16 - dist/runtime/components/nuxt-picture.vue | 105 ------ dist/runtime/components/nuxt-picture.vue.d.ts | 16 - dist/runtime/image.d.ts | 2 - dist/runtime/image.js | 182 ----------- dist/runtime/index.d.ts | 2 - dist/runtime/index.js | 2 - dist/runtime/ipx.d.ts | 3 - dist/runtime/ipx.js | 3 - dist/runtime/plugin.d.ts | 1 - dist/runtime/plugin.js | 31 -- dist/runtime/providers/cloudflare.d.ts | 2 - dist/runtime/providers/cloudflare.js | 41 --- dist/runtime/providers/cloudimage.d.ts | 2 - dist/runtime/providers/cloudimage.js | 34 -- dist/runtime/providers/cloudinary.d.ts | 2 - dist/runtime/providers/cloudinary.js | 96 ------ dist/runtime/providers/contentful.d.ts | 3 - dist/runtime/providers/contentful.js | 36 --- dist/runtime/providers/fastly.d.ts | 2 - dist/runtime/providers/fastly.js | 21 -- dist/runtime/providers/glide.d.ts | 2 - dist/runtime/providers/glide.js | 49 --- dist/runtime/providers/gumlet.d.ts | 3 - dist/runtime/providers/gumlet.js | 75 ----- dist/runtime/providers/imageengine.d.ts | 3 - dist/runtime/providers/imageengine.js | 45 --- dist/runtime/providers/imagekit.d.ts | 2 - dist/runtime/providers/imagekit.js | 172 ---------- dist/runtime/providers/imgix.d.ts | 3 - dist/runtime/providers/imgix.js | 168 ---------- dist/runtime/providers/ipx.d.ts | 4 - dist/runtime/providers/ipx.js | 31 -- dist/runtime/providers/layer0.d.ts | 2 - dist/runtime/providers/layer0.js | 20 -- dist/runtime/providers/netlify.d.ts | 3 - dist/runtime/providers/netlify.js | 40 --- dist/runtime/providers/prismic.d.ts | 2 - dist/runtime/providers/prismic.js | 10 - dist/runtime/providers/sanity.d.ts | 2 - dist/runtime/providers/sanity.js | 87 ----- dist/runtime/providers/static.d.ts | 3 - dist/runtime/providers/static.js | 6 - dist/runtime/providers/storyblok.d.ts | 2 - dist/runtime/providers/storyblok.js | 28 -- dist/runtime/providers/strapi.d.ts | 3 - dist/runtime/providers/strapi.js | 13 - dist/runtime/providers/twicpics.d.ts | 2 - dist/runtime/providers/twicpics.js | 64 ---- dist/runtime/providers/unsplash.d.ts | 2 - dist/runtime/providers/unsplash.js | 9 - dist/runtime/providers/vercel.d.ts | 3 - dist/runtime/providers/vercel.js | 28 -- dist/runtime/utils/index.d.ts | 17 - dist/runtime/utils/index.js | 72 ----- dist/runtime/utils/meta.d.ts | 2 - dist/runtime/utils/meta.js | 67 ---- dist/runtime/utils/static-map.d.ts | 2 - dist/runtime/utils/static-map.js | 20 -- package.json | 3 +- 68 files changed, 14 insertions(+), 2647 deletions(-) delete mode 100644 dist/module.cjs delete mode 100644 dist/module.d.ts delete mode 100644 dist/module.mjs delete mode 100644 dist/runtime/components/image.mixin.d.ts delete mode 100644 dist/runtime/components/image.mixin.js delete mode 100644 dist/runtime/components/nuxt-img.vue delete mode 100644 dist/runtime/components/nuxt-img.vue.d.ts delete mode 100644 dist/runtime/components/nuxt-picture.vue delete mode 100644 dist/runtime/components/nuxt-picture.vue.d.ts delete mode 100644 dist/runtime/image.d.ts delete mode 100644 dist/runtime/image.js delete mode 100644 dist/runtime/index.d.ts delete mode 100644 dist/runtime/index.js delete mode 100644 dist/runtime/ipx.d.ts delete mode 100644 dist/runtime/ipx.js delete mode 100644 dist/runtime/plugin.d.ts delete mode 100644 dist/runtime/plugin.js delete mode 100644 dist/runtime/providers/cloudflare.d.ts delete mode 100644 dist/runtime/providers/cloudflare.js delete mode 100644 dist/runtime/providers/cloudimage.d.ts delete mode 100644 dist/runtime/providers/cloudimage.js delete mode 100644 dist/runtime/providers/cloudinary.d.ts delete mode 100644 dist/runtime/providers/cloudinary.js delete mode 100644 dist/runtime/providers/contentful.d.ts delete mode 100644 dist/runtime/providers/contentful.js delete mode 100644 dist/runtime/providers/fastly.d.ts delete mode 100644 dist/runtime/providers/fastly.js delete mode 100644 dist/runtime/providers/glide.d.ts delete mode 100644 dist/runtime/providers/glide.js delete mode 100644 dist/runtime/providers/gumlet.d.ts delete mode 100644 dist/runtime/providers/gumlet.js delete mode 100644 dist/runtime/providers/imageengine.d.ts delete mode 100644 dist/runtime/providers/imageengine.js delete mode 100644 dist/runtime/providers/imagekit.d.ts delete mode 100644 dist/runtime/providers/imagekit.js delete mode 100644 dist/runtime/providers/imgix.d.ts delete mode 100644 dist/runtime/providers/imgix.js delete mode 100644 dist/runtime/providers/ipx.d.ts delete mode 100644 dist/runtime/providers/ipx.js delete mode 100644 dist/runtime/providers/layer0.d.ts delete mode 100644 dist/runtime/providers/layer0.js delete mode 100644 dist/runtime/providers/netlify.d.ts delete mode 100644 dist/runtime/providers/netlify.js delete mode 100644 dist/runtime/providers/prismic.d.ts delete mode 100644 dist/runtime/providers/prismic.js delete mode 100644 dist/runtime/providers/sanity.d.ts delete mode 100644 dist/runtime/providers/sanity.js delete mode 100644 dist/runtime/providers/static.d.ts delete mode 100644 dist/runtime/providers/static.js delete mode 100644 dist/runtime/providers/storyblok.d.ts delete mode 100644 dist/runtime/providers/storyblok.js delete mode 100644 dist/runtime/providers/strapi.d.ts delete mode 100644 dist/runtime/providers/strapi.js delete mode 100644 dist/runtime/providers/twicpics.d.ts delete mode 100644 dist/runtime/providers/twicpics.js delete mode 100644 dist/runtime/providers/unsplash.d.ts delete mode 100644 dist/runtime/providers/unsplash.js delete mode 100644 dist/runtime/providers/vercel.d.ts delete mode 100644 dist/runtime/providers/vercel.js delete mode 100644 dist/runtime/utils/index.d.ts delete mode 100644 dist/runtime/utils/index.js delete mode 100644 dist/runtime/utils/meta.d.ts delete mode 100644 dist/runtime/utils/meta.js delete mode 100644 dist/runtime/utils/static-map.d.ts delete mode 100644 dist/runtime/utils/static-map.js diff --git a/.gitignore b/.gitignore index 3934dfb3a..da8a822b8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ node_modules .nuxt *.log cache/ +dist/ .DS_Store coverage sw.* diff --git a/README.md b/README.md index 56f139215..8e6c4cc9e 100755 --- a/README.md +++ b/README.md @@ -2,11 +2,21 @@ This is a fork, to fix the fingerprinting of static files. This package should in fact use the contents of the file to create the `[hash]` part of static filename. -I couldn't work out the best way to report back this change to the main module as they are preparing for a new release, so it exists here, with the `dist` folder commited, for you to: +I couldn't work out the best way to report back this change to the main module as they are preparing for a new release, so it exists here, for you to: ## Install -`yarn add jthawme/nuxt-image-fork` +`yarn add jthawme-image-fork` + +With nuxt 2 you also have to add this package to the `transpile` property in `nuxt.config.js` + +``` +... +build: { + // other config etc. + transpile: ["jthawme-nuxt-image"] +}, +``` --- diff --git a/dist/module.cjs b/dist/module.cjs deleted file mode 100644 index 05774a1f0..000000000 --- a/dist/module.cjs +++ /dev/null @@ -1,303 +0,0 @@ -'use strict'; - -const upath = require('upath'); -const defu = require('defu'); -const ufo = require('ufo'); -const LruCache = require('lru-cache'); -const fs = require('fs'); -const util = require('util'); -const stream = require('stream'); -const path = require('path'); -const fsExtra = require('fs-extra'); -const nodeFetchNative = require('node-fetch-native'); -const hasha$1 = require('hasha'); -const pLimit = require('p-limit'); -const consola = require('consola'); -const hasha = require('hasha/index.js'); -const rc9 = require('rc9'); -const semver = require('semver'); - -function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; } - -const defu__default = /*#__PURE__*/_interopDefaultLegacy(defu); -const LruCache__default = /*#__PURE__*/_interopDefaultLegacy(LruCache); -const stream__default = /*#__PURE__*/_interopDefaultLegacy(stream); -const path__default = /*#__PURE__*/_interopDefaultLegacy(path); -const hasha__default$1 = /*#__PURE__*/_interopDefaultLegacy(hasha$1); -const pLimit__default = /*#__PURE__*/_interopDefaultLegacy(pLimit); -const consola__default = /*#__PURE__*/_interopDefaultLegacy(consola); -const hasha__default = /*#__PURE__*/_interopDefaultLegacy(hasha); - -const name = "@jthawme/nuxt-image"; -const version = "0.8.4"; - -const logger = consola__default.withScope("@nuxt/image"); -const pkg = { name, version }; -function hash(value, length = 6) { - return hasha__default(value).substr(0, length); -} -function pick(obj, keys) { - const newobj = {}; - for (const key of keys) { - newobj[key] = obj[key]; - } - return newobj; -} -function guessExt(input = "") { - const ext = input.split(".").pop()?.split("?")[0]; - if (ext && /^[\w0-9]+$/.test(ext)) { - return "." + ext; - } - return ""; -} - -function getHash(input, url) { - const staticFile = path__default.join(process.cwd(), "static", input); - if (fs.existsSync(staticFile)) { - return hasha__default$1.fromFileSync(staticFile); - } - return hash(url); -} -function setupStaticGeneration(nuxt, options) { - const staticImages = {}; - nuxt.hook("vue-renderer:ssr:prepareContext", (renderContext) => { - renderContext.image = renderContext.image || {}; - renderContext.image.mapToStatic = function({ url, format }, input) { - if (!staticImages[url]) { - const { pathname } = ufo.parseURL(input); - const params = { - name: upath.trimExt(upath.basename(pathname)), - ext: format && `.${format}` || guessExt(input), - hash: getHash(input, url), - publicPath: nuxt.options.app.cdnURL ? "/" : ufo.withoutTrailingSlash(nuxt.options.build.publicPath) - }; - staticImages[url] = options.staticFilename.replace(/\[(\w+)]/g, (match, key) => params[key] || match); - } - return ufo.joinURL(nuxt.options.app.cdnURL || nuxt.options.app.basePath, staticImages[url]); - }; - }); - nuxt.hook("generate:done", async () => { - const limit = pLimit__default(8); - const downloads = Object.entries(staticImages).map(([url, name]) => { - if (!ufo.hasProtocol(url)) { - url = ufo.joinURL(options.internalUrl, url); - } - return limit(() => downloadImage({ - url, - name, - outDir: nuxt.options.generate.dir - })); - }); - await Promise.all(downloads); - }); -} -const pipeline = util.promisify(stream__default.pipeline); -async function downloadImage({ url, name, outDir }) { - try { - const response = await nodeFetchNative.fetch(url); - if (!response.ok) { - throw new Error(`Unexpected response ${response.statusText}`); - } - const dstFile = upath.join(outDir, name); - await fsExtra.mkdirp(upath.dirname(dstFile)); - await pipeline(response.body, fs.createWriteStream(dstFile)); - logger.success("Generated static image " + upath.relative(process.cwd(), dstFile)); - } catch (error) { - logger.error(error?.message); - } -} - -const ipxSetup = async (_providerOptions, moduleOptions, nuxt) => { - const isStatic = nuxt.options.target === "static"; - const runtimeDir = upath.resolve(__dirname, "runtime"); - const ipxOptions = { - dir: upath.resolve(nuxt.options.rootDir, moduleOptions.dir), - domains: moduleOptions.domains, - sharp: moduleOptions.sharp, - alias: moduleOptions.alias - }; - const hasUserProvidedIPX = !!nuxt.options.serverMiddleware.find((mw) => mw.path && mw.path.startsWith("/_ipx")); - if (!hasUserProvidedIPX) { - const { createIPX, createIPXMiddleware } = await import('ipx').catch((err) => { - console.error("[@nuxt/image] `ipx` is an optional dependency for local image optimization and is not properly installed. Please try `npm install` or `yarn install` again."); - throw new Error(err); - }); - const ipx = createIPX(ipxOptions); - nuxt.options.serverMiddleware.push({ - path: "/_ipx", - handle: createIPXMiddleware(ipx) - }); - } - const installedInModules = nuxt.options.modules.some((mod) => typeof mod === "string" && mod.includes("@nuxt/image")); - if (!isStatic && !hasUserProvidedIPX && !installedInModules && semver.lt(nuxt.constructor.version, "2.16.0")) { - console.warn("[@nuxt/image] If you would like to use the `ipx` provider at runtime.\nMake sure to follow the instructions at https://image.nuxtjs.org/providers/ipx ."); - } - if (nuxt.options.dev || hasUserProvidedIPX) { - return; - } - nuxt.hook("build:done", async () => { - const handler = await fsExtra.readFile(upath.resolve(runtimeDir, "ipx.js"), "utf-8"); - const distDir = upath.resolve(nuxt.options.buildDir, "dist"); - const apiDir = upath.resolve(distDir, "api"); - const apiFile = upath.resolve(apiDir, "ipx.js"); - const relativeApiFile = "~~/" + upath.relative(nuxt.options.rootDir, apiFile); - await fsExtra.mkdirp(apiDir); - await fsExtra.writeFile(apiFile, handler.replace(/.__IPX_OPTIONS__./, JSON.stringify(ipxOptions))); - rc9.update({ serverMiddleware: [{ path: "/_ipx", handler: relativeApiFile }] }, { dir: distDir, name: "nuxtrc" }); - }); -}; - -const BuiltInProviders = [ - "cloudflare", - "cloudinary", - "contentful", - "cloudimage", - "fastly", - "glide", - "imagekit", - "gumlet", - "imgix", - "ipx", - "netlify", - "layer0", - "prismic", - "sanity", - "static", - "twicpics", - "strapi", - "storyblok", - "unsplash", - "vercel", - "imageengine" -]; -const providerSetup = { - ipx: ipxSetup, - static: ipxSetup, - async vercel(_providerOptions, moduleOptions, nuxt) { - const imagesConfig = upath.resolve(nuxt.options.rootDir, ".vercel_build_output/config/images.json"); - await fsExtra.mkdirp(upath.dirname(imagesConfig)); - await fsExtra.writeJson(imagesConfig, { - domains: moduleOptions.domains, - sizes: Array.from(new Set(Object.values(moduleOptions.screens || {}))) - }); - } -}; -function resolveProviders(nuxt, options) { - const providers = []; - for (const key in options) { - if (BuiltInProviders.includes(key)) { - providers.push(resolveProvider(nuxt, key, { provider: key, options: options[key] })); - } - } - for (const key in options.providers) { - providers.push(resolveProvider(nuxt, key, options.providers[key])); - } - return providers; -} -function resolveProvider(nuxt, key, input) { - if (typeof input === "string") { - input = { name: input }; - } - if (!input.name) { - input.name = key; - } - if (!input.provider) { - input.provider = input.name; - } - input.provider = BuiltInProviders.includes(input.provider) ? require.resolve("./runtime/providers/" + input.provider) : nuxt.resolver.resolvePath(input.provider); - const setup = input.setup || providerSetup[input.name]; - return { - ...input, - setup, - runtime: upath.normalize(input.provider), - importName: `${key}Runtime$${hash(input.provider, 4)}`, - runtimeOptions: input.options - }; -} -function detectProvider(userInput, isStatic = false) { - if (process.env.NUXT_IMAGE_PROVIDER) { - return process.env.NUXT_IMAGE_PROVIDER; - } - if (userInput && userInput !== "auto") { - return userInput; - } - if (process.env.VERCEL || process.env.VERCEL_ENV || process.env.NOW_BUILDER) { - return "vercel"; - } - return isStatic ? "static" : "ipx"; -} - -const imageModule = async function imageModule2(moduleOptions) { - const { nuxt, addPlugin } = this; - const defaults = { - staticFilename: "[publicPath]/image/[hash][ext]", - provider: "auto", - presets: {}, - dir: upath.resolve(nuxt.options.srcDir, nuxt.options.dir.static), - domains: [], - sharp: {}, - screens: { - xs: 320, - sm: 640, - md: 768, - lg: 1024, - xl: 1280, - xxl: 1536, - "2xl": 1536 - }, - internalUrl: "", - providers: {}, - static: {}, - alias: {} - }; - const options = defu__default(moduleOptions, nuxt.options.image, defaults); - options.domains = options.domains.map((d) => { - if (!d.startsWith("http")) { - d = "http://" + d; - } - return new URL(d).hostname; - }).filter(Boolean); - options.alias = Object.fromEntries(Object.entries(options.alias).map((e) => [ufo.withLeadingSlash(e[0]), e[1]])); - options.provider = detectProvider(options.provider, nuxt.options.target === "static"); - options[options.provider] = options[options.provider] || {}; - const imageOptions = pick(options, [ - "screens", - "presets", - "provider", - "domains", - "alias" - ]); - const providers = resolveProviders(nuxt, options); - for (const p of providers) { - if (typeof p.setup === "function") { - await p.setup(p, options, nuxt); - } - } - const runtimeDir = upath.resolve(__dirname, "runtime"); - nuxt.options.alias["~image"] = runtimeDir; - nuxt.options.build.transpile.push(runtimeDir, "@nuxt/image", "allowlist", "defu", "ufo"); - addPlugin({ - fileName: "image.js", - src: upath.resolve(runtimeDir, "plugin.js"), - options: { - imageOptions, - providers - } - }); - nuxt.options.build.loaders = defu__default({ - vue: { transformAssetUrls: { "nuxt-img": "src", "nuxt-picture": "src", NuxtPicture: "src", NuxtImg: "src" } } - }, nuxt.options.build.loaders || {}); - nuxt.hook("generate:before", () => { - setupStaticGeneration(nuxt, options); - }); - const cache = new LruCache__default({ max: 1e3 }); - nuxt.hook("vue-renderer:context", (ssrContext) => { - ssrContext.cache = cache; - }); - nuxt.hook("listen", (_, listener) => { - options.internalUrl = `http://localhost:${listener.port}`; - }); -}; -imageModule.meta = pkg; - -module.exports = imageModule; diff --git a/dist/module.d.ts b/dist/module.d.ts deleted file mode 100644 index 84fc531a2..000000000 --- a/dist/module.d.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Module } from '@nuxt/types'; -import { IPXOptions } from 'ipx'; - -interface ImageModifiers { - width: number; - height: number; - fit: string; - format: string; - [key: string]: any; -} -interface ImageOptions { - provider?: string; - preset?: string; - modifiers?: Partial; - [key: string]: any; -} -interface ImageSizesOptions extends ImageOptions { - sizes: Record | string; -} -declare type ProviderGetImage = (src: string, options: ImageOptions, ctx: ImageCTX) => ResolvedImage; -interface ImageProvider { - defaults?: any; - getImage: ProviderGetImage; - validateDomains?: Boolean; - supportsAlias?: Boolean; -} -interface CreateImageOptions { - providers: { - [name: string]: { - defaults: any; - provider: ImageProvider; - }; - }; - presets: { - [name: string]: ImageOptions; - }; - provider: string; - screens: Record; - alias: Record; - domains: string[]; -} -interface ImageInfo { - width: number; - height: number; - placeholder?: string; -} -interface ResolvedImage { - url: string; - format?: string; - isStatic?: boolean; - getMeta?: () => Promise; -} -interface ImageSizes { - srcset: string; - sizes: string; - src: string; -} -interface Img { - (source: string, modifiers?: ImageOptions['modifiers'], options?: ImageOptions): ResolvedImage['url']; - options: CreateImageOptions; - getImage: (source: string, options?: ImageOptions) => ResolvedImage; - getSizes: (source: string, options?: ImageOptions, sizes?: string[]) => ImageSizes; - getMeta: (source: string, options?: ImageOptions) => Promise; -} -declare type $Img = Img & { - [preset: string]: $Img; -}; -interface ImageCTX { - options: CreateImageOptions; - nuxtContext: { - ssrContext: any; - cache?: any; - isDev: boolean; - isStatic: boolean; - nuxtState?: any; - base?: string; - }; - $img?: $Img; -} -interface ImageSize { - width: number; - media: string; - breakpoint: number; - format: string; - url: string; -} -interface RuntimePlaceholder extends ImageInfo { - url: string; -} -declare type OperationFormatter = (key: string, value: string) => string; -declare type OperationMapper = { - [key: string]: string | false; -} | ((key: string) => string); -interface OperationGeneratorConfig { - keyMap?: OperationMapper; - formatter?: OperationFormatter; - joinWith?: string; - valueMap?: { - [key: string]: OperationMapper; - }; -} -declare type MapToStatic = (image: ResolvedImage, input: string) => string; - -declare type ProviderSetup = (providerOptions: ImageModuleProvider, moduleOptions: ModuleOptions, nuxt: any) => void | Promise; -interface InputProvider { - name?: string; - provider?: string; - options?: T; - setup?: ProviderSetup; -} -interface CloudinaryModifiers extends ImageModifiers { - format: string; - quality: string; - background: string; - rotate: 'auto_right' | 'auto_left' | 'ignore' | 'vflip' | 'hflip' | number; - roundCorner: string; - gravity: string; - effect: string; - color: string; - flags: string; - dpr: string; - opacity: number; - overlay: string; - underlay: string; - transformation: string; - zoom: number; - colorSpace: string; - customFunc: string; - density: number; -} -interface CloudinaryOptions { - baseURL: string; - modifiers: Partial; - [key: string]: any; -} -interface ImageProviders { - cloudflare?: any; - cloudinary?: Partial; - contentful?: any; - cloudimage?: any; - fastly?: any; - glide?: any; - gumlet?: any; - imagekit?: any; - imgix?: any; - layer0?: any; - prismic?: any; - twicpics?: any; - storyblok?: any; - strapi?: any; - imageengine?: any; - ipx?: Partial; - static?: Partial; -} -interface ModuleOptions extends ImageProviders { - staticFilename: string; - provider: CreateImageOptions['provider']; - presets: { - [name: string]: ImageOptions; - }; - dir: string; - domains: string[]; - sharp: any; - alias: Record; - screens: CreateImageOptions['screens']; - internalUrl: string; - providers: { - [name: string]: InputProvider | any; - } & ImageProviders; - [key: string]: any; -} -interface ImageModuleProvider { - name: string; - importName: string; - options: any; - provider: string; - runtime: string; - runtimeOptions: any; - setup: ProviderSetup; -} - -declare const imageModule: Module; - -export { $Img, CloudinaryModifiers, CloudinaryOptions, CreateImageOptions, ImageCTX, ImageInfo, ImageModifiers, ImageModuleProvider, ImageOptions, ImageProvider, ImageProviders, ImageSize, ImageSizes, ImageSizesOptions, Img, InputProvider, MapToStatic, ModuleOptions, OperationFormatter, OperationGeneratorConfig, OperationMapper, ProviderGetImage, ProviderSetup, ResolvedImage, RuntimePlaceholder, imageModule as default }; diff --git a/dist/module.mjs b/dist/module.mjs deleted file mode 100644 index a76ec845e..000000000 --- a/dist/module.mjs +++ /dev/null @@ -1,290 +0,0 @@ -import { trimExt, basename, join, dirname, relative, resolve, normalize } from 'upath'; -import defu from 'defu'; -import { parseURL, withoutTrailingSlash, joinURL, hasProtocol, withLeadingSlash } from 'ufo'; -import LruCache from 'lru-cache'; -import { createWriteStream, existsSync } from 'fs'; -import { promisify } from 'util'; -import stream from 'stream'; -import path from 'path'; -import { mkdirp, readFile, writeFile, writeJson } from 'fs-extra'; -import { fetch } from 'node-fetch-native'; -import hasha$1 from 'hasha'; -import pLimit from 'p-limit'; -import consola from 'consola'; -import hasha from 'hasha/index.js'; -import { update } from 'rc9'; -import { lt } from 'semver'; - -const name = "@jthawme/nuxt-image"; -const version = "0.8.4"; - -const logger = consola.withScope("@nuxt/image"); -const pkg = { name, version }; -function hash(value, length = 6) { - return hasha(value).substr(0, length); -} -function pick(obj, keys) { - const newobj = {}; - for (const key of keys) { - newobj[key] = obj[key]; - } - return newobj; -} -function guessExt(input = "") { - const ext = input.split(".").pop()?.split("?")[0]; - if (ext && /^[\w0-9]+$/.test(ext)) { - return "." + ext; - } - return ""; -} - -function getHash(input, url) { - const staticFile = path.join(process.cwd(), "static", input); - if (existsSync(staticFile)) { - return hasha$1.fromFileSync(staticFile); - } - return hash(url); -} -function setupStaticGeneration(nuxt, options) { - const staticImages = {}; - nuxt.hook("vue-renderer:ssr:prepareContext", (renderContext) => { - renderContext.image = renderContext.image || {}; - renderContext.image.mapToStatic = function({ url, format }, input) { - if (!staticImages[url]) { - const { pathname } = parseURL(input); - const params = { - name: trimExt(basename(pathname)), - ext: format && `.${format}` || guessExt(input), - hash: getHash(input, url), - publicPath: nuxt.options.app.cdnURL ? "/" : withoutTrailingSlash(nuxt.options.build.publicPath) - }; - staticImages[url] = options.staticFilename.replace(/\[(\w+)]/g, (match, key) => params[key] || match); - } - return joinURL(nuxt.options.app.cdnURL || nuxt.options.app.basePath, staticImages[url]); - }; - }); - nuxt.hook("generate:done", async () => { - const limit = pLimit(8); - const downloads = Object.entries(staticImages).map(([url, name]) => { - if (!hasProtocol(url)) { - url = joinURL(options.internalUrl, url); - } - return limit(() => downloadImage({ - url, - name, - outDir: nuxt.options.generate.dir - })); - }); - await Promise.all(downloads); - }); -} -const pipeline = promisify(stream.pipeline); -async function downloadImage({ url, name, outDir }) { - try { - const response = await fetch(url); - if (!response.ok) { - throw new Error(`Unexpected response ${response.statusText}`); - } - const dstFile = join(outDir, name); - await mkdirp(dirname(dstFile)); - await pipeline(response.body, createWriteStream(dstFile)); - logger.success("Generated static image " + relative(process.cwd(), dstFile)); - } catch (error) { - logger.error(error?.message); - } -} - -const ipxSetup = async (_providerOptions, moduleOptions, nuxt) => { - const isStatic = nuxt.options.target === "static"; - const runtimeDir = resolve(__dirname, "runtime"); - const ipxOptions = { - dir: resolve(nuxt.options.rootDir, moduleOptions.dir), - domains: moduleOptions.domains, - sharp: moduleOptions.sharp, - alias: moduleOptions.alias - }; - const hasUserProvidedIPX = !!nuxt.options.serverMiddleware.find((mw) => mw.path && mw.path.startsWith("/_ipx")); - if (!hasUserProvidedIPX) { - const { createIPX, createIPXMiddleware } = await import('ipx').catch((err) => { - console.error("[@nuxt/image] `ipx` is an optional dependency for local image optimization and is not properly installed. Please try `npm install` or `yarn install` again."); - throw new Error(err); - }); - const ipx = createIPX(ipxOptions); - nuxt.options.serverMiddleware.push({ - path: "/_ipx", - handle: createIPXMiddleware(ipx) - }); - } - const installedInModules = nuxt.options.modules.some((mod) => typeof mod === "string" && mod.includes("@nuxt/image")); - if (!isStatic && !hasUserProvidedIPX && !installedInModules && lt(nuxt.constructor.version, "2.16.0")) { - console.warn("[@nuxt/image] If you would like to use the `ipx` provider at runtime.\nMake sure to follow the instructions at https://image.nuxtjs.org/providers/ipx ."); - } - if (nuxt.options.dev || hasUserProvidedIPX) { - return; - } - nuxt.hook("build:done", async () => { - const handler = await readFile(resolve(runtimeDir, "ipx.js"), "utf-8"); - const distDir = resolve(nuxt.options.buildDir, "dist"); - const apiDir = resolve(distDir, "api"); - const apiFile = resolve(apiDir, "ipx.js"); - const relativeApiFile = "~~/" + relative(nuxt.options.rootDir, apiFile); - await mkdirp(apiDir); - await writeFile(apiFile, handler.replace(/.__IPX_OPTIONS__./, JSON.stringify(ipxOptions))); - update({ serverMiddleware: [{ path: "/_ipx", handler: relativeApiFile }] }, { dir: distDir, name: "nuxtrc" }); - }); -}; - -const BuiltInProviders = [ - "cloudflare", - "cloudinary", - "contentful", - "cloudimage", - "fastly", - "glide", - "imagekit", - "gumlet", - "imgix", - "ipx", - "netlify", - "layer0", - "prismic", - "sanity", - "static", - "twicpics", - "strapi", - "storyblok", - "unsplash", - "vercel", - "imageengine" -]; -const providerSetup = { - ipx: ipxSetup, - static: ipxSetup, - async vercel(_providerOptions, moduleOptions, nuxt) { - const imagesConfig = resolve(nuxt.options.rootDir, ".vercel_build_output/config/images.json"); - await mkdirp(dirname(imagesConfig)); - await writeJson(imagesConfig, { - domains: moduleOptions.domains, - sizes: Array.from(new Set(Object.values(moduleOptions.screens || {}))) - }); - } -}; -function resolveProviders(nuxt, options) { - const providers = []; - for (const key in options) { - if (BuiltInProviders.includes(key)) { - providers.push(resolveProvider(nuxt, key, { provider: key, options: options[key] })); - } - } - for (const key in options.providers) { - providers.push(resolveProvider(nuxt, key, options.providers[key])); - } - return providers; -} -function resolveProvider(nuxt, key, input) { - if (typeof input === "string") { - input = { name: input }; - } - if (!input.name) { - input.name = key; - } - if (!input.provider) { - input.provider = input.name; - } - input.provider = BuiltInProviders.includes(input.provider) ? require.resolve("./runtime/providers/" + input.provider) : nuxt.resolver.resolvePath(input.provider); - const setup = input.setup || providerSetup[input.name]; - return { - ...input, - setup, - runtime: normalize(input.provider), - importName: `${key}Runtime$${hash(input.provider, 4)}`, - runtimeOptions: input.options - }; -} -function detectProvider(userInput, isStatic = false) { - if (process.env.NUXT_IMAGE_PROVIDER) { - return process.env.NUXT_IMAGE_PROVIDER; - } - if (userInput && userInput !== "auto") { - return userInput; - } - if (process.env.VERCEL || process.env.VERCEL_ENV || process.env.NOW_BUILDER) { - return "vercel"; - } - return isStatic ? "static" : "ipx"; -} - -const imageModule = async function imageModule2(moduleOptions) { - const { nuxt, addPlugin } = this; - const defaults = { - staticFilename: "[publicPath]/image/[hash][ext]", - provider: "auto", - presets: {}, - dir: resolve(nuxt.options.srcDir, nuxt.options.dir.static), - domains: [], - sharp: {}, - screens: { - xs: 320, - sm: 640, - md: 768, - lg: 1024, - xl: 1280, - xxl: 1536, - "2xl": 1536 - }, - internalUrl: "", - providers: {}, - static: {}, - alias: {} - }; - const options = defu(moduleOptions, nuxt.options.image, defaults); - options.domains = options.domains.map((d) => { - if (!d.startsWith("http")) { - d = "http://" + d; - } - return new URL(d).hostname; - }).filter(Boolean); - options.alias = Object.fromEntries(Object.entries(options.alias).map((e) => [withLeadingSlash(e[0]), e[1]])); - options.provider = detectProvider(options.provider, nuxt.options.target === "static"); - options[options.provider] = options[options.provider] || {}; - const imageOptions = pick(options, [ - "screens", - "presets", - "provider", - "domains", - "alias" - ]); - const providers = resolveProviders(nuxt, options); - for (const p of providers) { - if (typeof p.setup === "function") { - await p.setup(p, options, nuxt); - } - } - const runtimeDir = resolve(__dirname, "runtime"); - nuxt.options.alias["~image"] = runtimeDir; - nuxt.options.build.transpile.push(runtimeDir, "@nuxt/image", "allowlist", "defu", "ufo"); - addPlugin({ - fileName: "image.js", - src: resolve(runtimeDir, "plugin.js"), - options: { - imageOptions, - providers - } - }); - nuxt.options.build.loaders = defu({ - vue: { transformAssetUrls: { "nuxt-img": "src", "nuxt-picture": "src", NuxtPicture: "src", NuxtImg: "src" } } - }, nuxt.options.build.loaders || {}); - nuxt.hook("generate:before", () => { - setupStaticGeneration(nuxt, options); - }); - const cache = new LruCache({ max: 1e3 }); - nuxt.hook("vue-renderer:context", (ssrContext) => { - ssrContext.cache = cache; - }); - nuxt.hook("listen", (_, listener) => { - options.internalUrl = `http://localhost:${listener.port}`; - }); -}; -imageModule.meta = pkg; - -export { imageModule as default }; diff --git a/dist/runtime/components/image.mixin.d.ts b/dist/runtime/components/image.mixin.d.ts deleted file mode 100644 index 03d80996c..000000000 --- a/dist/runtime/components/image.mixin.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -export declare const imageMixin: { - nImgAttrs: { - width?: number; - height?: number; - alt?: string; - referrerpolicy?: string; - usemap?: string; - longdesc?: string; - ismap?: boolean; - crossorigin?: '' | 'anonymous' | 'use-credentials'; - loading?: string; - decoding?: 'async' | 'auto' | 'sync'; - }; - nModifiers: { - width?: number; - height?: number; - format?: string; - quality?: string | number; - background?: string; - fit?: string; - } & Record; - nOptions: { - provider?: string; - preset?: string; - }; -} & { - src: string; - format: string; - quality: string | number; - background: string; - fit: string; - modifiers: Record; - preset: string; - provider: string; - sizes: string | Record; - preload: boolean; - width: string | number; - height: string | number; - alt: string; - referrerpolicy: string; - usemap: string; - longdesc: string; - ismap: boolean; - crossorigin: boolean | "" | "anonymous" | "use-credentials"; - loading: string; - decoding: "async" | "auto" | "sync"; -} & import("vue").VueConstructor; diff --git a/dist/runtime/components/image.mixin.js b/dist/runtime/components/image.mixin.js deleted file mode 100644 index 1453cd629..000000000 --- a/dist/runtime/components/image.mixin.js +++ /dev/null @@ -1,59 +0,0 @@ -import { parseSize } from "../utils"; -const defineMixin = (opts) => opts; -export const imageMixin = defineMixin({ - props: { - src: { type: String, required: true }, - format: { type: String, default: void 0 }, - quality: { type: [Number, String], default: void 0 }, - background: { type: String, default: void 0 }, - fit: { type: String, default: void 0 }, - modifiers: { type: Object, default: void 0 }, - preset: { type: String, default: void 0 }, - provider: { type: String, default: void 0 }, - sizes: { type: [Object, String], default: void 0 }, - preload: { type: Boolean, default: void 0 }, - width: { type: [String, Number], default: void 0 }, - height: { type: [String, Number], default: void 0 }, - alt: { type: String, default: void 0 }, - referrerpolicy: { type: String, default: void 0 }, - usemap: { type: String, default: void 0 }, - longdesc: { type: String, default: void 0 }, - ismap: { type: Boolean, default: void 0 }, - crossorigin: { type: [Boolean, String], default: void 0, validator: (val) => ["anonymous", "use-credentials", "", true, false].includes(val) }, - loading: { type: String, default: void 0 }, - decoding: { type: String, default: void 0, validator: (val) => ["async", "auto", "sync"].includes(val) } - }, - computed: { - nImgAttrs() { - return { - width: parseSize(this.width), - height: parseSize(this.height), - alt: this.alt, - referrerpolicy: this.referrerpolicy, - usemap: this.usemap, - longdesc: this.longdesc, - ismap: this.ismap, - crossorigin: this.crossorigin === true ? "anonymous" : this.crossorigin || void 0, - loading: this.loading, - decoding: this.decoding - }; - }, - nModifiers() { - return { - ...this.modifiers, - width: parseSize(this.width), - height: parseSize(this.height), - format: this.format, - quality: this.quality, - background: this.background, - fit: this.fit - }; - }, - nOptions() { - return { - provider: this.provider, - preset: this.preset - }; - } - } -}); diff --git a/dist/runtime/components/nuxt-img.vue b/dist/runtime/components/nuxt-img.vue deleted file mode 100644 index b6fc4e4dc..000000000 --- a/dist/runtime/components/nuxt-img.vue +++ /dev/null @@ -1,92 +0,0 @@ - - - diff --git a/dist/runtime/components/nuxt-img.vue.d.ts b/dist/runtime/components/nuxt-img.vue.d.ts deleted file mode 100644 index 96acf717f..000000000 --- a/dist/runtime/components/nuxt-img.vue.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { ImageSizes } from '../../types'; -import { imageMixin } from './image.mixin'; -declare type NAttrs = typeof imageMixin['nImgAttrs'] & { - sizes?: string; - srcset?: string; -}; -declare const _default: import("vue/types/vue").ExtendedVue; -export default _default; diff --git a/dist/runtime/components/nuxt-picture.vue b/dist/runtime/components/nuxt-picture.vue deleted file mode 100644 index 516bde5c0..000000000 --- a/dist/runtime/components/nuxt-picture.vue +++ /dev/null @@ -1,105 +0,0 @@ - - - diff --git a/dist/runtime/components/nuxt-picture.vue.d.ts b/dist/runtime/components/nuxt-picture.vue.d.ts deleted file mode 100644 index 3236333ac..000000000 --- a/dist/runtime/components/nuxt-picture.vue.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -declare const _default: import("vue/types/vue").ExtendedVue; -export default _default; diff --git a/dist/runtime/image.d.ts b/dist/runtime/image.d.ts deleted file mode 100644 index d5b2a1227..000000000 --- a/dist/runtime/image.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { CreateImageOptions, $Img } from '../types/image'; -export declare function createImage(globalOptions: CreateImageOptions, nuxtContext: any): $Img; diff --git a/dist/runtime/image.js b/dist/runtime/image.js deleted file mode 100644 index 8397eeb2c..000000000 --- a/dist/runtime/image.js +++ /dev/null @@ -1,182 +0,0 @@ -import defu from "defu"; -import { hasProtocol, parseURL, joinURL, withLeadingSlash } from "ufo"; -import { imageMeta } from "./utils/meta"; -import { parseSize } from "./utils"; -import { useStaticImageMap } from "./utils/static-map"; -export function createImage(globalOptions, nuxtContext) { - const staticImageManifest = process.client && process.static ? useStaticImageMap(nuxtContext) : {}; - const ctx = { - options: globalOptions, - nuxtContext - }; - const getImage = function(input, options = {}) { - const image = resolveImage(ctx, input, options); - if (image.isStatic) { - handleStaticImage(image, input); - } - return image; - }; - const $img = function $img2(input, modifiers = {}, options = {}) { - return getImage(input, { - ...options, - modifiers: defu(modifiers, options.modifiers || {}) - }).url; - }; - function handleStaticImage(image, input) { - if (process.static) { - if (process.client && "fetchPayload" in window.$nuxt) { - const mappedURL = staticImageManifest[image.url]; - image.url = mappedURL || input; - return image; - } - if (process.server) { - const { ssrContext } = ctx.nuxtContext; - if (ssrContext) { - const ssrState = ssrContext.nuxt || {}; - const staticImages = ssrState._img = ssrState._img || {}; - const ssrData = ssrState.data?.[0]; - if (ssrData) { - ssrData._img = staticImages; - } - const mapToStatic = ssrContext.image?.mapToStatic; - if (typeof mapToStatic === "function") { - const mappedURL = mapToStatic(image, input); - if (mappedURL) { - staticImages[image.url] = mappedURL; - image.url = mappedURL; - } - } - } - } - } else if (process.env.NODE_ENV === "production") { - image.url = input; - } - } - for (const presetName in globalOptions.presets) { - $img[presetName] = (source, modifiers, options) => $img(source, modifiers, { ...globalOptions.presets[presetName], ...options }); - } - $img.options = globalOptions; - $img.getImage = getImage; - $img.getMeta = (input, options) => getMeta(ctx, input, options); - $img.getSizes = (input, options) => getSizes(ctx, input, options); - ctx.$img = $img; - return $img; -} -async function getMeta(ctx, input, options) { - const image = resolveImage(ctx, input, { ...options }); - if (typeof image.getMeta === "function") { - return await image.getMeta(); - } else { - return await imageMeta(ctx, image.url); - } -} -function resolveImage(ctx, input, options) { - if (typeof input !== "string" || input === "") { - throw new TypeError(`input must be a string (received ${typeof input}: ${JSON.stringify(input)})`); - } - if (input.startsWith("data:")) { - return { - url: input - }; - } - const { provider, defaults } = getProvider(ctx, options.provider || ctx.options.provider); - const preset = getPreset(ctx, options.preset); - input = hasProtocol(input) ? input : withLeadingSlash(input); - if (!provider.supportsAlias) { - for (const base in ctx.options.alias) { - if (input.startsWith(base)) { - input = joinURL(ctx.options.alias[base], input.substr(base.length)); - } - } - } - if (provider.validateDomains && hasProtocol(input)) { - const inputHost = parseURL(input).host; - if (!ctx.options.domains.find((d) => d === inputHost)) { - return { - url: input - }; - } - } - const _options = defu(options, preset, defaults); - _options.modifiers = { ..._options.modifiers }; - const expectedFormat = _options.modifiers.format; - if (_options.modifiers?.width) { - _options.modifiers.width = parseSize(_options.modifiers.width); - } - if (_options.modifiers?.height) { - _options.modifiers.height = parseSize(_options.modifiers.height); - } - const image = provider.getImage(input, _options, ctx); - image.format = image.format || expectedFormat || ""; - return image; -} -function getProvider(ctx, name) { - const provider = ctx.options.providers[name]; - if (!provider) { - throw new Error("Unknown provider: " + name); - } - return provider; -} -function getPreset(ctx, name) { - if (!name) { - return {}; - } - if (!ctx.options.presets[name]) { - throw new Error("Unknown preset: " + name); - } - return ctx.options.presets[name]; -} -function getSizes(ctx, input, opts) { - const width = parseSize(opts.modifiers?.width); - const height = parseSize(opts.modifiers?.height); - const hwRatio = width && height ? height / width : 0; - const variants = []; - const sizes = {}; - if (typeof opts.sizes === "string") { - for (const entry of opts.sizes.split(/[\s,]+/).filter((e) => e)) { - const s = entry.split(":"); - if (s.length !== 2) { - continue; - } - sizes[s[0].trim()] = s[1].trim(); - } - } else { - Object.assign(sizes, opts.sizes); - } - for (const key in sizes) { - const screenMaxWidth = ctx.options.screens && ctx.options.screens[key] || parseInt(key); - let size = String(sizes[key]); - const isFluid = size.endsWith("vw"); - if (!isFluid && /^\d+$/.test(size)) { - size = size + "px"; - } - if (!isFluid && !size.endsWith("px")) { - continue; - } - let _cWidth = parseInt(size); - if (!screenMaxWidth || !_cWidth) { - continue; - } - if (isFluid) { - _cWidth = Math.round(_cWidth / 100 * screenMaxWidth); - } - const _cHeight = hwRatio ? Math.round(_cWidth * hwRatio) : height; - variants.push({ - width: _cWidth, - size, - screenMaxWidth, - media: `(max-width: ${screenMaxWidth}px)`, - src: ctx.$img(input, { ...opts.modifiers, width: _cWidth, height: _cHeight }, opts) - }); - } - variants.sort((v1, v2) => v1.screenMaxWidth - v2.screenMaxWidth); - const defaultVar = variants[variants.length - 1]; - if (defaultVar) { - defaultVar.media = ""; - } - return { - sizes: variants.map((v) => `${v.media ? v.media + " " : ""}${v.size}`).join(", "), - srcset: variants.map((v) => `${v.src} ${v.width}w`).join(", "), - src: defaultVar?.src - }; -} diff --git a/dist/runtime/index.d.ts b/dist/runtime/index.d.ts deleted file mode 100644 index 7f0709662..000000000 --- a/dist/runtime/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './image'; -export * from './utils'; diff --git a/dist/runtime/index.js b/dist/runtime/index.js deleted file mode 100644 index 8895cfd07..000000000 --- a/dist/runtime/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./image"; -export * from "./utils"; diff --git a/dist/runtime/ipx.d.ts b/dist/runtime/ipx.d.ts deleted file mode 100644 index 16b6ea93f..000000000 --- a/dist/runtime/ipx.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -/// -declare const _default: (req: import("http").IncomingMessage, res: import("http").ServerResponse) => void; -export default _default; diff --git a/dist/runtime/ipx.js b/dist/runtime/ipx.js deleted file mode 100644 index 5da24f0ed..000000000 --- a/dist/runtime/ipx.js +++ /dev/null @@ -1,3 +0,0 @@ -import { createIPX, createIPXMiddleware } from "ipx"; -const ipx = createIPX("__IPX_OPTIONS__"); -export default createIPXMiddleware(ipx); diff --git a/dist/runtime/plugin.d.ts b/dist/runtime/plugin.d.ts deleted file mode 100644 index b8c0cf786..000000000 --- a/dist/runtime/plugin.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function _default(nuxtContext: any, inject: any): void; diff --git a/dist/runtime/plugin.js b/dist/runtime/plugin.js deleted file mode 100644 index 4e361c6bb..000000000 --- a/dist/runtime/plugin.js +++ /dev/null @@ -1,31 +0,0 @@ -import Vue from 'vue' -import { createImage} from '~image' -import NuxtImg from '~image/components/nuxt-img.vue' -import NuxtPicture from '~image/components/nuxt-picture.vue' - -<%=options.providers.map(p => `import * as ${p.importName} from '${p.runtime}'`).join('\n')%> - -const imageOptions = <%= JSON.stringify(options.imageOptions, null, 2) %> - -imageOptions.providers = { -<%=options.providers.map(p => ` ['${p.name}']: { provider: ${p.importName}, defaults: ${JSON.stringify(p.runtimeOptions)} }`).join(',\n') %> -} - - -Vue.component(NuxtImg.name, NuxtImg) -Vue.component(NuxtPicture.name, NuxtPicture) -Vue.component('NImg', NuxtImg) -Vue.component('NPicture', NuxtPicture) - -export default function (nuxtContext, inject) { - const $img = createImage(imageOptions, nuxtContext) - - if (process.static && process.server) { - nuxtContext.beforeNuxtRender(({ nuxtState }) => { - const ssrData = nuxtState.data[0] || {} - ssrData._img = nuxtState._img || {} - }) - } - - inject('img', $img) -} diff --git a/dist/runtime/providers/cloudflare.d.ts b/dist/runtime/providers/cloudflare.d.ts deleted file mode 100644 index 12489337f..000000000 --- a/dist/runtime/providers/cloudflare.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/cloudflare.js b/dist/runtime/providers/cloudflare.js deleted file mode 100644 index 5906ef6e7..000000000 --- a/dist/runtime/providers/cloudflare.js +++ /dev/null @@ -1,41 +0,0 @@ -import { joinURL, encodeQueryItem } from "ufo"; -import { createOperationsGenerator } from "~image"; -const operationsGenerator = createOperationsGenerator({ - keyMap: { - width: "w", - height: "h", - dpr: "dpr", - fit: "fit", - gravity: "g", - quality: "q", - format: "f", - sharpen: "sharpen" - }, - valueMap: { - fit: { - cover: "cover", - contain: "contain", - fill: "scale-down", - outside: "crop", - inside: "pad" - }, - gravity: { - auto: "auto", - side: "side" - } - }, - joinWith: ",", - formatter: (key, val) => encodeQueryItem(key, val) -}); -const defaultModifiers = {}; -export const getImage = (src, { - modifiers = {}, - baseURL = "/" -} = {}) => { - const mergeModifiers = { ...defaultModifiers, ...modifiers }; - const operations = operationsGenerator(mergeModifiers); - const url = operations ? joinURL(baseURL, "cdn-cgi/image", operations, src) : joinURL(baseURL, src); - return { - url - }; -}; diff --git a/dist/runtime/providers/cloudimage.d.ts b/dist/runtime/providers/cloudimage.d.ts deleted file mode 100644 index d07bf64e2..000000000 --- a/dist/runtime/providers/cloudimage.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/cloudimage.js b/dist/runtime/providers/cloudimage.js deleted file mode 100644 index 4c0b4ebb1..000000000 --- a/dist/runtime/providers/cloudimage.js +++ /dev/null @@ -1,34 +0,0 @@ -import { joinURL } from "ufo"; -import { createOperationsGenerator } from "~image"; -const operationsGenerator = createOperationsGenerator({ - keyMap: { - fit: "func", - quality: "q", - format: "force_format" - }, - valueMap: { - fit: { - cover: "crop", - contain: "fit", - fill: "cover", - inside: "bound", - outside: "boundmin" - } - }, - joinWith: "&", - formatter: (key, value) => `${key}=${value}` -}); -export const getImage = (src, { - modifiers = {}, - baseURL = "", - token = "demo", - cdnURL = "" -} = {}) => { - const operations = operationsGenerator(modifiers); - if (!cdnURL) { - cdnURL = `https://${token}.cloudimg.io/v7`; - } - return { - url: joinURL(cdnURL, baseURL, src) + (operations ? "?" + operations : "") - }; -}; diff --git a/dist/runtime/providers/cloudinary.d.ts b/dist/runtime/providers/cloudinary.d.ts deleted file mode 100644 index d07bf64e2..000000000 --- a/dist/runtime/providers/cloudinary.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/cloudinary.js b/dist/runtime/providers/cloudinary.js deleted file mode 100644 index 81437ce45..000000000 --- a/dist/runtime/providers/cloudinary.js +++ /dev/null @@ -1,96 +0,0 @@ -import { joinURL, encodePath } from "ufo"; -import defu from "defu"; -import { createOperationsGenerator } from "~image"; -const convertHextoRGBFormat = (value) => value.startsWith("#") ? value.replace("#", "rgb_") : value; -const removePathExtension = (value) => value.replace(/\.[^/.]+$/, ""); -const operationsGenerator = createOperationsGenerator({ - keyMap: { - fit: "c", - width: "w", - height: "h", - format: "f", - quality: "q", - background: "b", - rotate: "a", - roundCorner: "r", - gravity: "g", - effect: "e", - color: "co", - flags: "fl", - dpr: "dpr", - opacity: "o", - overlay: "l", - underlay: "u", - transformation: "t", - zoom: "z", - colorSpace: "cs", - customFunc: "fn", - density: "dpi" - }, - valueMap: { - fit: { - fill: "fill", - inside: "pad", - outside: "lpad", - cover: "fit", - contain: "scale", - minCover: "mfit", - minInside: "mpad", - thumbnail: "thumb", - cropping: "crop", - coverLimit: "limit" - }, - format: { - jpeg: "jpg" - }, - background(value) { - return convertHextoRGBFormat(value); - }, - color(value) { - return convertHextoRGBFormat(value); - }, - gravity: { - auto: "auto", - subject: "auto:subject", - face: "face", - sink: "sink", - faceCenter: "face:center", - multipleFaces: "faces", - multipleFacesCenter: "faces:center", - north: "north", - northEast: "north_east", - northWest: "north_west", - west: "west", - southWest: "south_west", - south: "south", - southEast: "south_east", - east: "east", - center: "center" - } - }, - joinWith: ",", - formatter: (key, value) => `${key}_${value}` -}); -const defaultModifiers = { - format: "auto", - quality: "auto" -}; -export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { - const mergeModifiers = defu(modifiers, defaultModifiers); - const operations = operationsGenerator(mergeModifiers); - const remoteFolderMapping = baseURL.match(/\/image\/upload\/(.*)/); - if (remoteFolderMapping?.length >= 1) { - const remoteFolder = remoteFolderMapping[1]; - const baseURLWithoutRemoteFolder = baseURL.replace(remoteFolder, ""); - return { - url: joinURL(baseURLWithoutRemoteFolder, operations, remoteFolder, src) - }; - } else if (/\/image\/fetch\/?/.test(baseURL)) { - src = encodePath(src); - } else { - src = removePathExtension(src); - } - return { - url: joinURL(baseURL, operations, src) - }; -}; diff --git a/dist/runtime/providers/contentful.d.ts b/dist/runtime/providers/contentful.d.ts deleted file mode 100644 index e4f818101..000000000 --- a/dist/runtime/providers/contentful.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const operationsGenerator: any; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/contentful.js b/dist/runtime/providers/contentful.js deleted file mode 100644 index c77864b14..000000000 --- a/dist/runtime/providers/contentful.js +++ /dev/null @@ -1,36 +0,0 @@ -import { withBase, parseURL } from "ufo"; -import { createOperationsGenerator } from "~image"; -const contentfulCDN = "https://images.ctfassets.net"; -export const operationsGenerator = createOperationsGenerator({ - keyMap: { - format: "fm", - width: "w", - height: "h", - focus: "f", - radius: "r", - quality: "q", - background: "bg" - }, - valueMap: { - format: { - jpeg: "jpg" - }, - fit: { - cover: "crop", - contain: "fill", - fill: "scale", - thumbnail: "thumb" - } - }, - joinWith: "&", - formatter: (key, value) => `${key}=${value}` -}); -export const getImage = (src, { modifiers = {}, baseURL = contentfulCDN } = {}) => { - const operations = operationsGenerator(modifiers); - const { pathname } = parseURL(src); - const path = pathname + (operations ? "?" + operations : ""); - const url = withBase(path, baseURL); - return { - url - }; -}; diff --git a/dist/runtime/providers/fastly.d.ts b/dist/runtime/providers/fastly.d.ts deleted file mode 100644 index d07bf64e2..000000000 --- a/dist/runtime/providers/fastly.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/fastly.js b/dist/runtime/providers/fastly.js deleted file mode 100644 index 5e5f27ce4..000000000 --- a/dist/runtime/providers/fastly.js +++ /dev/null @@ -1,21 +0,0 @@ -import { joinURL } from "ufo"; -import { createOperationsGenerator } from "~image"; -const operationsGenerator = createOperationsGenerator({ - valueMap: { - fit: { - fill: "crop", - inside: "crop", - outside: "crop", - cover: "bounds", - contain: "bounds" - } - }, - joinWith: "&", - formatter: (key, value) => `${key}=${value}` -}); -export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { - const operations = operationsGenerator(modifiers); - return { - url: joinURL(baseURL, src + (operations ? "?" + operations : "")) - }; -}; diff --git a/dist/runtime/providers/glide.d.ts b/dist/runtime/providers/glide.d.ts deleted file mode 100644 index 12489337f..000000000 --- a/dist/runtime/providers/glide.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/glide.js b/dist/runtime/providers/glide.js deleted file mode 100644 index 538a701dc..000000000 --- a/dist/runtime/providers/glide.js +++ /dev/null @@ -1,49 +0,0 @@ -import { joinURL, encodeQueryItem, encodePath, withBase } from "ufo"; -import { createOperationsGenerator } from "~image"; -const operationsGenerator = createOperationsGenerator({ - keyMap: { - orientation: "or", - flip: "flip", - crop: "crop", - width: "w", - height: "h", - fit: "fit", - dpr: "dpr", - bri: "bri", - con: "con", - gam: "gam", - sharp: "sharp", - blur: "blur", - pixel: "pixel", - filt: "filt", - mark: "mark", - markw: "markw", - markh: "markh", - markx: "markx", - marky: "marky", - markpad: "markpad", - markpos: "markpos", - markalpha: "markalpha", - background: "bg", - border: "border", - quality: "q", - format: "fm" - }, - valueMap: { - fit: { - fill: "fill", - inside: "max", - outside: "stretch", - cover: "crop", - contain: "contain" - } - }, - joinWith: "&", - formatter: (key, val) => encodeQueryItem(key, val) -}); -export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { - const params = operationsGenerator(modifiers); - return { - url: withBase(joinURL(encodePath(src) + (params ? "?" + params : "")), baseURL) - }; -}; diff --git a/dist/runtime/providers/gumlet.d.ts b/dist/runtime/providers/gumlet.d.ts deleted file mode 100644 index e4f818101..000000000 --- a/dist/runtime/providers/gumlet.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const operationsGenerator: any; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/gumlet.js b/dist/runtime/providers/gumlet.js deleted file mode 100644 index e1bf6ef06..000000000 --- a/dist/runtime/providers/gumlet.js +++ /dev/null @@ -1,75 +0,0 @@ -import { joinURL } from "ufo"; -import { createOperationsGenerator } from "~image"; -export const operationsGenerator = createOperationsGenerator({ - keyMap: { - width: "w", - height: "h", - format: "format", - quality: "q", - backgroundColor: "bg", - rotate: "rot", - mask: "mask", - auto: "auto", - crop: "crop", - brightness: "bri", - contrast: "con", - exposure: "exp", - gamma: "gam", - highlight: "high", - hueShift: "hue", - invert: "invert", - saturation: "sat", - sharpen: "sharp", - padding: "pad", - paletteColorCount: "colors", - colorPaletteExtraction: "palette", - cssPrefix: "prefix", - jsonFaceData: "faces", - fillMode: "fill", - fillColor: "fill-color", - transparency: "transparency", - focalPointDebug: "fp-debug", - focalPointXPosition: "fp-x", - focalPointYPosition: "fp-y", - focalPointZoom: "fp-z", - chromaSubsampling: "chromasub", - colorQuantization: "colorquant", - colorSpace: "colorspace", - dotsPerInch: "dpi", - pdfPageNumber: "page", - pixelDensity: "dpr", - aspectRatio: "ar", - sourceRectangleRegion: "rect", - monochrome: "monochrome" - }, - valueMap: { - fit: { - fill: "scale", - inside: "max", - outside: "min", - cover: "crop", - contain: "fill", - clamp: "clamp", - clip: "clip", - facearea: "facearea", - fillMax: "fillmax" - }, - format: { - gif: "gif", - jpg: "jpg", - json: "json", - png: "png", - avif: "avif", - webp: "webp", - auto: "auto" - } - }, - joinWith: "&", - formatter: (key, value) => `${key}=${value}` -}); -export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { - const operations = operationsGenerator(modifiers); - return { - url: joinURL(baseURL, src + (operations ? "?" + operations : "")) - }; -}; diff --git a/dist/runtime/providers/imageengine.d.ts b/dist/runtime/providers/imageengine.d.ts deleted file mode 100644 index e4f818101..000000000 --- a/dist/runtime/providers/imageengine.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const operationsGenerator: any; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/imageengine.js b/dist/runtime/providers/imageengine.js deleted file mode 100644 index 58dc4aa5c..000000000 --- a/dist/runtime/providers/imageengine.js +++ /dev/null @@ -1,45 +0,0 @@ -import { joinURL } from "ufo"; -import { createOperationsGenerator } from "~image"; -export const operationsGenerator = createOperationsGenerator({ - keyMap: { - width: "w", - height: "h", - quality: "cmpr", - format: "f", - fit: "m", - passThrough: "pass", - sharpen: "s", - rotate: "r", - screenPercent: "pc", - crop: "cr", - inline: "in", - metadata: "meta" - }, - valueMap: { - fit: { - cover: "cropbox", - contain: "letterbox", - fill: "stretch", - inside: "box", - outside: "box" - }, - format: { - jpeg: "jpg" - }, - quality(value) { - let compression = 100 - parseInt(value, 10); - if (compression === 100) { - compression = 99; - } - return compression.toString(); - } - }, - joinWith: "/", - formatter: (key, value) => `${key}_${value}` -}); -export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { - const operations = operationsGenerator(modifiers); - return { - url: joinURL(baseURL, src + (operations ? "?imgeng=/" + operations : "")) - }; -}; diff --git a/dist/runtime/providers/imagekit.d.ts b/dist/runtime/providers/imagekit.d.ts deleted file mode 100644 index d07bf64e2..000000000 --- a/dist/runtime/providers/imagekit.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/imagekit.js b/dist/runtime/providers/imagekit.js deleted file mode 100644 index e10a7e67e..000000000 --- a/dist/runtime/providers/imagekit.js +++ /dev/null @@ -1,172 +0,0 @@ -import { joinURL } from "ufo"; -import { createOperationsGenerator } from "~image"; -const operationsGenerator = createOperationsGenerator({ - keyMap: { - fit: "c", - width: "w", - height: "h", - format: "f", - quality: "q", - bg: "bg", - background: "bg", - crop: "c", - cropMode: "cm", - aspectRatio: "ar", - x: "x", - y: "y", - xc: "xc", - yc: "yc", - oix: "oix", - oiy: "oiy", - oixc: "oixc", - oiyc: "oiyc", - focus: "fo", - radius: "r", - border: "b", - rotate: "rt", - blur: "bl", - named: "n", - overlayX: "ox", - overlayY: "oy", - overlayFocus: "ofo", - overlayHeight: "oh", - overlayWidth: "ow", - overlayImage: "oi", - overlayImageTrim: "oit", - overlayImageAspectRatio: "oiar", - overlayImageBackground: "oibg", - overlayImageBorder: "oib", - overlayImageDPR: "oidpr", - overlayImageQuality: "oiq", - overlayImageCropping: "oic", - overlayImageCropMode: "oicm", - overlayText: "ot", - overlayTextFontSize: "ots", - overlayTextFontFamily: "otf", - overlayTextColor: "otc", - overlayTextTransparency: "oa", - overlayTextTypography: "ott", - overlayBackground: "obg", - overlayTextEncoded: "ote", - overlayTextWidth: "otw", - overlayTextBackground: "otbg", - overlayTextPadding: "otp", - overlayTextInnerAlignment: "otia", - overlayRadius: "or", - progressive: "pr", - lossless: "lo", - trim: "t", - metadata: "md", - colorProfile: "cp", - defaultImage: "di", - dpr: "dpr", - effectSharpen: "e-sharpen", - effectUSM: "e-usm", - effectContrast: "e-contrast", - effectGray: "e-grayscale", - original: "orig" - }, - valueMap: { - fit: { - cover: "maintain_ratio", - contain: "pad_resize", - fill: "force", - inside: "at_max", - outside: "at_least", - extract: "extract", - pad_extract: "pad_extract" - }, - background(value) { - if (value.startsWith("#")) { - return value.replace("#", ""); - } - return value; - }, - crop: { - maintain_ratio: "maintain_ratio", - force: "force", - at_max: "at_max", - at_least: "at_least" - }, - cropMode: { - pad_resize: "pad_resize", - pad_extract: "pad_extract", - extract: "extract" - }, - format: { - auto: "auto", - jpg: "jpg", - jpeg: "jpeg", - webp: "webp", - avif: "avif", - png: "png" - }, - focus: { - left: "left", - right: "right", - top: "top", - bottom: "bottom", - custom: "custom", - center: "center", - top_left: "top_left", - top_right: "top_right", - bottom_left: "bottom_left", - bottom_right: "bottom_right", - auto: "auto", - face: "face" - }, - rotate: { - auto: "auto", - 0: "0", - 90: "90", - 180: "180", - 270: "270", - 360: "360" - }, - overlayFocus: { - left: "left", - right: "right", - top: "top", - bottom: "bottom", - custom: "custom", - center: "center", - top_left: "top_left", - top_right: "top_right", - bottom_left: "bottom_left", - bottom_right: "bottom_right", - auto: "auto", - face: "face" - }, - overlayImageCropping: { - maintain_ratio: "maintain_ratio", - force: "force", - at_max: "at_max", - at_least: "at_least" - }, - overlayImageCropMode: { - pad_resize: "pad_resize", - pad_extract: "pad_extract", - extract: "extract" - }, - overlayTextTypography: { - b: "b", - i: "i" - }, - overlayTextInnerAlignment: { - left: "left", - right: "right", - center: "center" - } - }, - joinWith: ",", - formatter: (key, value) => `${key}-${value}` -}); -export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { - let operations = operationsGenerator(modifiers); - operations = operations.replace("c-pad_resize", "cm-pad_resize"); - operations = operations.replace("c-pad_extract", "cm-pad_extract"); - operations = operations.replace("c-extract", "cm-extract"); - return { - url: joinURL(baseURL, src + (operations ? `?tr=${operations}` : "")) - }; -}; diff --git a/dist/runtime/providers/imgix.d.ts b/dist/runtime/providers/imgix.d.ts deleted file mode 100644 index e4f818101..000000000 --- a/dist/runtime/providers/imgix.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const operationsGenerator: any; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/imgix.js b/dist/runtime/providers/imgix.js deleted file mode 100644 index ba19b6e01..000000000 --- a/dist/runtime/providers/imgix.js +++ /dev/null @@ -1,168 +0,0 @@ -import { joinURL } from "ufo"; -import { createOperationsGenerator } from "~image"; -export const operationsGenerator = createOperationsGenerator({ - keyMap: { - width: "w", - height: "h", - format: "fm", - quality: "q", - backgroundColor: "bg", - rotate: "rot", - mask: "mask", - auto: "auto", - crop: "crop", - brightness: "bri", - contrast: "con", - exposure: "exp", - gamma: "gam", - highlight: "high", - hueShift: "hue", - invert: "invert", - saturation: "sat", - shadow: "shad", - sharpen: "sharp", - unsharpMask: "usm", - unsharpMaskRadius: "usmrad", - vibrance: "vib", - blend: "blend", - blendAlign: "blend-align", - blendAlpha: "blend-alpha", - blendColor: "blend-color", - blendCrop: "blend-crop", - blendFit: "blend-fit", - blendHeight: "blend-h", - blendMode: "blend-mode", - blendPadding: "blend-pad", - blendSize: "blend-size", - blendWidth: "blend-w", - blendXPosition: "blend-x", - blendYPosition: "blend-y", - padding: "pad", - borderBottom: "border-bottom", - borderLeft: "border-left", - innerBorderRadius: "border-radius-inner", - outerBorderRadius: "border-radius", - borderRight: "border-right", - borderTop: "border-top", - borderSizeColor: "border", - paddingBottom: "pad-bottom", - paddingLeft: "pad-left", - paddingRight: "pad-right", - paddingTop: "pad-top", - paletteColorCount: "colors", - colorPaletteExtraction: "palette", - cssPrefix: "prefix", - expirationTimestamp: "expires", - faceIndex: "faceindex", - facePadding: "facepad", - jsonFaceData: "faces", - fillMode: "fill", - fillColor: "fill-color", - gridColors: "grid-colors", - gridSize: "grid-size", - transparency: "transparency", - focalPointDebug: "fp-debug", - focalPointXPosition: "fp-x", - focalPointYPosition: "fp-y", - focalPointZoom: "fp-z", - clientHints: "ch", - chromaSubsampling: "chromasub", - colorQuantization: "colorquant", - colorSpace: "cs", - download: "dl", - dotsPerInch: "dpi", - losslessCompression: "lossless", - maskBackgroundColor: "mask-bg", - maskCornerRadius: "corner-radius", - noiseReductionSharp: "nrs", - noiseReductionBound: "nr", - pdfPageNumber: "page", - pdfAnnotation: "pdf-annotation", - pixelDensity: "dpr", - orientation: "orient", - flipAxis: "flip", - aspectRatio: "ar", - maximumHeight: "max-h", - maximumWidth: "max-w", - minimumHeight: "min-h", - minimumWidth: "min-w", - sourceRectangleRegion: "rect", - gaussianBlur: "blur", - duotoneAlpha: "duotone-alpha", - duotone: "duotone", - halftone: "htn", - monochrome: "monochrome", - pixellate: "px", - sepiaTone: "sepia", - textAlign: "txt-align", - textClippingMode: "txt-clip", - textColor: "txt-color", - textFitMode: "txt-fit", - textFont: "txt-font", - textLigatures: "txt-lig", - textOutlineColor: "txt-line-color", - textOutline: "txt-line", - textPadding: "txt-pad", - textShadow: "txt-shad", - textFontSize: "txt-size", - textWidth: "txt-width", - textString: "txt", - trimColor: "trim-color", - trimMeanDifference: "trim-md", - trimStandardDeviation: "trim-sd", - trimTolerance: "trim-tol", - trimImage: "trim", - textLeading: "txt-lead", - textTracking: "txt-track", - typesettingEndpoint: "~text", - watermarkAlignment: "mark-align", - watermarkAlpha: "mark-alpha", - watermarkBaseURL: "mark-base", - watermarkFitMode: "mark-fit", - watermarkHeight: "mark-h", - watermarkPadding: "mark-pad", - watermarkRotation: "mark-rot", - watermarkScale: "mark-sclae", - watermarkTile: "mark-tile", - watermarkWidth: "mark-w", - watermarkXPosition: "mark-x", - watermarkYPosition: "mark-y", - watermarkImageURL: "mark" - }, - valueMap: { - fit: { - fill: "scale", - inside: "max", - outside: "min", - cover: "crop", - contain: "fill", - clamp: "clamp", - clip: "clip", - facearea: "facearea", - fillMax: "fillmax" - }, - format: { - gif: "gif", - jp2: "jp2", - jpg: "jpg", - json: "json", - jxr: "jxr", - pjpg: "pjpg", - mp4: "mp4", - png: "png", - png8: "png8", - png32: "png32", - webm: "webm", - webp: "webp", - blurhash: "blurhash" - } - }, - joinWith: "&", - formatter: (key, value) => `${key}=${value}` -}); -export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { - const operations = operationsGenerator(modifiers); - return { - url: joinURL(baseURL, src + (operations ? "?" + operations : "")) - }; -}; diff --git a/dist/runtime/providers/ipx.d.ts b/dist/runtime/providers/ipx.d.ts deleted file mode 100644 index 65e2e1d38..000000000 --- a/dist/runtime/providers/ipx.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; -export declare const validateDomains = true; -export declare const supportsAlias = true; diff --git a/dist/runtime/providers/ipx.js b/dist/runtime/providers/ipx.js deleted file mode 100644 index f25d6030a..000000000 --- a/dist/runtime/providers/ipx.js +++ /dev/null @@ -1,31 +0,0 @@ -import { joinURL, encodePath, encodeParam } from "ufo"; -import { createOperationsGenerator } from "~image"; -const operationsGenerator = createOperationsGenerator({ - keyMap: { - format: "f", - fit: "fit", - width: "w", - height: "h", - resize: "s", - quality: "q", - background: "b" - }, - joinWith: ",", - formatter: (key, val) => encodeParam(key) + "_" + encodeParam(val) -}); -export const getImage = (src, { modifiers = {}, baseURL } = {}, ctx) => { - if (modifiers.width && modifiers.height) { - modifiers.resize = `${modifiers.width}x${modifiers.height}`; - delete modifiers.width; - delete modifiers.height; - } - const params = operationsGenerator(modifiers) || "_"; - if (!baseURL) { - baseURL = joinURL(ctx.nuxtContext?.base || "/", "/_ipx"); - } - return { - url: joinURL(baseURL, params, encodePath(src)) - }; -}; -export const validateDomains = true; -export const supportsAlias = true; diff --git a/dist/runtime/providers/layer0.d.ts b/dist/runtime/providers/layer0.d.ts deleted file mode 100644 index d07bf64e2..000000000 --- a/dist/runtime/providers/layer0.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/layer0.js b/dist/runtime/providers/layer0.js deleted file mode 100644 index 723ea91cb..000000000 --- a/dist/runtime/providers/layer0.js +++ /dev/null @@ -1,20 +0,0 @@ -import { joinURL } from "ufo"; -import { createOperationsGenerator } from "~image"; -const operationsGenerator = createOperationsGenerator({ - keyMap: { - height: "height", - quality: "quality", - width: "width" - }, - joinWith: "&", - formatter: (key, value) => String(value) === "true" ? key : `${key}=${value}` -}); -export const getImage = (src, { - modifiers = {}, - baseURL = "https://opt.moovweb.net" -} = {}) => { - const operations = operationsGenerator(modifiers); - return { - url: joinURL(baseURL, "?img=" + src + (operations ? "&" + operations : "")) - }; -}; diff --git a/dist/runtime/providers/netlify.d.ts b/dist/runtime/providers/netlify.d.ts deleted file mode 100644 index e4f818101..000000000 --- a/dist/runtime/providers/netlify.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const operationsGenerator: any; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/netlify.js b/dist/runtime/providers/netlify.js deleted file mode 100644 index fffd07535..000000000 --- a/dist/runtime/providers/netlify.js +++ /dev/null @@ -1,40 +0,0 @@ -import { joinURL } from "ufo"; -import { createOperationsGenerator } from "~image"; -export const operationsGenerator = createOperationsGenerator({ - keyMap: { - height: "h", - fit: "nf_resize", - width: "w" - }, - valueMap: { - fit: { - fill: "smartcrop", - contain: "fit" - } - }, - joinWith: "&", - formatter: (key, value) => `${key}=${value}` -}); -const isDev = process.env.NODE_ENV === "development"; -export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { - if (modifiers.format) { - delete modifiers.format; - } - const hasTransformation = modifiers.height || modifiers.width; - if (!modifiers.fit && hasTransformation) { - modifiers.fit = "contain"; - } - if (hasTransformation && modifiers.fit !== "contain" && !(modifiers.height && modifiers.width)) { - if (isDev) { - console.warn(`Defaulting to fit=contain as smart cropping is only supported when providing both height and width. Warning originated from \`${src}\`.`); - } - modifiers.fit = "contain"; - } - if (isDev) { - return { url: src }; - } - const operations = operationsGenerator(modifiers); - return { - url: joinURL(baseURL, src + (operations ? "?" + operations : "")) - }; -}; diff --git a/dist/runtime/providers/prismic.d.ts b/dist/runtime/providers/prismic.d.ts deleted file mode 100644 index d07bf64e2..000000000 --- a/dist/runtime/providers/prismic.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/prismic.js b/dist/runtime/providers/prismic.js deleted file mode 100644 index 84d1091c9..000000000 --- a/dist/runtime/providers/prismic.js +++ /dev/null @@ -1,10 +0,0 @@ -import { joinURL, parseQuery, parseURL, stringifyQuery } from "ufo"; -import { operationsGenerator } from "./imgix"; -const PRISMIC_IMGIX_BUCKET = "https://images.prismic.io"; -export const getImage = (src, { modifiers = {}, baseURL = PRISMIC_IMGIX_BUCKET } = {}) => { - const operations = operationsGenerator(modifiers); - const parsedURL = parseURL(src); - return { - url: joinURL(baseURL, parsedURL.pathname + "?" + stringifyQuery(Object.assign(parseQuery(parsedURL.search), parseQuery(operations)))) - }; -}; diff --git a/dist/runtime/providers/sanity.d.ts b/dist/runtime/providers/sanity.d.ts deleted file mode 100644 index d07bf64e2..000000000 --- a/dist/runtime/providers/sanity.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/sanity.js b/dist/runtime/providers/sanity.js deleted file mode 100644 index 9019eac54..000000000 --- a/dist/runtime/providers/sanity.js +++ /dev/null @@ -1,87 +0,0 @@ -import { joinURL } from "ufo"; -import { createOperationsGenerator } from "~image"; -const sanityCDN = "https://cdn.sanity.io/images"; -const operationsGenerator = createOperationsGenerator({ - keyMap: { - format: "fm", - height: "h", - quality: "q", - width: "w", - background: "bg", - download: "dl", - sharpen: "sharp", - orientation: "or", - "min-height": "min-h", - "max-height": "max-h", - "min-width": "min-w", - "max-width": "max-w", - minHeight: "min-h", - maxHeight: "max-h", - minWidth: "min-w", - maxWidth: "max-w", - saturation: "sat" - }, - valueMap: { - format: { - jpeg: "jpg" - }, - fit: { - cover: "crop", - contain: "fill", - fill: "scale", - inside: "min", - outside: "max" - } - }, - joinWith: "&", - formatter: (key, value) => String(value) === "true" ? key : `${key}=${value}` -}); -const isDev = process.env.NODE_ENV === "development"; -const getMetadata = (id) => { - const result = id.match(/-(?\d*)x(?\d*)-(?.*)$/); - if (!result || !result.groups) { - if (isDev) { - console.warn(`An invalid image asset ID was passed in: ${id}`); - } - return { width: void 0, height: void 0, format: void 0 }; - } - const width = Number(result.groups.width); - const height = Number(result.groups.height); - return { - width, - height, - format: result.groups.format - }; -}; -export const getImage = (src, { modifiers = {}, projectId, dataset = "production" } = {}) => { - const { height: sourceHeight, width: sourceWidth } = getMetadata(src); - if (modifiers.crop && typeof modifiers.crop !== "string" && sourceWidth && sourceHeight) { - const left = modifiers.crop.left * sourceWidth; - const top = modifiers.crop.top * sourceHeight; - const right = sourceWidth - modifiers.crop.right * sourceWidth; - const bottom = sourceHeight - modifiers.crop.bottom * sourceHeight; - modifiers.rect = [left, top, right - left, bottom - top].map((i) => i.toFixed(0)).join(","); - delete modifiers.crop; - } - if (modifiers.hotspot && typeof modifiers.hotspot !== "string") { - modifiers["fp-x"] = modifiers.hotspot.x; - modifiers["fp-y"] = modifiers.hotspot.y; - delete modifiers.hotspot; - } - if (!modifiers.format || modifiers.format === "auto") { - if (modifiers.format === "auto") { - delete modifiers.format; - } - modifiers.auto = "format"; - } - if (modifiers.fit === "contain" && !modifiers.bg) { - modifiers.bg = "ffffff"; - } - const operations = operationsGenerator(modifiers); - const parts = src.split("-").slice(1); - const format = parts.pop(); - const filenameAndQueries = parts.join("-") + "." + format + (operations ? "?" + operations : ""); - return { - url: joinURL(sanityCDN, projectId, dataset, filenameAndQueries) - }; -}; diff --git a/dist/runtime/providers/static.d.ts b/dist/runtime/providers/static.d.ts deleted file mode 100644 index 4bcebdd4c..000000000 --- a/dist/runtime/providers/static.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { getImage as _getImage } from './ipx'; -export declare const getImage: typeof _getImage; -export declare const supportsAlias = true; diff --git a/dist/runtime/providers/static.js b/dist/runtime/providers/static.js deleted file mode 100644 index 7a030d6db..000000000 --- a/dist/runtime/providers/static.js +++ /dev/null @@ -1,6 +0,0 @@ -import { getImage as _getImage } from "./ipx"; -export const getImage = (src, options, ctx) => ({ - ..._getImage(src, options, ctx), - isStatic: true -}); -export const supportsAlias = true; diff --git a/dist/runtime/providers/storyblok.d.ts b/dist/runtime/providers/storyblok.d.ts deleted file mode 100644 index d07bf64e2..000000000 --- a/dist/runtime/providers/storyblok.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/storyblok.js b/dist/runtime/providers/storyblok.js deleted file mode 100644 index f60b8120b..000000000 --- a/dist/runtime/providers/storyblok.js +++ /dev/null @@ -1,28 +0,0 @@ -import { withBase, joinURL, parseURL } from "ufo"; -const storyblockCDN = "https://a.storyblok.com"; -export const getImage = (src, { modifiers = {}, baseURL = storyblockCDN } = {}) => { - const { - fit, - smart, - width = "0", - height = "0", - filters = {}, - format, - quality - } = modifiers; - const doResize = width !== "0" || height !== "0"; - if (format) { - filters.format = format + ""; - } - if (quality) { - filters.quality = quality + ""; - } - const _filters = Object.entries(filters || {}).map((e) => `${e[0]}(${e[1]})`).join(":"); - const options = joinURL(fit ? `fit-${fit}` : "", doResize ? `${width}x${height}` : "", smart ? "smart" : "", _filters ? "filters:" + _filters : ""); - const { pathname } = parseURL(src); - const modifier = options ? "/m/" : ""; - const url = withBase(joinURL(pathname, modifier, options), baseURL); - return { - url - }; -}; diff --git a/dist/runtime/providers/strapi.d.ts b/dist/runtime/providers/strapi.d.ts deleted file mode 100644 index 3bfbfcade..000000000 --- a/dist/runtime/providers/strapi.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; -export declare const validateDomains = true; diff --git a/dist/runtime/providers/strapi.js b/dist/runtime/providers/strapi.js deleted file mode 100644 index 4633b12e8..000000000 --- a/dist/runtime/providers/strapi.js +++ /dev/null @@ -1,13 +0,0 @@ -import { withBase, withoutLeadingSlash } from "ufo"; -export const getImage = (src, { modifiers, baseURL = "http://localhost:1337/uploads" } = {}) => { - const breakpoint = modifiers?.breakpoint ?? ""; - if (!breakpoint) { - return { - url: withBase(src, baseURL) - }; - } - return { - url: withBase(`${breakpoint}_${withoutLeadingSlash(src)}`, baseURL) - }; -}; -export const validateDomains = true; diff --git a/dist/runtime/providers/twicpics.d.ts b/dist/runtime/providers/twicpics.d.ts deleted file mode 100644 index d07bf64e2..000000000 --- a/dist/runtime/providers/twicpics.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/twicpics.js b/dist/runtime/providers/twicpics.js deleted file mode 100644 index 440b7d4d0..000000000 --- a/dist/runtime/providers/twicpics.js +++ /dev/null @@ -1,64 +0,0 @@ -import { joinURL } from "ufo"; -import { createMapper, createOperationsGenerator } from "~image"; -const fits = createMapper({ - fill: "resize", - inside: "contain", - outside: "contain", - cover: "cover", - contain: "inside", - missingValue: "cover" -}); -const operationsGenerator = createOperationsGenerator({ - keyMap: { - format: "output", - quality: "quality", - background: "background", - focus: "focus", - zoom: "zoom" - }, - valueMap: { - format(value) { - if (value === "jpg") { - return "jpeg"; - } - return value; - }, - background(value) { - if (value.startsWith("#")) { - return value.replace("#", ""); - } - return value; - }, - focus: { - auto: "auto", - faces: "faces", - north: "50px0p", - northEast: "100px0p", - northWest: "0px0p", - west: "0px50p", - southWest: "100px100p", - south: "50px100p", - southEast: "0px100p", - east: "100px50p", - center: "50px50p" - } - }, - joinWith: "/", - formatter: (key, value) => `${key}=${value}` -}); -export const getImage = (src, { modifiers = {}, baseURL = "/" } = {}) => { - const { width, height, fit, ...providerModifiers } = modifiers; - let w = width; - let h = height; - if (width || height) { - if (fit && fit === "outside") { - w = Math.max(width || 0, height || 0); - h = Math.max(width || 0, height || 0); - } - providerModifiers[fits(fit)] = `${w || "-"}x${h || "-"}`; - } - const operations = operationsGenerator(providerModifiers); - return { - url: joinURL(baseURL, src + (operations ? "?twic=v1/" + operations : "")) - }; -}; diff --git a/dist/runtime/providers/unsplash.d.ts b/dist/runtime/providers/unsplash.d.ts deleted file mode 100644 index d07bf64e2..000000000 --- a/dist/runtime/providers/unsplash.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; diff --git a/dist/runtime/providers/unsplash.js b/dist/runtime/providers/unsplash.js deleted file mode 100644 index 328d6cd7d..000000000 --- a/dist/runtime/providers/unsplash.js +++ /dev/null @@ -1,9 +0,0 @@ -import { joinURL, withBase } from "ufo"; -import { operationsGenerator } from "./imgix"; -const unsplashCDN = "https://images.unsplash.com/"; -export const getImage = (src, { modifiers = {}, baseURL = unsplashCDN } = {}) => { - const operations = operationsGenerator(modifiers); - return { - url: withBase(joinURL(src + (operations ? "?" + operations : "")), baseURL) - }; -}; diff --git a/dist/runtime/providers/vercel.d.ts b/dist/runtime/providers/vercel.d.ts deleted file mode 100644 index 3bfbfcade..000000000 --- a/dist/runtime/providers/vercel.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ProviderGetImage } from 'src'; -export declare const getImage: ProviderGetImage; -export declare const validateDomains = true; diff --git a/dist/runtime/providers/vercel.js b/dist/runtime/providers/vercel.js deleted file mode 100644 index 613fd733d..000000000 --- a/dist/runtime/providers/vercel.js +++ /dev/null @@ -1,28 +0,0 @@ -import { stringifyQuery } from "ufo"; -export const getImage = (src, { modifiers, baseURL = "/_vercel/image" } = {}, ctx) => { - const validWidths = Object.values(ctx.options.screens || {}).sort((a, b) => a - b); - const largestWidth = validWidths[validWidths.length - 1]; - let width = Number(modifiers?.width || 0); - if (!width) { - width = largestWidth; - if (process.env.NODE_ENV === "development") { - console.warn(`A defined width should be provided to use the \`vercel\` provider. Defaulting to \`${largestWidth}\`. Warning originated from \`${src}\`.`); - } - } else if (!validWidths.includes(width)) { - width = validWidths.find((validWidth) => validWidth > width) || largestWidth; - if (process.env.NODE_ENV === "development") { - console.warn(`The width being used (\`${modifiers?.width}\`) should be added to \`image.screens\`. Defaulting to \`${width}\`. Warning originated from \`${src}\`.`); - } - } - if (process.env.NODE_ENV === "development") { - return { url: src }; - } - return { - url: baseURL + "?" + stringifyQuery({ - url: src, - w: String(width), - q: String(modifiers?.quality || "100") - }) - }; -}; -export const validateDomains = true; diff --git a/dist/runtime/utils/index.d.ts b/dist/runtime/utils/index.d.ts deleted file mode 100644 index 131c9723d..000000000 --- a/dist/runtime/utils/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { OperationGeneratorConfig } from '../../types/image'; -export default function imageFetch(url: string): Promise; -export declare function getInt(x: unknown): number | undefined; -export declare function getFileExtension(url?: string): string; -export declare function cleanDoubleSlashes(path?: string): string; -export declare function createMapper(map: any): (key?: string) => any; -export declare function createOperationsGenerator({ formatter, keyMap, joinWith, valueMap }?: OperationGeneratorConfig): (modifiers?: { - [key: string]: string; -}) => string; -declare type Attrs = { - [key: string]: string | number; -}; -export declare function renderAttributesToString(attributes?: Attrs): string; -export declare function renderTag(tag: string, attrs: Attrs, contents?: string): string; -export declare function generateAlt(src?: string): string; -export declare function parseSize(input?: string | number | undefined): number; -export {}; diff --git a/dist/runtime/utils/index.js b/dist/runtime/utils/index.js deleted file mode 100644 index db9713c03..000000000 --- a/dist/runtime/utils/index.js +++ /dev/null @@ -1,72 +0,0 @@ -export default function imageFetch(url) { - return fetch(cleanDoubleSlashes(url)); -} -export function getInt(x) { - if (typeof x === "number") { - return x; - } - if (typeof x === "string") { - return parseInt(x, 10); - } - return void 0; -} -export function getFileExtension(url = "") { - const extension = url.split(/[?#]/).shift().split("/").pop().split(".").pop(); - return extension; -} -export function cleanDoubleSlashes(path = "") { - return path.replace(/(https?:\/\/)|(\/)+/g, "$1$2"); -} -export function createMapper(map) { - return (key) => { - return key ? map[key] || key : map.missingValue; - }; -} -export function createOperationsGenerator({ formatter, keyMap, joinWith = "/", valueMap } = {}) { - if (!formatter) { - formatter = (key, value) => `${key}=${value}`; - } - if (keyMap && typeof keyMap !== "function") { - keyMap = createMapper(keyMap); - } - const map = valueMap || {}; - Object.keys(map).forEach((valueKey) => { - if (typeof map[valueKey] !== "function") { - map[valueKey] = createMapper(map[valueKey]); - } - }); - return (modifiers = {}) => { - const operations = Object.entries(modifiers).filter(([_, value]) => typeof value !== "undefined").map(([key, value]) => { - const mapper = map[key]; - if (typeof mapper === "function") { - value = mapper(modifiers[key]); - } - key = typeof keyMap === "function" ? keyMap(key) : key; - return formatter(key, value); - }); - return operations.join(joinWith); - }; -} -export function renderAttributesToString(attributes = {}) { - return Object.entries(attributes).map(([key, value]) => value ? `${key}="${value}"` : "").filter(Boolean).join(" "); -} -export function renderTag(tag, attrs, contents) { - const html = `<${tag} ${renderAttributesToString(attrs)}>`; - if (!contents) { - return html; - } - return html + contents + ``; -} -export function generateAlt(src = "") { - return src.split(/[?#]/).shift().split("/").pop().split(".").shift(); -} -export function parseSize(input = "") { - if (typeof input === "number") { - return input; - } - if (typeof input === "string") { - if (input.replace("px", "").match(/^\d+$/g)) { - return parseInt(input, 10); - } - } -} diff --git a/dist/runtime/utils/meta.d.ts b/dist/runtime/utils/meta.d.ts deleted file mode 100644 index 9a841ba42..000000000 --- a/dist/runtime/utils/meta.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { ImageInfo, ImageCTX } from '../../types/image'; -export declare function imageMeta(ctx: ImageCTX, url: string): Promise; diff --git a/dist/runtime/utils/meta.js b/dist/runtime/utils/meta.js deleted file mode 100644 index 6b9e9aa94..000000000 --- a/dist/runtime/utils/meta.js +++ /dev/null @@ -1,67 +0,0 @@ -export async function imageMeta(ctx, url) { - const cache = getCache(ctx); - const cacheKey = "image:meta:" + url; - if (cache.has(cacheKey)) { - return cache.get(cacheKey); - } - const meta = await _imageMeta(url).catch((err) => { - console.error("Failed to get image meta for " + url, err + ""); - return { - width: 0, - height: 0, - ratio: 0 - }; - }); - cache.set(cacheKey, meta); - return meta; -} -async function _imageMeta(url) { - if (process.server) { - const imageMeta2 = await import("image-meta").then((r) => r.default || r); - const data = await fetch(url).then((res) => res.buffer()); - const metadata = imageMeta2(data); - if (!metadata) { - throw new Error(`No metadata could be extracted from the image \`${url}\`.`); - } - const { width, height } = metadata; - const meta = { - width, - height, - ratio: width && height ? width / height : void 0 - }; - return meta; - } - if (typeof Image === "undefined") { - throw new TypeError("Image not supported"); - } - return new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => { - const meta = { - width: img.width, - height: img.height, - ratio: img.width / img.height - }; - resolve(meta); - }; - img.onerror = (err) => reject(err); - img.src = url; - }); -} -function getCache(ctx) { - if (!ctx.nuxtContext.cache) { - if (ctx.nuxtContext.ssrContext && ctx.nuxtContext.ssrContext.cache) { - ctx.nuxtContext.cache = ctx.nuxtContext.ssrContext.cache; - } else { - const _cache = {}; - ctx.nuxtContext.cache = { - get: (id) => _cache[id], - set: (id, value) => { - _cache[id] = value; - }, - has: (id) => typeof _cache[id] !== "undefined" - }; - } - } - return ctx.nuxtContext.cache; -} diff --git a/dist/runtime/utils/static-map.d.ts b/dist/runtime/utils/static-map.d.ts deleted file mode 100644 index 38d417a0d..000000000 --- a/dist/runtime/utils/static-map.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { Context } from '@nuxt/types'; -export declare function useStaticImageMap(nuxtContext?: Context): {}; diff --git a/dist/runtime/utils/static-map.js b/dist/runtime/utils/static-map.js deleted file mode 100644 index e6516964b..000000000 --- a/dist/runtime/utils/static-map.js +++ /dev/null @@ -1,20 +0,0 @@ -const staticImageMap = {}; -function updateImageMap() { - if (typeof window.$nuxt !== "undefined") { - const pageImages = window.$nuxt._pagePayload?.data?.[0]?._img || {}; - Object.assign(staticImageMap, pageImages); - } else if (typeof window.__NUXT__ !== "undefined") { - const pageImages = window.__NUXT__?._img || {}; - Object.assign(staticImageMap, pageImages); - } -} -export function useStaticImageMap(nuxtContext) { - updateImageMap(); - if (nuxtContext) { - nuxtContext.app.router?.afterEach(updateImageMap); - } - if (window.onNuxtReady) { - window.onNuxtReady(updateImageMap); - } - return staticImageMap; -} diff --git a/package.json b/package.json index bd0df3018..c1d3d672d 100755 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@jthawme/nuxt-image", + "name": "jthawme-nuxt-image", "version": "0.8.4", "description": "Nuxt Image Module", "repository": "https://github.com/jthawme/nuxt-image-fork", @@ -12,7 +12,6 @@ "vetur" ], "scripts": { - "prepare": "npm run build", "build": "unbuild", "dev": "yarn nuxt playground", "docs:build": "cd docs && nuxt generate", From a0c420fcf49c1b35f7324560b7455d0e5c976813 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Mon, 23 Jan 2023 11:33:17 +0000 Subject: [PATCH 12/17] fix: fixed issue of unique urls not being generated --- src/generate.ts | 2 +- src/utils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generate.ts b/src/generate.ts index f116d64fc..290a7f138 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -16,7 +16,7 @@ function getHash (input: string, url: string) { const staticFile = path.join(process.cwd(), 'static', input) if (existsSync(staticFile)) { - return hasha.fromFileSync(staticFile) + return hash(`${hasha.fromFileSync(staticFile)}${url}`) } return hash(url) diff --git a/src/utils.ts b/src/utils.ts index 7f0a9ed80..0b5c9022d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,7 +6,7 @@ export const logger = consola.withScope('@nuxt/image') export const pkg = { name, version } -export function hash (value: string, length = 6) { +export function hash (value: string, length = 32) { return hasha(value).substr(0, length) } From 42c1ab1a36a3a21523e4423cc9ed5859dbfe87ed Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Mon, 23 Jan 2023 11:33:46 +0000 Subject: [PATCH 13/17] chore(release): 0.8.5 --- CHANGELOG.md | 11 +++++++++++ package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a32d544d8..3f522a402 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.8.5](https://github.com/jthawme/nuxt-image-fork/compare/v0.8.4...v0.8.5) (2023-01-23) + + +### Bug Fixes + +* added prepare script for local install ([520a945](https://github.com/jthawme/nuxt-image-fork/commit/520a945469906affc659c1bcfa0adb379e2f0b20)) +* fixed issue of unique urls not being generated ([a0c420f](https://github.com/jthawme/nuxt-image-fork/commit/a0c420fcf49c1b35f7324560b7455d0e5c976813)) +* readjusted node version ([6704ef1](https://github.com/jthawme/nuxt-image-fork/commit/6704ef149d724184b145a48a8d17a43331933516)) +* updated readme and remove dist again in favour of npm ([0aa502e](https://github.com/jthawme/nuxt-image-fork/commit/0aa502e3b67d9de596ad6c582a45bbff2382d791)) +* updated readme for context ([5a441a9](https://github.com/jthawme/nuxt-image-fork/commit/5a441a98035b5d9c5fe79aa0bd10eb80e87b8600)) + ### [0.8.4](https://github.com/jthawme/nuxt-image-fork/compare/v0.8.3...v0.8.4) (2023-01-20) ### [0.8.3](https://github.com/nuxt/image/compare/v0.8.2...v0.8.3) (2023-01-20) diff --git a/package.json b/package.json index c1d3d672d..042e7ae2c 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jthawme-nuxt-image", - "version": "0.8.4", + "version": "0.8.5", "description": "Nuxt Image Module", "repository": "https://github.com/jthawme/nuxt-image-fork", "license": "MIT", From 989df5744ed0bdf0374db9357f4b6b1b2b92fb68 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Thu, 18 May 2023 17:52:21 +0100 Subject: [PATCH 14/17] fix: added image skip generation logic --- src/generate.ts | 20 +++++++++++++++++--- src/types/module.ts | 2 ++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/generate.ts b/src/generate.ts index 290a7f138..d2055a78d 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -45,6 +45,8 @@ export function setupStaticGeneration (nuxt: any, options: ModuleOptions) { }) nuxt.hook('generate:done', async () => { + const images = options.fetchImageDictionary ? await options.fetchImageDictionary(staticImages) : [] + const limit = pLimit(8) const downloads = Object.entries(staticImages).map(([url, name]) => { if (!hasProtocol(url)) { @@ -53,7 +55,9 @@ export function setupStaticGeneration (nuxt: any, options: ModuleOptions) { return limit(() => downloadImage({ url, name, - outDir: nuxt.options.generate.dir + outDir: nuxt.options.generate.dir, + skip: options.skipGeneration, + imageDictionary: images })) }) await Promise.all(downloads) @@ -61,11 +65,21 @@ export function setupStaticGeneration (nuxt: any, options: ModuleOptions) { } const pipeline = promisify(stream.pipeline) -async function downloadImage ({ url, name, outDir }: { url: string, name: string, outDir: string }) { +async function downloadImage ({ url, name, outDir, skip, imageDictionary }: { url: string, name: string, outDir: string, imageDictionary: string[], skip?: ModuleOptions['skipGeneration'] }) { try { + const dstFile = join(outDir, name) + + if (skip) { + const shouldSkip = await skip(name, fetch, imageDictionary).then(shouldSkip => shouldSkip) + + if (shouldSkip) { + logger.success('Skipping generation for ' + relative(process.cwd(), dstFile)) + return + } + } + const response = await fetch(url) if (!response.ok) { throw new Error(`Unexpected response ${response.statusText}`) } - const dstFile = join(outDir, name) await mkdirp(dirname(dstFile)) await pipeline(response.body as any, createWriteStream(dstFile)) logger.success('Generated static image ' + relative(process.cwd(), dstFile)) diff --git a/src/types/module.ts b/src/types/module.ts index 3521a08a5..ec6156cfe 100644 --- a/src/types/module.ts +++ b/src/types/module.ts @@ -71,6 +71,8 @@ export interface ModuleOptions extends ImageProviders { screens: CreateImageOptions['screens'], internalUrl: string providers: { [name: string]: InputProvider | any } & ImageProviders + skipGeneration?: (destFile: string, fetch: any, imageDictionary: string[]) => Promise, + fetchImageDictionary?: (staticImageDictionary: Record) => Promise, [key: string]: any } From 455847fe5c67fbeb8cd73ebd198d1fe3a30b8935 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Thu, 18 May 2023 17:53:02 +0100 Subject: [PATCH 15/17] chore(release): 0.8.6 --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f522a402..f2455aeaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.8.6](https://github.com/jthawme/nuxt-image-fork/compare/v0.8.5...v0.8.6) (2023-05-18) + + +### Bug Fixes + +* added image skip generation logic ([989df57](https://github.com/jthawme/nuxt-image-fork/commit/989df5744ed0bdf0374db9357f4b6b1b2b92fb68)) + ### [0.8.5](https://github.com/jthawme/nuxt-image-fork/compare/v0.8.4...v0.8.5) (2023-01-23) diff --git a/package.json b/package.json index 042e7ae2c..1ecb1f13d 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jthawme-nuxt-image", - "version": "0.8.5", + "version": "0.8.6", "description": "Nuxt Image Module", "repository": "https://github.com/jthawme/nuxt-image-fork", "license": "MIT", From 4fb761b9c695b34fc8ab2cb48fd82e8b9148a4e4 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Thu, 18 May 2023 17:54:25 +0100 Subject: [PATCH 16/17] chore(release): 0.8.7 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2455aeaf..ccc849854 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.8.7](https://github.com/jthawme/nuxt-image-fork/compare/v0.8.6...v0.8.7) (2023-05-18) + ### [0.8.6](https://github.com/jthawme/nuxt-image-fork/compare/v0.8.5...v0.8.6) (2023-05-18) diff --git a/package.json b/package.json index 1ecb1f13d..7d854027c 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jthawme-nuxt-image", - "version": "0.8.6", + "version": "0.8.7", "description": "Nuxt Image Module", "repository": "https://github.com/jthawme/nuxt-image-fork", "license": "MIT", From d8b06a66febe93b1d242bf09f59f61e2e305f155 Mon Sep 17 00:00:00 2001 From: Jonny Thaw Date: Mon, 22 May 2023 11:48:47 +0100 Subject: [PATCH 17/17] chore: corrected readme error --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e6c4cc9e..a839bf4c0 100755 --- a/README.md +++ b/README.md @@ -6,7 +6,9 @@ I couldn't work out the best way to report back this change to the main module a ## Install -`yarn add jthawme-image-fork` +``` +yarn add jthawme-nuxt-image // or npm install jthawme-nuxt-image +``` With nuxt 2 you also have to add this package to the `transpile` property in `nuxt.config.js`