From da8ee762c9a4b748e2b39e5b853e65c0d01c00b8 Mon Sep 17 00:00:00 2001 From: wenyiqing Date: Tue, 17 Mar 2026 11:06:37 +0800 Subject: [PATCH 1/2] feat(provider): add Tencent Cloud COS image provider --- docs/content/3.providers/tencent-cloud.md | 149 ++++++++ playground/app/pages/tencent-cloud.vue | 393 ++++++++++++++++++++++ playground/app/providers.ts | 43 +++ playground/nuxt.config.ts | 3 + src/provider.ts | 1 + src/runtime/providers/tencentCloud.ts | 194 +++++++++++ test/e2e/__snapshots__/tencentCloud.json5 | 18 + test/nuxt/providers.test.ts | 151 +++++++++ test/providers.ts | 6 + 9 files changed, 958 insertions(+) create mode 100644 docs/content/3.providers/tencent-cloud.md create mode 100644 playground/app/pages/tencent-cloud.vue create mode 100644 src/runtime/providers/tencentCloud.ts create mode 100644 test/e2e/__snapshots__/tencentCloud.json5 diff --git a/docs/content/3.providers/tencent-cloud.md b/docs/content/3.providers/tencent-cloud.md new file mode 100644 index 000000000..3c1939c90 --- /dev/null +++ b/docs/content/3.providers/tencent-cloud.md @@ -0,0 +1,149 @@ +--- +title: Tencent Cloud +description: Use Tencent Cloud COS imageMogr2 for image processing. +links: + - label: Source + icon: i-simple-icons-github + to: https://github.com/nuxt/image/blob/main/src/runtime/providers/tencentCloud.ts + size: xs +--- + +Integration with Tencent Cloud COS Cloud Infinite (CI) image processing (`imageMogr2`). Supports resizing, cropping, rotation, format conversion, quality control, Gaussian blur, sharpening, and more. + +## Setup + +Set the bucket domain as `baseURL` in `nuxt.config.ts`: + +```ts [nuxt.config.ts] +export default defineNuxtConfig({ + image: { + tencentCloud: { + baseURL: 'https://.cos..myqcloud.com' + } + } +}) +``` + +::note +`baseURL` should point to a publicly accessible COS bucket domain (or a bound CDN domain). No trailing slash is needed. +:: + +## Basic Usage + +```vue + +``` + +## Standard Modifiers + +All 7 standard NuxtImg modifiers are mapped to COS imageMogr2: + +| Modifier | COS Mapping | Description | +|---|---|---| +| `width` / `height` | `/thumbnail/x` | Proportional scaling, affected by `fit` | +| `fit` | thumbnail suffix | `contain` → `x`, `cover` → `!xr`, `fill` → `x!` | +| `quality` | `/quality/` | Quality 1-100 | +| `format` | `/format/` | Output format, `jpeg` is auto-mapped to `jpg` | +| `background` | `/pad/1/color/` | Used with scaling, fills background color | +| `blur` | `/blur/x` | Gaussian blur | + +## COS Extended Modifiers + +Pass Tencent Cloud-specific image processing parameters via the `:modifiers` prop: + +| Modifier | COS Mapping | Description | +|---|---|---| +| `crop` | `/crop/x` | Regular crop (independent of scaling) | +| `gravity` | `/gravity/` | Crop anchor: center, north, south, west, east, northwest, etc. | +| `dx` / `dy` | `/dx//dy/` | Crop offset | +| `iradius` | `/iradius/` | Inscribed circle crop radius | +| `scrop` | `/scrop/x` | Smart face crop | +| `rotate` | `/rotate/` | Clockwise rotation 0-360° | +| `autoOrient` | `/auto-orient` | Auto-rotate based on EXIF orientation | +| `sharpen` | `/sharpen/` | Sharpen | +| `strip` | `/strip` | Strip EXIF metadata | +| `interlace` | `/interlace/1` | Progressive JPEG/GIF | +| `pad` | `/pad/1` | Pad mode (used with background) | + +## Examples + +### Resize + Format + Quality + +```vue + +``` + +Generated URL: `?imageMogr2/thumbnail/!1200x500r/quality/85/format/webp` + +### Crop + Gravity + +```vue + +``` + +Generated URL: `?imageMogr2/crop/300x300/gravity/center` + +### Rotate + Sharpen + Strip Metadata + +```vue + +``` + +Generated URL: `?imageMogr2/rotate/90/sharpen/70/strip` + +### Gaussian Blur (Placeholder Effect) + +```vue + +``` + +Generated URL: `?imageMogr2/thumbnail/100x/quality/10/blur/20x20` + +### Smart Face Crop + +```vue + +``` + +Generated URL: `?imageMogr2/scrop/200x200` + +## References + +- [COS imageMogr2 Scaling](https://cloud.tencent.com/document/product/436/44880) +- [COS imageMogr2 Cropping](https://cloud.tencent.com/document/product/436/44881) +- [COS imageMogr2 Rotation](https://cloud.tencent.com/document/product/436/44882) +- [COS imageMogr2 Format Conversion](https://cloud.tencent.com/document/product/436/44883) +- [COS imageMogr2 Quality](https://cloud.tencent.com/document/product/436/44884) +- [COS imageMogr2 Gaussian Blur](https://cloud.tencent.com/document/product/436/44885) +- [COS imageMogr2 Sharpen](https://cloud.tencent.com/document/product/436/44886) diff --git a/playground/app/pages/tencent-cloud.vue b/playground/app/pages/tencent-cloud.vue new file mode 100644 index 000000000..47f22ff84 --- /dev/null +++ b/playground/app/pages/tencent-cloud.vue @@ -0,0 +1,393 @@ + + + + + diff --git a/playground/app/providers.ts b/playground/app/providers.ts index 6417d39fb..9450bd532 100644 --- a/playground/app/providers.ts +++ b/playground/app/providers.ts @@ -1116,6 +1116,49 @@ export const providers: Provider[] = [ }, ], }, + // Tencent Cloud + { + name: 'tencentCloud', + samples: [ + { + src: '/images/cases/case3.png', + width: 400, + height: 300, + fit: 'contain', + }, + { + src: '/images/cases/case2.png', + width: 400, + height: 300, + fit: 'cover', + }, + { + src: '/images/cases/case4.png', + width: 400, + height: 300, + fit: 'fill', + }, + { + src: '/images/cases/case3.png', + width: 300, + quality: 80, + format: 'webp', + }, + { + src: '/images/cases/case2.png', + modifiers: { + rotate: 90, + }, + }, + { + src: '/images/cases/case4.png', + modifiers: { + blur: 15, + quality: 50, + }, + }, + ], + }, // Unsplash { name: 'unsplash', diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index 9e9db4485..fca3ee031 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -111,6 +111,9 @@ export default defineNuxtConfig({ supabase: { baseURL: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt', }, + tencentCloud: { + baseURL: 'https://saas-starter.edgeone.app', + }, unsplash: {}, vercel: { baseURL: 'https://image-component.nextjs.gallery/_next/image', diff --git a/src/provider.ts b/src/provider.ts index e41451151..1f8db3acf 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -47,6 +47,7 @@ export const BuiltInProviders = [ 'strapi', 'strapi5', 'supabase', + 'tencentCloud', 'twicpics', 'unsplash', 'uploadcare', diff --git a/src/runtime/providers/tencentCloud.ts b/src/runtime/providers/tencentCloud.ts new file mode 100644 index 000000000..3044a1105 --- /dev/null +++ b/src/runtime/providers/tencentCloud.ts @@ -0,0 +1,194 @@ +import { joinURL } from 'ufo' +import type { ImageModifiers } from '@nuxt/image' +import { defineProvider } from '../utils/provider' + +interface TencentCloudModifiers extends ImageModifiers { + /** Regular crop: 'x' e.g. '300x400' */ + crop: string + /** Crop/scale gravity: center, north, south, west, east, northwest, northeast, southwest, southeast */ + gravity: string + /** Crop X offset */ + dx: number + /** Crop Y offset */ + dy: number + /** Inscribed circle crop radius */ + iradius: number + /** Smart face crop: 'x' */ + scrop: string + /** Clockwise rotation angle 0-360 */ + rotate: number + /** Auto-rotate based on EXIF orientation */ + autoOrient: boolean + /** Sharpen intensity */ + sharpen: number + /** Strip EXIF metadata */ + strip: boolean + /** Progressive display (JPEG/GIF) */ + interlace: boolean | number + /** Pad mode (used with thumbnail + background) 0 or 1 */ + pad: boolean | number +} + +/** Options for the Tencent Cloud COS image provider. */ +export interface TencentCloudOptions { + /** Base URL of the COS bucket (e.g. `https://example.cos.ap-guangzhou.myqcloud.com`). */ + baseURL: string + /** Optional image processing modifiers. */ + modifiers?: Partial +} + +const fitMap: Record = { + contain: '', // /thumbnail/x — scale to fit within bounds (default) + cover: 'r', // /thumbnail/!xr — scale to cover minimum bounds + fill: '!', // /thumbnail/x! — force stretch to exact dimensions + inside: '', // same as contain + outside: 'r', // same as cover +} + +/** Encode a hex color string to URL-safe Base64 for COS background fill. */ +function encodeCosColor(color: string): string { + const hex = color.startsWith('#') ? color : `#${color}` + if (typeof globalThis.btoa === 'function') { + return globalThis.btoa(hex).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '') + } + return Buffer.from(hex).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '') +} + +/** + * Tencent Cloud COS image provider. + * + * Transforms images via the COS `imageMogr2` API, supporting resize, + * crop, rotate, blur, quality, format conversion and more. + * + * @see https://cloud.tencent.com/document/product/460/6924 + */ +export default defineProvider({ + getImage: (src, { modifiers = {}, baseURL }) => { + if (!baseURL) { + throw new Error('Tencent Cloud provider requires baseURL to be set') + } + + const { + width, + height, + fit, + quality, + format, + background, + blur, + crop, + gravity, + dx, + dy, + iradius, + scrop, + rotate, + autoOrient, + sharpen, + strip, + interlace, + pad, + } = modifiers as Partial + + const operations: string[] = [] + + // --- Thumbnail (resize) --- + if (width || height) { + const w = width ?? '' + const h = height ?? '' + const fitSuffix = fit ? (fitMap[fit] ?? '') : '' + + if (fitSuffix === 'r') { + // cover / outside: !xr + operations.push(`thumbnail/!${w}x${h}r`) + } + else if (fitSuffix === '!') { + // fill: x! + operations.push(`thumbnail/${w}x${h}!`) + } + else { + // contain / inside / default: x + operations.push(`thumbnail/${w}x${h}`) + } + } + + // --- Pad + Color (background fill) --- + if (pad || (background && (width || height))) { + operations.push('pad/1') + if (background) { + operations.push(`color/${encodeCosColor(background)}`) + } + } + + // --- Crop (regular crop) --- + if (crop) { + operations.push(`crop/${crop}`) + if (gravity) { + operations.push(`gravity/${gravity}`) + } + if (typeof dx !== 'undefined') { + operations.push(`dx/${dx}`) + } + if (typeof dy !== 'undefined') { + operations.push(`dy/${dy}`) + } + } + + // --- iradius (inscribed circle crop) --- + if (typeof iradius !== 'undefined') { + operations.push(`iradius/${iradius}`) + } + + // --- scrop (smart face crop) --- + if (scrop) { + operations.push(`scrop/${scrop}`) + } + + // --- Rotate --- + if (typeof rotate !== 'undefined') { + operations.push(`rotate/${rotate}`) + } + + // --- Auto-orient --- + if (autoOrient) { + operations.push('auto-orient') + } + + // --- Quality --- + if (typeof quality !== 'undefined') { + operations.push(`quality/${quality}`) + } + + // --- Format --- + if (format) { + const mappedFormat = format === 'jpeg' ? 'jpg' : format + operations.push(`format/${mappedFormat}`) + } + + // --- Blur (Gaussian blur) --- + if (typeof blur !== 'undefined' && blur) { + operations.push(`blur/${blur}x${blur}`) + } + + // --- Sharpen --- + if (typeof sharpen !== 'undefined') { + operations.push(`sharpen/${sharpen}`) + } + + // --- Strip (remove metadata) --- + if (strip) { + operations.push('strip') + } + + // --- Interlace (progressive display) --- + if (interlace) { + operations.push(`interlace/${typeof interlace === 'number' ? interlace : 1}`) + } + + const query = operations.length ? `?imageMogr2/${operations.join('/')}` : '' + + return { + url: joinURL(baseURL, src + query), + } + }, +}) diff --git a/test/e2e/__snapshots__/tencentCloud.json5 b/test/e2e/__snapshots__/tencentCloud.json5 new file mode 100644 index 000000000..e1fe9a58c --- /dev/null +++ b/test/e2e/__snapshots__/tencentCloud.json5 @@ -0,0 +1,18 @@ +{ + "requests": [ + "https://saas-starter.edgeone.app/images/cases/case2.png?imageMogr2/rotate/90", + "https://saas-starter.edgeone.app/images/cases/case2.png?imageMogr2/thumbnail/!400x300r", + "https://saas-starter.edgeone.app/images/cases/case3.png?imageMogr2/thumbnail/300x/quality/80/format/webp", + "https://saas-starter.edgeone.app/images/cases/case3.png?imageMogr2/thumbnail/400x300", + "https://saas-starter.edgeone.app/images/cases/case4.png?imageMogr2/blur/15x15", + "https://saas-starter.edgeone.app/images/cases/case4.png?imageMogr2/thumbnail/400x300!", + ], + "sources": [ + "https://saas-starter.edgeone.app/images/cases/case3.png?imageMogr2/thumbnail/400x300", + "https://saas-starter.edgeone.app/images/cases/case2.png?imageMogr2/thumbnail/!400x300r", + "https://saas-starter.edgeone.app/images/cases/case4.png?imageMogr2/thumbnail/400x300!", + "https://saas-starter.edgeone.app/images/cases/case3.png?imageMogr2/thumbnail/300x/quality/80/format/webp", + "https://saas-starter.edgeone.app/images/cases/case2.png?imageMogr2/rotate/90", + "https://saas-starter.edgeone.app/images/cases/case4.png?imageMogr2/blur/15x15", + ], +} \ No newline at end of file diff --git a/test/nuxt/providers.test.ts b/test/nuxt/providers.test.ts index 21e7c6b25..3b884ed42 100644 --- a/test/nuxt/providers.test.ts +++ b/test/nuxt/providers.test.ts @@ -32,6 +32,7 @@ import storyblok from '../../dist/runtime/providers/storyblok' import strapi from '../../dist/runtime/providers/strapi' import strapi5 from '../../dist/runtime/providers/strapi5' import supabase from '../../dist/runtime/providers/supabase' +import tencentCloud from '../../dist/runtime/providers/tencentCloud' import vercel from '../../dist/runtime/providers/vercel' import wagtail from '../../dist/runtime/providers/wagtail' import uploadcare from '../../dist/runtime/providers/uploadcare' @@ -558,6 +559,156 @@ describe('Providers', () => { } }) + it('tencentCloud', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + + for (const image of images) { + const [src, modifiers] = image.args + const generated = tencentCloud().getImage(src, { modifiers, ...providerOptions }, getEmptyContext()) + expect(generated).toMatchObject(image.tencentCloud) + } + }) + + it('tencentCloud cover fit', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + const generated = tencentCloud().getImage('/test.png', { + modifiers: { width: 300, height: 200, fit: 'cover' }, + ...providerOptions, + }, getEmptyContext()) + expect(generated).toMatchObject({ + url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/!300x200r', + }) + }) + + it('tencentCloud fill fit', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + const generated = tencentCloud().getImage('/test.png', { + modifiers: { width: 300, height: 200, fit: 'fill' }, + ...providerOptions, + }, getEmptyContext()) + expect(generated).toMatchObject({ + url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/300x200!', + }) + }) + + it('tencentCloud blur', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + const generated = tencentCloud().getImage('/test.png', { + modifiers: { blur: 10 }, + ...providerOptions, + }, getEmptyContext()) + expect(generated).toMatchObject({ + url: 'https://example.cos.com/test.png?imageMogr2/blur/10x10', + }) + }) + + it('tencentCloud rotate', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + const generated = tencentCloud().getImage('/test.png', { + modifiers: { rotate: 90 }, + ...providerOptions, + }, getEmptyContext()) + expect(generated).toMatchObject({ + url: 'https://example.cos.com/test.png?imageMogr2/rotate/90', + }) + }) + + it('tencentCloud crop with gravity', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + const generated = tencentCloud().getImage('/test.png', { + modifiers: { crop: '300x400', gravity: 'center' }, + ...providerOptions, + }, getEmptyContext()) + expect(generated).toMatchObject({ + url: 'https://example.cos.com/test.png?imageMogr2/crop/300x400/gravity/center', + }) + }) + + it('tencentCloud sharpen and strip', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + const generated = tencentCloud().getImage('/test.png', { + modifiers: { sharpen: 70, strip: true }, + ...providerOptions, + }, getEmptyContext()) + expect(generated).toMatchObject({ + url: 'https://example.cos.com/test.png?imageMogr2/sharpen/70/strip', + }) + }) + + it('tencentCloud scrop (smart face crop)', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + const generated = tencentCloud().getImage('/test.png', { + modifiers: { scrop: '200x200' }, + ...providerOptions, + }, getEmptyContext()) + expect(generated).toMatchObject({ + url: 'https://example.cos.com/test.png?imageMogr2/scrop/200x200', + }) + }) + + it('tencentCloud interlace and autoOrient', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + const generated = tencentCloud().getImage('/test.png', { + modifiers: { interlace: true, autoOrient: true }, + ...providerOptions, + }, getEmptyContext()) + expect(generated).toMatchObject({ + url: 'https://example.cos.com/test.png?imageMogr2/auto-orient/interlace/1', + }) + }) + + it('tencentCloud iradius (circle crop)', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + const generated = tencentCloud().getImage('/test.png', { + modifiers: { iradius: 100 }, + ...providerOptions, + }, getEmptyContext()) + expect(generated).toMatchObject({ + url: 'https://example.cos.com/test.png?imageMogr2/iradius/100', + }) + }) + + it('tencentCloud combined operations', () => { + const providerOptions = { + baseURL: 'https://example.cos.com', + } + const generated = tencentCloud().getImage('/test.png', { + modifiers: { + width: 800, + height: 600, + fit: 'cover', + quality: 85, + format: 'webp', + sharpen: 50, + interlace: true, + }, + ...providerOptions, + }, getEmptyContext()) + expect(generated).toMatchObject({ + url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/!800x600r/quality/85/format/webp/sharpen/50/interlace/1', + }) + }) + it('strapi', () => { const test = { '': 'http://localhost:1337/uploads/test.png', diff --git a/test/providers.ts b/test/providers.ts index 122d0183e..6cb920351 100644 --- a/test/providers.ts +++ b/test/providers.ts @@ -29,6 +29,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png' }, storyblok: { url: 'https://a.storyblok.com/test.png' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png' }, + tencentCloud: { url: 'https://example.cos.com/test.png' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=1536&q=100' }, wagtail: { url: '329944/original|format-webp|webpquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4' }, @@ -71,6 +72,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png?width=200' }, storyblok: { url: 'https://a.storyblok.com/test.png/m/200x0' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png?width=200' }, + tencentCloud: { url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/200x' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=640&q=100' }, wagtail: { url: '329944/width-200|format-webp|webpquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4?width=200' }, @@ -112,6 +114,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png?height=200' }, storyblok: { url: 'https://a.storyblok.com/test.png/m/0x200' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png?height=200' }, + tencentCloud: { url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/x200' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=1536&q=100' }, wagtail: { url: '329944/height-200|format-webp|webpquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4?height=200' }, @@ -153,6 +156,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png?width=200&height=200' }, storyblok: { url: 'https://a.storyblok.com/test.png/m/200x200' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png?width=200&height=200' }, + tencentCloud: { url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/200x200' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=640&q=100' }, wagtail: { url: '329944/fill-200x200-c0|format-webp|webpquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4?width=200&height=200' }, @@ -194,6 +198,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png?width=200&height=200&func=fit' }, storyblok: { url: 'https://a.storyblok.com/test.png/m/fit-contain/200x200' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png?width=200&height=200&resize=contain' }, + tencentCloud: { url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/200x200' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=640&q=100' }, wagtail: { url: '329944/fill-200x200-c0|format-webp|webpquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4?width=200&height=200&fit=contain' }, @@ -235,6 +240,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png?width=200&height=200&func=fit&force_format=jpeg' }, storyblok: { url: 'https://a.storyblok.com/test.png/m/fit-contain/200x200/filters:format(jpeg)' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png?width=200&height=200&resize=contain&format=jpeg' }, + tencentCloud: { url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/200x200/format/jpg' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=640&q=100' }, wagtail: { url: '329944/fill-200x200-c0|format-jpeg|jpegquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4?width=200&height=200&fit=contain&format=jpg' }, From 7bb8fff206c28d4da1d4c2683e4ba1bbb952bdf8 Mon Sep 17 00:00:00 2001 From: wenyiqing Date: Mon, 23 Mar 2026 20:05:11 +0800 Subject: [PATCH 2/2] feat: add edgeonePages image provider --- .../{tencent-cloud.md => edgeone-pages.md} | 46 +++---- .../{tencent-cloud.vue => edgeone-pages.vue} | 16 +-- playground/app/providers.ts | 16 +-- playground/nuxt.config.ts | 4 +- src/provider.ts | 2 +- .../{tencentCloud.ts => edgeonePages.ts} | 28 ++--- test/e2e/__snapshots__/edgeonePages.json5 | 18 +++ test/e2e/__snapshots__/tencentCloud.json5 | 18 --- test/nuxt/providers.test.ts | 116 +++++++++++------- test/providers.ts | 12 +- 10 files changed, 148 insertions(+), 128 deletions(-) rename docs/content/3.providers/{tencent-cloud.md => edgeone-pages.md} (62%) rename playground/app/pages/{tencent-cloud.vue => edgeone-pages.vue} (95%) rename src/runtime/providers/{tencentCloud.ts => edgeonePages.ts} (84%) create mode 100644 test/e2e/__snapshots__/edgeonePages.json5 delete mode 100644 test/e2e/__snapshots__/tencentCloud.json5 diff --git a/docs/content/3.providers/tencent-cloud.md b/docs/content/3.providers/edgeone-pages.md similarity index 62% rename from docs/content/3.providers/tencent-cloud.md rename to docs/content/3.providers/edgeone-pages.md index 3c1939c90..8e02af1b4 100644 --- a/docs/content/3.providers/tencent-cloud.md +++ b/docs/content/3.providers/edgeone-pages.md @@ -1,38 +1,38 @@ --- -title: Tencent Cloud -description: Use Tencent Cloud COS imageMogr2 for image processing. +title: EdgeOne Pages +description: Use EdgeOne Pages imageMogr2 for image processing. links: - label: Source icon: i-simple-icons-github - to: https://github.com/nuxt/image/blob/main/src/runtime/providers/tencentCloud.ts + to: https://github.com/nuxt/image/blob/main/src/runtime/providers/edgeonePages.ts size: xs --- -Integration with Tencent Cloud COS Cloud Infinite (CI) image processing (`imageMogr2`). Supports resizing, cropping, rotation, format conversion, quality control, Gaussian blur, sharpening, and more. +Integration with EdgeOne Pages image processing (`imageMogr2`). Supports resizing, cropping, rotation, format conversion, quality control, Gaussian blur, sharpening, and more. ## Setup -Set the bucket domain as `baseURL` in `nuxt.config.ts`: +Set the site domain as `baseURL` in `nuxt.config.ts`: ```ts [nuxt.config.ts] export default defineNuxtConfig({ image: { - tencentCloud: { - baseURL: 'https://.cos..myqcloud.com' + edgeonePages: { + baseURL: 'https://.edgeone.app' } } }) ``` ::note -`baseURL` should point to a publicly accessible COS bucket domain (or a bound CDN domain). No trailing slash is needed. +`baseURL` should point to a publicly accessible EdgeOne Pages domain. No trailing slash is needed. :: ## Basic Usage ```vue x` | Proportional scaling, affected by `fit` | | `fit` | thumbnail suffix | `contain` → `x`, `cover` → `!xr`, `fill` → `x!` | @@ -54,11 +54,11 @@ All 7 standard NuxtImg modifiers are mapped to COS imageMogr2: | `background` | `/pad/1/color/` | Used with scaling, fills background color | | `blur` | `/blur/x` | Gaussian blur | -## COS Extended Modifiers +## Extended Modifiers -Pass Tencent Cloud-specific image processing parameters via the `:modifiers` prop: +Pass EdgeOne Pages-specific image processing parameters via the `:modifiers` prop: -| Modifier | COS Mapping | Description | +| Modifier | Mapping | Description | |---|---|---| | `crop` | `/crop/x` | Regular crop (independent of scaling) | | `gravity` | `/gravity/` | Crop anchor: center, north, south, west, east, northwest, etc. | @@ -78,7 +78,7 @@ Pass Tencent Cloud-specific image processing parameters via the `:modifiers` pro ```vue @@ -105,7 +105,7 @@ Generated URL: `?imageMogr2/crop/300x300/gravity/center` ```vue @@ -117,7 +117,7 @@ Generated URL: `?imageMogr2/rotate/90/sharpen/70/strip` ```vue @@ -140,10 +140,4 @@ Generated URL: `?imageMogr2/scrop/200x200` ## References -- [COS imageMogr2 Scaling](https://cloud.tencent.com/document/product/436/44880) -- [COS imageMogr2 Cropping](https://cloud.tencent.com/document/product/436/44881) -- [COS imageMogr2 Rotation](https://cloud.tencent.com/document/product/436/44882) -- [COS imageMogr2 Format Conversion](https://cloud.tencent.com/document/product/436/44883) -- [COS imageMogr2 Quality](https://cloud.tencent.com/document/product/436/44884) -- [COS imageMogr2 Gaussian Blur](https://cloud.tencent.com/document/product/436/44885) -- [COS imageMogr2 Sharpen](https://cloud.tencent.com/document/product/436/44886) +- [EdgeOne Pages Image Processing](https://edgeone.ai/document/162498) diff --git a/playground/app/pages/tencent-cloud.vue b/playground/app/pages/edgeone-pages.vue similarity index 95% rename from playground/app/pages/tencent-cloud.vue rename to playground/app/pages/edgeone-pages.vue index 47f22ff84..80ba1e0ac 100644 --- a/playground/app/pages/tencent-cloud.vue +++ b/playground/app/pages/edgeone-pages.vue @@ -3,11 +3,11 @@

- Tencent Cloud · COS + EdgeOne Pages

Image Processing Playground

- Enter your COS bucket domain and object path to compare the original image with the optimized result from the Nuxt Image tencentCloud provider. + Enter your EdgeOne Pages domain and image path to compare the original image with the optimized result from the Nuxt Image edgeonePages provider.

@@ -16,10 +16,10 @@

Parameters

- +
@@ -167,7 +167,7 @@ (800) const height = ref(500) const fit = ref<'cover' | 'contain' | 'fill' | ''>('contain') @@ -233,7 +233,7 @@ watchEffect(() => { cfg.public = cfg.public || {} cfg.public.image = cfg.public.image || {} cfg.public.image.providers = cfg.public.image.providers || {} - cfg.public.image.providers.tencentCloud = { + cfg.public.image.providers.edgeonePages = { baseURL: baseURL.value, } }) diff --git a/playground/app/providers.ts b/playground/app/providers.ts index 9450bd532..c66a42c79 100644 --- a/playground/app/providers.ts +++ b/playground/app/providers.ts @@ -1116,42 +1116,42 @@ export const providers: Provider[] = [ }, ], }, - // Tencent Cloud + // EdgeOne Pages { - name: 'tencentCloud', + name: 'edgeonePages', samples: [ { - src: '/images/cases/case3.png', + src: '/ssg-img.png', width: 400, height: 300, fit: 'contain', }, { - src: '/images/cases/case2.png', + src: '/ssg-img.png', width: 400, height: 300, fit: 'cover', }, { - src: '/images/cases/case4.png', + src: '/ssg-img.png', width: 400, height: 300, fit: 'fill', }, { - src: '/images/cases/case3.png', + src: '/ssg-img.png', width: 300, quality: 80, format: 'webp', }, { - src: '/images/cases/case2.png', + src: '/ssg-img.png', modifiers: { rotate: 90, }, }, { - src: '/images/cases/case4.png', + src: '/ssg-img.png', modifiers: { blur: 15, quality: 50, diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index fca3ee031..ca179808b 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -111,8 +111,8 @@ export default defineNuxtConfig({ supabase: { baseURL: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt', }, - tencentCloud: { - baseURL: 'https://saas-starter.edgeone.app', + edgeonePages: { + baseURL: 'https://nuxt-mix-template.edgeone.site', }, unsplash: {}, vercel: { diff --git a/src/provider.ts b/src/provider.ts index 1f8db3acf..9e8510a76 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -47,7 +47,7 @@ export const BuiltInProviders = [ 'strapi', 'strapi5', 'supabase', - 'tencentCloud', + 'edgeonePages', 'twicpics', 'unsplash', 'uploadcare', diff --git a/src/runtime/providers/tencentCloud.ts b/src/runtime/providers/edgeonePages.ts similarity index 84% rename from src/runtime/providers/tencentCloud.ts rename to src/runtime/providers/edgeonePages.ts index 3044a1105..d996e441d 100644 --- a/src/runtime/providers/tencentCloud.ts +++ b/src/runtime/providers/edgeonePages.ts @@ -2,7 +2,7 @@ import { joinURL } from 'ufo' import type { ImageModifiers } from '@nuxt/image' import { defineProvider } from '../utils/provider' -interface TencentCloudModifiers extends ImageModifiers { +interface EdgeOnePagesModifiers extends ImageModifiers { /** Regular crop: 'x' e.g. '300x400' */ crop: string /** Crop/scale gravity: center, north, south, west, east, northwest, northeast, southwest, southeast */ @@ -29,12 +29,12 @@ interface TencentCloudModifiers extends ImageModifiers { pad: boolean | number } -/** Options for the Tencent Cloud COS image provider. */ -export interface TencentCloudOptions { - /** Base URL of the COS bucket (e.g. `https://example.cos.ap-guangzhou.myqcloud.com`). */ +/** Options for the EdgeOne Pages image provider. */ +export interface EdgeOnePagesOptions { + /** Base URL of the EdgeOne Pages site (e.g. `https://domain`). */ baseURL: string /** Optional image processing modifiers. */ - modifiers?: Partial + modifiers?: Partial } const fitMap: Record = { @@ -45,8 +45,8 @@ const fitMap: Record = { outside: 'r', // same as cover } -/** Encode a hex color string to URL-safe Base64 for COS background fill. */ -function encodeCosColor(color: string): string { +/** Encode a hex color string to URL-safe Base64 for background fill. */ +function encodeColor(color: string): string { const hex = color.startsWith('#') ? color : `#${color}` if (typeof globalThis.btoa === 'function') { return globalThis.btoa(hex).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '') @@ -55,17 +55,17 @@ function encodeCosColor(color: string): string { } /** - * Tencent Cloud COS image provider. + * EdgeOne Pages image provider. * - * Transforms images via the COS `imageMogr2` API, supporting resize, + * Transforms images via the `imageMogr2` API, supporting resize, * crop, rotate, blur, quality, format conversion and more. * - * @see https://cloud.tencent.com/document/product/460/6924 + * @see https://edgeone.ai/document/162498 */ -export default defineProvider({ +export default defineProvider({ getImage: (src, { modifiers = {}, baseURL }) => { if (!baseURL) { - throw new Error('Tencent Cloud provider requires baseURL to be set') + throw new Error('EdgeOne Pages provider requires baseURL to be set') } const { @@ -88,7 +88,7 @@ export default defineProvider({ strip, interlace, pad, - } = modifiers as Partial + } = modifiers as Partial const operations: string[] = [] @@ -116,7 +116,7 @@ export default defineProvider({ if (pad || (background && (width || height))) { operations.push('pad/1') if (background) { - operations.push(`color/${encodeCosColor(background)}`) + operations.push(`color/${encodeColor(background)}`) } } diff --git a/test/e2e/__snapshots__/edgeonePages.json5 b/test/e2e/__snapshots__/edgeonePages.json5 new file mode 100644 index 000000000..77d07de5f --- /dev/null +++ b/test/e2e/__snapshots__/edgeonePages.json5 @@ -0,0 +1,18 @@ +{ + "requests": [ + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/blur/15x15", + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/rotate/90", + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/!400x300r", + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/300x/quality/80/format/webp", + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/400x300", + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/400x300!", + ], + "sources": [ + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/400x300", + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/!400x300r", + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/400x300!", + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/300x/quality/80/format/webp", + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/rotate/90", + "https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/blur/15x15", + ], +} \ No newline at end of file diff --git a/test/e2e/__snapshots__/tencentCloud.json5 b/test/e2e/__snapshots__/tencentCloud.json5 deleted file mode 100644 index e1fe9a58c..000000000 --- a/test/e2e/__snapshots__/tencentCloud.json5 +++ /dev/null @@ -1,18 +0,0 @@ -{ - "requests": [ - "https://saas-starter.edgeone.app/images/cases/case2.png?imageMogr2/rotate/90", - "https://saas-starter.edgeone.app/images/cases/case2.png?imageMogr2/thumbnail/!400x300r", - "https://saas-starter.edgeone.app/images/cases/case3.png?imageMogr2/thumbnail/300x/quality/80/format/webp", - "https://saas-starter.edgeone.app/images/cases/case3.png?imageMogr2/thumbnail/400x300", - "https://saas-starter.edgeone.app/images/cases/case4.png?imageMogr2/blur/15x15", - "https://saas-starter.edgeone.app/images/cases/case4.png?imageMogr2/thumbnail/400x300!", - ], - "sources": [ - "https://saas-starter.edgeone.app/images/cases/case3.png?imageMogr2/thumbnail/400x300", - "https://saas-starter.edgeone.app/images/cases/case2.png?imageMogr2/thumbnail/!400x300r", - "https://saas-starter.edgeone.app/images/cases/case4.png?imageMogr2/thumbnail/400x300!", - "https://saas-starter.edgeone.app/images/cases/case3.png?imageMogr2/thumbnail/300x/quality/80/format/webp", - "https://saas-starter.edgeone.app/images/cases/case2.png?imageMogr2/rotate/90", - "https://saas-starter.edgeone.app/images/cases/case4.png?imageMogr2/blur/15x15", - ], -} \ No newline at end of file diff --git a/test/nuxt/providers.test.ts b/test/nuxt/providers.test.ts index 3b884ed42..0ab25d19c 100644 --- a/test/nuxt/providers.test.ts +++ b/test/nuxt/providers.test.ts @@ -32,7 +32,7 @@ import storyblok from '../../dist/runtime/providers/storyblok' import strapi from '../../dist/runtime/providers/strapi' import strapi5 from '../../dist/runtime/providers/strapi5' import supabase from '../../dist/runtime/providers/supabase' -import tencentCloud from '../../dist/runtime/providers/tencentCloud' +import edgeonePages from '../../dist/runtime/providers/edgeonePages' import vercel from '../../dist/runtime/providers/vercel' import wagtail from '../../dist/runtime/providers/wagtail' import uploadcare from '../../dist/runtime/providers/uploadcare' @@ -559,140 +559,166 @@ describe('Providers', () => { } }) - it('tencentCloud', () => { + it('edgeonePages', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } for (const image of images) { const [src, modifiers] = image.args - const generated = tencentCloud().getImage(src, { modifiers, ...providerOptions }, getEmptyContext()) - expect(generated).toMatchObject(image.tencentCloud) + const generated = edgeonePages().getImage(src, { modifiers, ...providerOptions }, getEmptyContext()) + expect(generated).toMatchObject(image.edgeonePages) } + + const src = '/ssg-img.png' + + // no modifiers + expect(edgeonePages().getImage(src, { modifiers: {}, ...providerOptions }, getEmptyContext())) + .toMatchObject({ url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png' }) + + // width only + expect(edgeonePages().getImage(src, { modifiers: { width: 200 }, ...providerOptions }, getEmptyContext())) + .toMatchObject({ url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/200x' }) + + // height only + expect(edgeonePages().getImage(src, { modifiers: { height: 200 }, ...providerOptions }, getEmptyContext())) + .toMatchObject({ url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/x200' }) + + // width + height + expect(edgeonePages().getImage(src, { modifiers: { width: 200, height: 200 }, ...providerOptions }, getEmptyContext())) + .toMatchObject({ url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/200x200' }) + + // width + height + fit contain + expect(edgeonePages().getImage(src, { modifiers: { width: 200, height: 200, fit: 'contain' }, ...providerOptions }, getEmptyContext())) + .toMatchObject({ url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/200x200' }) + + // width + height + fit contain + format + expect(edgeonePages().getImage(src, { modifiers: { width: 200, height: 200, fit: 'contain', format: 'jpeg' }, ...providerOptions }, getEmptyContext())) + .toMatchObject({ url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/200x200/format/jpg' }) }) - it('tencentCloud cover fit', () => { + it('edgeonePages cover fit', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } - const generated = tencentCloud().getImage('/test.png', { + const generated = edgeonePages().getImage('/ssg-img.png', { modifiers: { width: 300, height: 200, fit: 'cover' }, ...providerOptions, }, getEmptyContext()) expect(generated).toMatchObject({ - url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/!300x200r', + url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/!300x200r', }) }) - it('tencentCloud fill fit', () => { + it('edgeonePages fill fit', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } - const generated = tencentCloud().getImage('/test.png', { + const generated = edgeonePages().getImage('/ssg-img.png', { modifiers: { width: 300, height: 200, fit: 'fill' }, ...providerOptions, }, getEmptyContext()) expect(generated).toMatchObject({ - url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/300x200!', + url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/300x200!', }) }) - it('tencentCloud blur', () => { + it('edgeonePages blur', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } - const generated = tencentCloud().getImage('/test.png', { + const generated = edgeonePages().getImage('/ssg-img.png', { modifiers: { blur: 10 }, ...providerOptions, }, getEmptyContext()) expect(generated).toMatchObject({ - url: 'https://example.cos.com/test.png?imageMogr2/blur/10x10', + url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/blur/10x10', }) }) - it('tencentCloud rotate', () => { + it('edgeonePages rotate', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } - const generated = tencentCloud().getImage('/test.png', { + const generated = edgeonePages().getImage('/ssg-img.png', { modifiers: { rotate: 90 }, ...providerOptions, }, getEmptyContext()) expect(generated).toMatchObject({ - url: 'https://example.cos.com/test.png?imageMogr2/rotate/90', + url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/rotate/90', }) }) - it('tencentCloud crop with gravity', () => { + it('edgeonePages crop with gravity', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } - const generated = tencentCloud().getImage('/test.png', { + const generated = edgeonePages().getImage('/ssg-img.png', { modifiers: { crop: '300x400', gravity: 'center' }, ...providerOptions, }, getEmptyContext()) expect(generated).toMatchObject({ - url: 'https://example.cos.com/test.png?imageMogr2/crop/300x400/gravity/center', + url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/crop/300x400/gravity/center', }) }) - it('tencentCloud sharpen and strip', () => { + it('edgeonePages sharpen and strip', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } - const generated = tencentCloud().getImage('/test.png', { + const generated = edgeonePages().getImage('/ssg-img.png', { modifiers: { sharpen: 70, strip: true }, ...providerOptions, }, getEmptyContext()) expect(generated).toMatchObject({ - url: 'https://example.cos.com/test.png?imageMogr2/sharpen/70/strip', + url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/sharpen/70/strip', }) }) - it('tencentCloud scrop (smart face crop)', () => { + it('edgeonePages scrop (smart face crop)', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } - const generated = tencentCloud().getImage('/test.png', { + const generated = edgeonePages().getImage('/ssg-img.png', { modifiers: { scrop: '200x200' }, ...providerOptions, }, getEmptyContext()) expect(generated).toMatchObject({ - url: 'https://example.cos.com/test.png?imageMogr2/scrop/200x200', + url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/scrop/200x200', }) }) - it('tencentCloud interlace and autoOrient', () => { + it('edgeonePages interlace and autoOrient', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } - const generated = tencentCloud().getImage('/test.png', { + const generated = edgeonePages().getImage('/ssg-img.png', { modifiers: { interlace: true, autoOrient: true }, ...providerOptions, }, getEmptyContext()) expect(generated).toMatchObject({ - url: 'https://example.cos.com/test.png?imageMogr2/auto-orient/interlace/1', + url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/auto-orient/interlace/1', }) }) - it('tencentCloud iradius (circle crop)', () => { + it('edgeonePages iradius (circle crop)', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } - const generated = tencentCloud().getImage('/test.png', { + const generated = edgeonePages().getImage('/ssg-img.png', { modifiers: { iradius: 100 }, ...providerOptions, }, getEmptyContext()) expect(generated).toMatchObject({ - url: 'https://example.cos.com/test.png?imageMogr2/iradius/100', + url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/iradius/100', }) }) - it('tencentCloud combined operations', () => { + it('edgeonePages combined operations', () => { const providerOptions = { - baseURL: 'https://example.cos.com', + baseURL: 'https://nuxt-mix-template.edgeone.site', } - const generated = tencentCloud().getImage('/test.png', { + const generated = edgeonePages().getImage('/ssg-img.png', { modifiers: { width: 800, height: 600, @@ -705,7 +731,7 @@ describe('Providers', () => { ...providerOptions, }, getEmptyContext()) expect(generated).toMatchObject({ - url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/!800x600r/quality/85/format/webp/sharpen/50/interlace/1', + url: 'https://nuxt-mix-template.edgeone.site/ssg-img.png?imageMogr2/thumbnail/!800x600r/quality/85/format/webp/sharpen/50/interlace/1', }) }) diff --git a/test/providers.ts b/test/providers.ts index 6cb920351..a82aaae10 100644 --- a/test/providers.ts +++ b/test/providers.ts @@ -29,7 +29,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png' }, storyblok: { url: 'https://a.storyblok.com/test.png' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png' }, - tencentCloud: { url: 'https://example.cos.com/test.png' }, + edgeonePages: { url: 'https://nuxt-mix-template.edgeone.site/test.png' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=1536&q=100' }, wagtail: { url: '329944/original|format-webp|webpquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4' }, @@ -72,7 +72,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png?width=200' }, storyblok: { url: 'https://a.storyblok.com/test.png/m/200x0' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png?width=200' }, - tencentCloud: { url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/200x' }, + edgeonePages: { url: 'https://nuxt-mix-template.edgeone.site/test.png?imageMogr2/thumbnail/200x' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=640&q=100' }, wagtail: { url: '329944/width-200|format-webp|webpquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4?width=200' }, @@ -114,7 +114,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png?height=200' }, storyblok: { url: 'https://a.storyblok.com/test.png/m/0x200' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png?height=200' }, - tencentCloud: { url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/x200' }, + edgeonePages: { url: 'https://nuxt-mix-template.edgeone.site/test.png?imageMogr2/thumbnail/x200' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=1536&q=100' }, wagtail: { url: '329944/height-200|format-webp|webpquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4?height=200' }, @@ -156,7 +156,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png?width=200&height=200' }, storyblok: { url: 'https://a.storyblok.com/test.png/m/200x200' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png?width=200&height=200' }, - tencentCloud: { url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/200x200' }, + edgeonePages: { url: 'https://nuxt-mix-template.edgeone.site/test.png?imageMogr2/thumbnail/200x200' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=640&q=100' }, wagtail: { url: '329944/fill-200x200-c0|format-webp|webpquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4?width=200&height=200' }, @@ -198,7 +198,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png?width=200&height=200&func=fit' }, storyblok: { url: 'https://a.storyblok.com/test.png/m/fit-contain/200x200' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png?width=200&height=200&resize=contain' }, - tencentCloud: { url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/200x200' }, + edgeonePages: { url: 'https://nuxt-mix-template.edgeone.site/test.png?imageMogr2/thumbnail/200x200' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=640&q=100' }, wagtail: { url: '329944/fill-200x200-c0|format-webp|webpquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4?width=200&height=200&fit=contain' }, @@ -240,7 +240,7 @@ export const images = [ cloudimage: { url: 'https://demo.cloudimg.io/v7/_sl_/test.png?width=200&height=200&func=fit&force_format=jpeg' }, storyblok: { url: 'https://a.storyblok.com/test.png/m/fit-contain/200x200/filters:format(jpeg)' }, supabase: { url: 'https://ovzjdhllnxrizgszqlsi.supabase.co/storage/v1/render/image/public/nuxt/test.png?width=200&height=200&resize=contain&format=jpeg' }, - tencentCloud: { url: 'https://example.cos.com/test.png?imageMogr2/thumbnail/200x200/format/jpg' }, + edgeonePages: { url: 'https://nuxt-mix-template.edgeone.site/test.png?imageMogr2/thumbnail/200x200/format/jpg' }, vercel: { url: '/_vercel/image?url=%2Ftest.png&w=640&q=100' }, wagtail: { url: '329944/fill-200x200-c0|format-jpeg|jpegquality-70' }, directus: { url: '/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4?width=200&height=200&fit=contain&format=jpg' },