### Install Dependencies and Start Development Server Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Navigate to the demo directory, install dependencies using pnpm, and start the development server for local testing. ```bash cd demo pnpm install pnpm dev ``` -------------------------------- ### Example CDN Configuration Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md JSON configuration for the 'example-cdn' provider, mapping the provider name to its display name and a demo image URL. ```json // examples.json { "example-cdn": [ "Example CDN", "https://example-cdn.com/demo-image.jpg" ] } ``` -------------------------------- ### Install Unpic via npm Source: https://github.com/ascorbic/unpic/blob/main/README.md Install the Unpic library using npm for use in Node.js projects. ```sh npm install unpic ``` -------------------------------- ### Comprehensive CDN Provider Tests Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Unit tests for an example CDN provider, covering URL extraction, generation, transformation, and error handling. Ensure all operations and edge cases are tested. ```typescript // example-cdn.test.ts import { assertEquals } from "jsr:@std/assert"; import { extract, generate, transform } from "./example-cdn.ts"; import { assertEqualIgnoringQueryOrder } from "../test-utils.ts"; const img = "https://example-cdn.com/image.jpg"; Deno.test("Example CDN", async (t) => { // Test extraction await t.step("should extract operations from URL", () => { const url = `${img}?w=300&h=200&q=80&fmt=webp&specialCrop=smart`; const result = extract(url); assertEquals(result, { src: img, operations: { width: 300, height: 200, quality: 80, format: "webp", specialCrop: "smart", }, options: { baseUrl: "https://example-cdn.com", }, }); }); // Test URL generation await t.step("should generate URL with operations", () => { const result = generate(img, { width: 400, height: 300, quality: 90, specialCrop: "center", }); assertEqualIgnoringQueryOrder( result, `${img}?w=400&h=300&q=90&specialCrop=center`, ); }); // Test transformation await t.step("should transform existing URL", () => { const url = `${img}?w=300&h=200`; const result = transform(url, { width: 500, blur: 5, }); assertEqualIgnoringQueryOrder( result, `${img}?w=500&h=200&blur=5`, ); }); // Test error cases await t.step("should handle invalid URLs", () => { const result = extract("invalid-url"); assertEquals(result, null); }); // Test relative URLs await t.step("should handle relative URLs", () => { const result = generate("/image.jpg", { width: 300 }); assertEqualIgnoringQueryOrder( result, "/image.jpg?w=300", ); }); }); ``` -------------------------------- ### Get CDN Transformer Function Source: https://context7.com/ascorbic/unpic/llms.txt Retrieve a synchronous `transform` function for a given CDN identifier using `getTransformerForCdn`. This is useful when the provider is known beforehand. Returns `undefined` for unsupported identifiers. ```ts import { getTransformerForCdn } from "unpic"; const shopifyTransform = getTransformerForCdn("shopify"); if (shopifyTransform) { const url = shopifyTransform( "https://cdn.shopify.com/static/sample-images/bath.jpeg", { width: 600, height: 400, crop: "center" }, ); console.log(url); // → "https://cdn.shopify.com/static/sample-images/bath.jpeg?width=600&height=400&crop=center" } // Returns undefined for unsupported/invalid CDN identifiers const none = getTransformerForCdn(false); // → undefined ``` -------------------------------- ### Provider Configuration Argument: V3 vs V4 Source: https://github.com/ascorbic/unpic/blob/main/UPGRADING.md Demonstrates how provider-specific options are passed. Version 4 uses the third argument for configuration, while v3 used `cdnOptions`. ```typescript // Version 3 transformUrl({ url: "image.jpg", width: 800, cdn: "cloudinary", cdnOptions: { cloudinary: { cloudName: "demo", }, }, }); // Version 4 transformUrl( { url: "image.jpg", width: 800, provider: "cloudinary", }, {}, // operations (empty in this case) { cloudinary: { cloudName: "demo", }, }, ); ``` -------------------------------- ### Running Deno Tests Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Commands for executing Deno tests, including running all tests, specific provider tests, and E2E tests with network access. ```bash # Run all tests denp test # Run tests for a specific provider denp test src/providers/example-cdn.test.ts # Run E2E tests. These need network access. denp test --allow-net e2e.test.ts ``` -------------------------------- ### Deno Development Commands Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Essential Deno commands for project development, including running tests, type checking, and code formatting. ```bash # Run tests denp test # Run tests with watch mode denp test --watch # Type checking denp check # Format code denp fmt ``` -------------------------------- ### Direct Provider Imports for Tree-Shaking Source: https://github.com/ascorbic/unpic/blob/main/UPGRADING.md Demonstrates importing providers directly from 'unpic/providers' in v4. This improves tree-shaking by allowing only the necessary provider code to be included. ```typescript import { transform } from "unpic/providers/shopify"; const url = transform( "https://cdn.shopify.com/image.jpg", { width: 800, crop: "center", // Provider-specific options available directly }, ); ``` -------------------------------- ### Import Unpic from JSR for Deno Source: https://context7.com/ascorbic/unpic/llms.txt Import the library for Deno environments from JSR. ```ts import { transformUrl, parseUrl, getProviderForUrl } from "jsr:@unpic/lib"; ``` -------------------------------- ### Run End-to-End Tests Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Execute end-to-end tests using Deno, ensuring providers work with real CDN endpoints. This command requires network access. ```bash deno test --allow-net e2e.test.ts ``` -------------------------------- ### URL Parameter Handling Patterns Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Illustrates different URL structures for handling parameters, including standard query parameters, path segments, and custom separators. ```typescript // Standard query parameters // https://example.com/image.jpg?width=100&height=200 { kvSeparator: "=", paramSeparator: "&" } ``` ```typescript // Path segments // https://example.com/image/w_100/h_200/image.jpg { kvSeparator: "_", paramSeparator: "/" } ``` ```typescript // Custom separators // https://example.com/image:w=100,h=200/image.jpg { kvSeparator: "=", paramSeparator: "," } ``` -------------------------------- ### Replace URL Delegation with Fallback System: V3 vs V4 Source: https://github.com/ascorbic/unpic/blob/main/UPGRADING.md Illustrates the shift from URL delegation (recursive checking) in v3 to an explicit fallback system in v4 for handling unrecognized URLs. ```typescript // Version 3 (with delegation) transformUrl({ url: "/_next/image?url=https://example.com/image.jpg&w=800", width: 1200, recursive: true, // would try to use the source image's CDN }); // Version 4 (with fallback) transformUrl({ url: "https://example.com/image.jpg", width: 1200, fallback: "nextjs", // will use Next.js image optimization if URL isn't recognized }); // Or use a different fallback provider transformUrl( { url: "https://example.com/image.jpg", width: 1200, fallback: "cloudinary", // use Cloudinary for unrecognized URLs }, {}, { cloudinary: { cloudName: "demo", }, }, ); ``` -------------------------------- ### Async API for Dynamic Provider Imports Source: https://context7.com/ascorbic/unpic/llms.txt Use the `unpic/async` submodule for async versions of core functions that dynamically import only the required provider module. This is ideal for server-side rendering or edge functions to minimize cold-start bundle size. ```ts import { transformUrl, getTransformerForProvider, getExtractorForProvider, getGeneratorForProvider, getModuleForProvider, } from "unpic/async"; // Async transformUrl: dynamically loads the matched provider module const url = await transformUrl( "https://images.unsplash.com/photo-123", { width: 800, height: 600, quality: 80 }, ); // → "https://images.unsplash.com/photo-123?w=800&h=600&fit=min&auto=format&q=80" // Load a specific provider module on demand const transformer = await getTransformerForProvider("cloudinary"); if (transformer) { const result = transformer( "https://res.cloudinary.com/demo/image/upload/sample.jpg", { width: 300, height: 300, c: "fill" }, ); console.log(result); } // Get just the extractor for a known provider const extractor = await getExtractorForProvider("imgix"); if (extractor) { const parsed = extractor("https://demo.imgix.net/image.jpg?w=800&h=600&fit=crop"); console.log(parsed); // { src: "https://demo.imgix.net/image.jpg", operations: { w: 800, h: 600, fit: "crop", auto: "format" } } } // Load the full module (generate + extract + transform) for a provider const module = await getModuleForProvider("netlify"); const generated = module?.generate( "https://example.com/image.jpg", { width: 600, height: 400 }, { baseUrl: "https://my-site.netlify.app" }, ); ``` -------------------------------- ### Import transformUrl in Deno Source: https://github.com/ascorbic/unpic/blob/main/README.md Import the transformUrl function from the unpic library using JSR for use in Deno. ```ts import { transformUrl } from "jsr:@unpic/lib"; ``` -------------------------------- ### Configure Operations Handlers - Query Style Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Configure `createOperationsHandlers` for URLs using query parameters (e.g., `?w=100&h=200`). Specifies key mappings, defaults, and separators. ```typescript // Query parameters: ?width=100&height=200 const queryStyle = createOperationsHandlers({ keyMap: { width: "w", height: "h", quality: "q", format: "fmt", }, defaults: { quality: 80, }, kvSeparator: "=", paramSeparator: "&", }); ``` -------------------------------- ### Specify Provider Options and Fallback Source: https://github.com/ascorbic/unpic/blob/main/README.md Configure provider-specific options, like 'cloudName' for Cloudinary, and specify a fallback provider. These options are passed to the respective CDN services. ```ts const url = transformUrl( src, { width: 800, height: 600, fallback: "cloudinary", }, { shopify: { crop: "left", }, }, { cloudinary: { cloudName: "demo", }, }, ); ``` -------------------------------- ### Async API - getModuleForProvider Source: https://context7.com/ascorbic/unpic/llms.txt Asynchronously retrieves the full module (generate, extract, transform) for a specific provider. ```APIDOC ## Async getModuleForProvider ### Description Dynamically loads and returns the complete module for a given provider, including `generate`, `extract`, and `transform` functions. This allows for accessing all functionalities of a provider on demand. ### Usage ```ts import { getModuleForProvider } from "unpic/async"; const module = await getModuleForProvider("netlify"); const generated = module?.generate( "https://example.com/image.jpg", { width: 600, height: 400 }, { baseUrl: "https://my-site.netlify.app" }, ); ``` ``` -------------------------------- ### Cloudinary Provider Direct Import Source: https://context7.com/ascorbic/unpic/llms.txt Import and use the transform function directly from the Cloudinary provider for image URL manipulation. ```APIDOC ## Cloudinary Provider Transform Function ### Description Provides direct access to the `transform` function for the Cloudinary provider. This function allows for manipulating image URLs according to Cloudinary's CDN specifications. ### Usage ```ts import { transform as cloudinaryTransform } from "unpic/providers/cloudinary"; const url = cloudinaryTransform( "https://res.cloudinary.com/demo/image/upload/sample.jpg", { width: 500, height: 500, c: "thumb", g: "face", f: "webp" }, ); // → "https://res.cloudinary.com/demo/image/upload/w_500,h_500,c_thumb,g_face,f_webp/sample.jpg" ``` ``` -------------------------------- ### Direct Shopify Provider Import Source: https://context7.com/ascorbic/unpic/llms.txt Import only the Shopify provider directly from its subpath for tree-shaking. This exposes `generate`, `extract`, and `transform` functions with full type safety for the Shopify provider. ```ts import { transform, generate, extract } from "unpic/providers/shopify"; // transform: extract existing transforms then apply new ones const transformed = transform( "https://cdn.shopify.com/static/sample-images/bath_800x600_crop_center.jpeg", { width: 400, height: 300, crop: "top" }, ); // → "https://cdn.shopify.com/static/sample-images/bath.jpeg?width=400&height=300&crop=top" // generate: build a CDN URL from a clean source URL + operations const generated = generate( "https://cdn.shopify.com/static/sample-images/bath.jpeg", { width: 1200, height: 800, crop: "center" }, ); // → "https://cdn.shopify.com/static/sample-images/bath.jpeg?width=1200&height=800&crop=center" // extract: decompose an existing CDN URL into src + operations const extracted = extract( "https://cdn.shopify.com/static/sample-images/bath_400x300_crop_center.jpeg", ); console.log(extracted); // { src: "https://cdn.shopify.com/static/sample-images/bath.jpeg", operations: { width: 400, height: 300, crop: "center" } } ``` ```ts // Cloudinary direct import import { transform as cloudinaryTransform } from "unpic/providers/cloudinary"; const url = cloudinaryTransform( "https://res.cloudinary.com/demo/image/upload/sample.jpg", { width: 500, height: 500, c: "thumb", g: "face", f: "webp" }, ); // → "https://res.cloudinary.com/demo/image/upload/w_500,h_500,c_thumb,g_face,f_webp/sample.jpg" ``` -------------------------------- ### Implement Core Functions - Generate Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Implement the `URLGenerator` function to create a new URL with specified operations. It takes a source URL, operations, and optional options, then uses `operationsGenerator` to build the final URL. ```typescript // Generate new URL with operations export const generate: URLGenerator<"example-cdn"> = ( src, operations, options = {}, ) => { const url = toUrl(src, options.baseUrl); url.search = operationsGenerator(operations); return toCanonicalUrlString(url); }; ``` -------------------------------- ### Async API - transformUrl Source: https://context7.com/ascorbic/unpic/llms.txt Asynchronously transforms an image URL by dynamically importing the necessary provider module. ```APIDOC ## Async transformUrl ### Description Dynamically imports the matched provider module to transform an image URL. This is useful for server-side rendering or edge functions to minimize cold-start bundle size. ### Usage ```ts import { transformUrl } from "unpic/async"; const url = await transformUrl( "https://images.unsplash.com/photo-123", { width: 800, height: 600, quality: 80 }, ); // → "https://images.unsplash.com/photo-123?w=800&h=600&fit=min&auto=format&q=80" ``` ``` -------------------------------- ### Shopify Provider Direct Import Source: https://context7.com/ascorbic/unpic/llms.txt Import and use the transform, generate, and extract functions directly from the Shopify provider for type-safe operations. ```APIDOC ## Shopify Provider Functions ### Description Provides direct access to `transform`, `generate`, and `extract` functions for the Shopify provider. These functions allow for manipulating image URLs according to Shopify's CDN specifications. ### Usage ```ts import { transform, generate, extract } from "unpic/providers/shopify"; // Example: transform an existing URL const transformed = transform( "https://cdn.shopify.com/static/sample-images/bath_800x600_crop_center.jpeg", { width: 400, height: 300, crop: "top" }, ); // → "https://cdn.shopify.com/static/sample-images/bath.jpeg?width=400&height=300&crop=top" // Example: generate a new CDN URL const generated = generate( "https://cdn.shopify.com/static/sample-images/bath.jpeg", { width: 1200, height: 800, crop: "center" }, ); // → "https://cdn.shopify.com/static/sample-images/bath.jpeg?width=1200&height=800&crop=center" // Example: extract operations from an existing URL const extracted = extract( "https://cdn.shopify.com/static/sample-images/bath_400x300_crop_center.jpeg", ); console.log(extracted); // { src: "https://cdn.shopify.com/static/sample-images/bath.jpeg", operations: { width: 400, height: 300, crop: "center" } } ``` ``` -------------------------------- ### Implement Core Functions - Transform Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Implement the `URLTransformer` function using `createExtractAndGenerate`. This utility combines the `extract` and `generate` functions to transform an existing URL with new operations in a single step. ```typescript // Transform existing URL with new operations export const transform: URLTransformer<"example-cdn"> = createExtractAndGenerate(extract, generate); ``` -------------------------------- ### Import and Use Shopify Provider Directly Source: https://github.com/ascorbic/unpic/blob/main/README.md Import the 'transform' function specifically from the Shopify provider to reduce bundle size. This allows direct application of Shopify-specific transformations. ```ts import { transform } from "unpic/providers/shopify"; const url = transform( "https://cdn.shopify.com/static/sample-images/bath.jpeg", { width: 800, height: 600, crop: "center", }, ); ``` -------------------------------- ### SupportedProviders Registry Usage Source: https://context7.com/ascorbic/unpic/llms.txt Access the `SupportedProviders` typed record to map `ImageCdn` identifiers to human-readable display names. This is useful for building UI dropdowns, logging, or diagnostics. ```ts import { SupportedProviders } from "unpic"; console.log(SupportedProviders["imgix"]); // → "Imgix" console.log(SupportedProviders["cloudflare_images"]); // → "Cloudflare Images" console.log(SupportedProviders["kontent.ai"]); // → "Kontent.ai" console.log(SupportedProviders["scene7"]); // → "Adobe Dynamic Media / Scene7" // Enumerate all supported providers Object.entries(SupportedProviders).forEach(([id, name]) => { console.log(`${id}: ${name}`); }); // appwrite: Appwrite // astro: Astro image service // builder.io: Builder.io // bunny: Bunny.net // cloudflare: Cloudflare // ... (28 providers total) ``` -------------------------------- ### Configure Operations Handlers - Path Style Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Configure `createOperationsHandlers` for URLs using path segments (e.g., `/w_100/h_200/q_80`). Defines key mappings, defaults, and separators suitable for path-based operations. ```typescript // Path segments: /w_100/h_200/q_80 const pathStyle = createOperationsHandlers({ keyMap: { width: "w", height: "h", quality: "q", format: "fmt", }, defaults: { quality: 80, }, kvSeparator: "_", paramSeparator: "/", }); ``` -------------------------------- ### Import transformUrl in Node.js Source: https://github.com/ascorbic/unpic/blob/main/README.md Import the transformUrl function from the unpic library for use in Node.js. ```ts import { transformUrl } from "unpic"; ``` -------------------------------- ### SupportedProviders Registry Source: https://context7.com/ascorbic/unpic/llms.txt Provides a typed record of all supported image CDN providers and their human-readable names. ```APIDOC ## SupportedProviders Registry ### Description A typed record that maps each `ImageCdn` identifier to its corresponding display name. This is useful for UI elements like dropdowns, logging, or diagnostic purposes. ### Usage ```ts import { SupportedProviders } from "unpic"; // Accessing a specific provider's name console.log(SupportedProviders["imgix"]); // → "Imgix" console.log(SupportedProviders["cloudflare_images"]); // → "Cloudflare Images" // Enumerating all supported providers Object.entries(SupportedProviders).forEach(([id, name]) => { console.log(`${id}: ${name}`); }); // Example output: // appwrite: Appwrite // astro: Astro image service // ... (28 providers total) ``` ``` -------------------------------- ### Detect CDN Provider for URL Source: https://context7.com/ascorbic/unpic/llms.txt Use `getProviderForUrl` to detect the CDN provider from a full URL. For more specific detection, use `getProviderForUrlByDomain` or `getProviderForUrlByPath`. Returns the provider identifier or `false` if not recognized. ```ts import { getProviderForUrl, getProviderForUrlByDomain, getProviderForUrlByPath } from "unpic"; // Detect by full URL getProviderForUrl("https://images.unsplash.com/photo-123"); // → "imgix" getProviderForUrl("https://cdn.shopify.com/s/files/1/image.jpg"); // → "shopify" getProviderForUrl("https://res.cloudinary.com/demo/image/upload/sample.jpg"); // → "cloudinary" getProviderForUrl("https://example.com/image.jpg"); // → false // Detect using only domain matching getProviderForUrlByDomain("https://a.storyblok.com/f/image.jpg"); // → "storyblok" // Detect using only path matching (works with relative URLs) getProviderForUrlByPath("/_next/image?url=%2Fprofile.png&w=200&q=75"); // → "nextjs" getProviderForUrlByPath("/_vercel/image?url=...&w=400&q=75"); // → "vercel" getProviderForUrlByPath("/_ipx/w_800,h_600/image.jpg"); // → "ipx" ``` -------------------------------- ### Implement Core Functions - Extract Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Implement the `URLExtractor` function to parse a URL, extract operations using `operationsParser`, and return the source URL and operations. Handles base URL configuration. ```typescript // Extract operations from existing URL export const extract: URLExtractor<"example-cdn"> = (url) => { const parsedUrl = toUrl(url); const operations = operationsParser(parsedUrl); parsedUrl.search = ""; return { src: toCanonicalUrlString(parsedUrl), operations, options: { baseUrl: parsedUrl.origin, }, }; }; ``` -------------------------------- ### New Fallback Provider Feature Source: https://github.com/ascorbic/unpic/blob/main/UPGRADING.md Introduces the new fallback provider system in v4, which allows specifying a provider to use when a URL is not recognized. Useful for handling user-provided or unknown URLs. ```typescript transformUrl({ url: "https://example.com/image.jpg", width: 800, fallback: "netlify", // Use Netlify if URL isn't recognized }); ``` -------------------------------- ### URL Manipulation Utilities Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Use these utilities to convert strings to URL objects, canonicalize URLs back to strings, and manipulate URL paths. Handles relative URLs and ensures consistent path formatting. ```typescript const url = toUrl("https://example.com/image.jpg"); // Convert back to string, preserving relativeness const urlString = toCanonicalUrlString(url); // Path manipulation const cleanPath = stripLeadingSlash("/path/to/image.jpg"); const formattedPath = addTrailingSlash("path/to/image"); ``` -------------------------------- ### Provider Type Definitions Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md TypeScript interfaces for defining provider-specific operations and options. Extend these to add support for new image CDNs. ```typescript // types.ts export interface ProviderOperations { "example-cdn": ExampleCdnOperations; // ... } export interface ProviderOptions { "example-cdn": ExampleCdnOptions; // ... } ``` -------------------------------- ### Transform URL with Fallback Provider Source: https://github.com/ascorbic/unpic/blob/main/README.md Define a fallback provider to be used if the input URL is not recognized as a known CDN. This ensures transformations are applied even for unrecognized sources. ```ts const url = transformUrl( "https://example.com/image.jpg", { width: 800, height: 600, fallback: "netlify", }, ); ``` -------------------------------- ### Provider-specific operations and options with `transformUrl` Source: https://context7.com/ascorbic/unpic/llms.txt Each CDN provider offers specific operations and options that extend the base `Operations` interface. These can be passed to the `transformUrl` function to customize image transformations according to the provider's capabilities. ```APIDOC ## Provider-specific operations and options Each provider exposes typed operations and options that extend the base `Operations` interface. Pass provider-specific operations as the second argument and provider-level options (e.g., cloud name, base URL) as the third argument to `transformUrl`. Options for multiple providers can be passed simultaneously — only the matching provider's options will be applied. ### Usage ```ts import { transformUrl } from "unpic"; // Cloudinary: provider-specific operations (crop mode, gravity, effects) const cloudinaryUrl = transformUrl( { url: "https://res.cloudinary.com/demo/image/upload/sample.jpg", width: 800, height: 600, }, { cloudinary: { c: "fill", // crop mode g: "faces", // gravity e: "grayscale", // effect r: "max", // rounded corners }, }, ); // → "https://res.cloudinary.com/demo/image/upload/w_800,h_600,c_fill,g_faces,e_grayscale,r_max,f_auto/sample.jpg" // Imgix: provider-specific operations (auto, fit, dpr, blur) const imgixUrl = transformUrl( { url: "https://demo.imgix.net/image.jpg", width: 1200, height: 800, quality: 75, }, { imgix: { auto: "format,compress", fit: "crop", dpr: 2, blur: 0, }, }, ); // Netlify: with base URL option for absolute URL generation const netlifyUrl = transformUrl( { url: "https://example.com/photo.jpg", width: 800, height: 400, fallback: "netlify", }, {}, { netlify: { baseUrl: "https://my-site.netlify.app" }, }, ); // → "https://my-site.netlify.app/.netlify/images?w=800&h=400&fit=cover&url=https%3A%2F%2Fexample.com%2Fphoto.jpg" // Vercel: with custom prefix for Next.js deployments const vercelUrl = transformUrl( { url: "/images/hero.jpg", width: 1920, fallback: "vercel", }, {}, { vercel: { prefix: "_next" }, }, ); // → "/_next/image?w=1920&q=75&url=%2Fimages%2Fhero.jpg" ``` ``` -------------------------------- ### Async API - getTransformerForProvider Source: https://context7.com/ascorbic/unpic/llms.txt Asynchronously retrieves the transformer function for a specific provider. ```APIDOC ## Async getTransformerForProvider ### Description Dynamically loads and returns the transformer function for a given provider name. This allows for on-demand loading of provider-specific transformation logic. ### Usage ```ts import { getTransformerForProvider } from "unpic/async"; const transformer = await getTransformerForProvider("cloudinary"); if (transformer) { const result = transformer( "https://res.cloudinary.com/demo/image/upload/sample.jpg", { width: 300, height: 300, c: "fill" }, ); console.log(result); } ``` ``` -------------------------------- ### `getProviderForUrl` Source: https://context7.com/ascorbic/unpic/llms.txt Detects the CDN provider for a given URL by matching its domain, subdomain, or path. Returns the provider identifier string or `false` if the URL is not recognized. ```APIDOC ## `getProviderForUrl` — Detect the CDN provider for a URL Detects which image CDN a URL belongs to by matching its domain, subdomain, or path. Returns the provider identifier string (e.g., `"imgix"`, `"cloudinary"`) or `false` if the URL is not recognised. ### Usage ```ts import { getProviderForUrl, getProviderForUrlByDomain, getProviderForUrlByPath } from "unpic"; // Detect by full URL getProviderForUrl("https://images.unsplash.com/photo-123"); // → "imgix" getProviderForUrl("https://cdn.shopify.com/s/files/1/image.jpg"); // → "shopify" getProviderForUrl("https://res.cloudinary.com/demo/image/upload/sample.jpg"); // → "cloudinary" getProviderForUrl("https://example.com/image.jpg"); // → false // Detect using only domain matching getProviderForUrlByDomain("https://a.storyblok.com/f/image.jpg"); // → "storyblok" // Detect using only path matching (works with relative URLs) getProviderForUrlByPath("/_next/image?url=%2Fprofile.png&w=200&q=75"); // → "nextjs" getProviderForUrlByPath("/_vercel/image?url=...&w=400&q=75"); // → "vercel" getProviderForUrlByPath("/_ipx/w_800,h_600/image.jpg"); // → "ipx" ``` ``` -------------------------------- ### Async API - getExtractorForProvider Source: https://context7.com/ascorbic/unpic/llms.txt Asynchronously retrieves the extractor function for a specific provider. ```APIDOC ## Async getExtractorForProvider ### Description Dynamically loads and returns the extractor function for a given provider name. This function parses image URLs to extract the source and operations. ### Usage ```ts import { getExtractorForProvider } from "unpic/async"; const extractor = await getExtractorForProvider("imgix"); if (extractor) { const parsed = extractor("https://demo.imgix.net/image.jpg?w=800&h=600&fit=crop"); console.log(parsed); // { src: "https://demo.imgix.net/image.jpg", operations: { w: 800, h: 600, fit: "crop", auto: "format" } } } ``` ``` -------------------------------- ### Create Operations Handlers Source: https://github.com/ascorbic/unpic/blob/main/CONTRIBUTING.md Generates standardized parser and generator functions for URL operations. Configure key mappings, default values, format transformations, and separators for different URL styles. ```typescript const { operationsGenerator, operationsParser } = createOperationsHandlers({ // Map standard operation names to provider-specific names keyMap: { width: "w", height: "h", quality: "q", format: "fmt", }, // Set default values defaults: { quality: 80, format: "auto", }, // Normalize format names formatMap: { jpg: "jpeg", }, // Define parameter formatting kvSeparator: "=", // key=value paramSeparator: "&", // param1¶m2 }); ``` -------------------------------- ### Transform URL with Provider-Specific Options Source: https://context7.com/ascorbic/unpic/llms.txt Use `transformUrl` to modify image URLs, applying provider-specific operations and options. Options for multiple providers can be passed; only matching ones are applied. Base URL and custom prefixes can also be configured. ```ts import { transformUrl } from "unpic"; // Cloudinary: provider-specific operations (crop mode, gravity, effects) const cloudinaryUrl = transformUrl( { url: "https://res.cloudinary.com/demo/image/upload/sample.jpg", width: 800, height: 600, }, { cloudinary: { c: "fill", // crop mode g: "faces", // gravity e: "grayscale", // effect r: "max", // rounded corners }, }, ); // → "https://res.cloudinary.com/demo/image/upload/w_800,h_600,c_fill,g_faces,e_grayscale,r_max,f_auto/sample.jpg" // Imgix: provider-specific operations (auto, fit, dpr, blur) const imgixUrl = transformUrl( { url: "https://demo.imgix.net/image.jpg", width: 1200, height: 800, quality: 75, }, { imgix: { auto: "format,compress", fit: "crop", dpr: 2, blur: 0, }, } ); // Netlify: with base URL option for absolute URL generation const netlifyUrl = transformUrl( { url: "https://example.com/photo.jpg", width: 800, height: 400, fallback: "netlify", }, {}, { netlify: { baseUrl: "https://my-site.netlify.app" }, } ); // → "https://my-site.netlify.app/.netlify/images?w=800&h=400&fit=cover&url=https%3A%2F%2Fexample.com%2Fphoto.jpg" // Vercel: with custom prefix for Next.js deployments const vercelUrl = transformUrl( { url: "/images/hero.jpg", width: 1920, fallback: "vercel", }, {}, { vercel: { prefix: "_next" }, } ); // → "/_next/image?w=1920&q=75&url=%2Fimages%2Fhero.jpg" ``` -------------------------------- ### Apply Provider-Specific Operations Source: https://github.com/ascorbic/unpic/blob/main/README.md Pass provider-specific operations, such as 'crop' for Shopify, as a third argument to transformUrl. This allows for fine-grained control over transformations. ```ts const url = transformUrl( "https://cdn.shopify.com/static/sample-images/bath.jpeg", { width: 800, height: 600, }, { shopify: { crop: "center", }, }, ); ``` -------------------------------- ### Transform an image URL with Unpic Source: https://context7.com/ascorbic/unpic/llms.txt Use `transformUrl` to automatically detect the CDN provider and apply transformations like resizing and format changes. It returns a new URL string with the requested transforms applied, or `undefined` if the URL is not from a recognized CDN and no `fallback` was provided. ```ts import { transformUrl } from "unpic"; // Auto-detect provider (Shopify) and resize const shopifyUrl = transformUrl({ url: "https://cdn.shopify.com/static/sample-images/bath_grande_crop_center.jpeg", width: 800, height: 600, }); // → "https://cdn.shopify.com/static/sample-images/bath.jpeg?width=800&height=600&crop=center" // Auto-detect provider (Imgix / Unsplash) and resize const imgixUrl = transformUrl({ url: "https://images.unsplash.com/photo-123?auto=format&fit=crop&w=2089&q=80", width: 400, height: 300, quality: 85, }); // → "https://images.unsplash.com/photo-123?w=400&h=300&fit=min&auto=format&q=85" // Force a specific provider (useful for custom domains) const forcedUrl = transformUrl({ url: "https://my-custom-domain.com/image.jpg", width: 1200, height: 630, provider: "cloudinary", }, {}, { cloudinary: { cloudName: "my-cloud" }, }); // Use a fallback provider when no CDN is detected const fallbackUrl = transformUrl({ url: "https://example.com/photo.jpg", width: 800, height: 400, fallback: "netlify", }); // → "/.netlify/images?w=800&h=400&fit=cover&url=https%3A%2F%2Fexample.com%2Fphoto.jpg" // Returns undefined when no CDN detected and no fallback set const unknown = transformUrl({ url: "https://example.com/photo.jpg", width: 800 }); // → undefined ``` -------------------------------- ### Provider-Specific Transform Function Source: https://github.com/ascorbic/unpic/blob/main/README.md Transforms an image URL using a specific CDN provider's API. This is useful for reducing bundle size by importing only the necessary provider. ```APIDOC ## Provider-Specific Transform ### Description Transforms an image URL using a specific CDN provider's API. This is useful for reducing bundle size by importing only the necessary provider. ### Function Signature `transform(src: string, options: object): string` ### Parameters #### `src` (string) - Required - The original image URL. #### `options` (object) - Required - An object containing transformation options specific to the provider. ### Request Example ```ts import { transform } from "unpic/providers/shopify"; const url = transform( "https://cdn.shopify.com/static/sample-images/bath.jpeg", { width: 800, height: 600, crop: "center", }, ); console.log(url); ``` ``` -------------------------------- ### Apply Multiple Provider Operations Source: https://github.com/ascorbic/unpic/blob/main/README.md Provide operations for multiple CDNs in the third argument of transformUrl. The correct operations will be applied based on the detected CDN. ```ts const url = transformUrl( src, { width: 800, height: 600, }, { shopify: { crop: "left", }, imgix: { position: "left", }, }, ); ``` -------------------------------- ### Function Renames in Unpic: V3 vs V4 Source: https://github.com/ascorbic/unpic/blob/main/UPGRADING.md Shows renamed functions in v4, with old names still available but deprecated. Use the new names for clarity and future compatibility. ```typescript // Version 3 import { getImageCdnForUrl, getImageCdnForUrlByDomain, getImageCdnForUrlByPath, } from "unpic"; // Version 4 import { getProviderForUrl, // new name getProviderForUrlByDomain, // new name getProviderForUrlByPath, // new name } from "unpic"; ``` -------------------------------- ### transformUrl Source: https://context7.com/ascorbic/unpic/llms.txt Transforms an image URL by applying standard operations (width, height, format, quality) and optional provider-specific parameters. It auto-detects the CDN provider from the URL. Returns a new URL string with the requested transforms applied, or undefined if the URL is not from a recognized CDN and no fallback was provided. ```APIDOC ## transformUrl ### Description Transforms an image URL by applying standard operations (width, height, format, quality) and optional provider-specific parameters. It auto-detects the CDN provider from the URL. Returns a new URL string with the requested transforms applied, or undefined if the URL is not from a recognized CDN and no fallback was provided. ### Parameters - **url** (string | URL) - Required - The image URL to transform. - **width** (number) - Optional - The desired width of the image. - **height** (number) - Optional - The desired height of the image. - **format** (string) - Optional - The desired image format (e.g., 'jpeg', 'png', 'webp'). - **quality** (number) - Optional - The desired image quality (0-100). - **fallback** (string) - Optional - The name of a fallback CDN provider to use if the URL is not recognized. - **provider** (string) - Optional - The name of the CDN provider to force. ### Provider Options - **options** (object) - Optional - Provider-specific options. - **[providerName]** (object) - Optional - Configuration for a specific provider. - **cloudName** (string) - Required for Cloudinary - The Cloudinary cloud name. - **domain** (string) - Optional - The custom domain for the CDN. - **privateCdn** (boolean) - Optional - Whether to use a private CDN. ### Request Example ```ts import { transformUrl } from "unpic"; // Auto-detect provider (Shopify) and resize const shopifyUrl = transformUrl({ url: "https://cdn.shopify.com/static/sample-images/bath_grande_crop_center.jpeg", width: 800, height: 600, }); // → "https://cdn.shopify.com/static/sample-images/bath.jpeg?width=800&height=600&crop=center" // Auto-detect provider (Imgix / Unsplash) and resize const imgixUrl = transformUrl({ url: "https://images.unsplash.com/photo-123?auto=format&fit=crop&w=2089&q=80", width: 400, height: 300, quality: 85, }); // → "https://images.unsplash.com/photo-123?w=400&h=300&fit=min&auto=format&q=85" // Force a specific provider (useful for custom domains) const forcedUrl = transformUrl({ url: "https://my-custom-domain.com/image.jpg", width: 1200, height: 630, provider: "cloudinary", }, {}, { cloudinary: { cloudName: "my-cloud" }, }); // Use a fallback provider when no CDN is detected const fallbackUrl = transformUrl({ url: "https://example.com/photo.jpg", width: 800, height: 400, fallback: "netlify", }); // → "/.netlify/images?w=800&h=400&fit=cover&url=https%3A%2F%2Fexample.com%2Fphoto.jpg" // Returns undefined when no CDN detected and no fallback set const unknown = transformUrl({ url: "https://example.com/photo.jpg", width: 800 }); // → undefined ``` ``` -------------------------------- ### Transform URL with Explicit Provider Source: https://github.com/ascorbic/unpic/blob/main/README.md Specify the image CDN provider explicitly when transforming a URL. This is useful for custom domains or when auto-detection might fail. ```ts const url = transformUrl( "https://cdn.shopify.com/static/sample-images/bath_grande_crop_center.jpeg", { width: 800, height: 600, provider: "shopify", }, ); ``` -------------------------------- ### `getTransformerForCdn` Source: https://context7.com/ascorbic/unpic/llms.txt Retrieves the synchronous `transform` function for a specified CDN identifier. This is useful when the provider is known in advance, allowing direct access to the provider's transformer without relying on auto-detection. ```APIDOC ## `getTransformerForCdn` — Get a provider's transform function Returns the synchronous `transform` function for a specific CDN identifier. Useful when you know the provider ahead of time and want direct access to the provider's transformer without going through auto-detection. ### Usage ```ts import { getTransformerForCdn } from "unpic"; const shopifyTransform = getTransformerForCdn("shopify"); if (shopifyTransform) { const url = shopifyTransform( "https://cdn.shopify.com/static/sample-images/bath.jpeg", { width: 600, height: 400, crop: "center" }, ); console.log(url); // → "https://cdn.shopify.com/static/sample-images/bath.jpeg?width=600&height=400&crop=center" } // Returns undefined for unsupported/invalid CDN identifiers const none = getTransformerForCdn(false); // → undefined ``` ``` -------------------------------- ### Parse Image URL with Unpic Source: https://github.com/ascorbic/unpic/blob/main/README.md Use the parseUrl function to extract image source and transformation details from a given URL. This is useful for understanding existing image CDN URLs. ```ts const parsed = parseUrl( "https://cdn.shopify.com/static/sample-images/bath_800x600_crop_center.jpeg", ); console.log(parsed); // { // provider: "shopify", // src: "https://cdn.shopify.com/static/sample-images/bath.jpeg", // operations: { // width: 800, // height: 600, // crop: "center" // } // } ``` -------------------------------- ### parseUrl Source: https://context7.com/ascorbic/unpic/llms.txt Parses a CDN image URL into a structured object containing the canonical source URL (src), the detected provider (cdn), and the currently applied operations. Useful for inspecting what transforms have already been applied before applying new ones. Returns undefined if the URL is not from a known CDN. ```APIDOC ## parseUrl ### Description Parses a CDN image URL into a structured object containing the canonical source URL (`src`), the detected provider (`cdn`), and the currently applied `operations`. Useful for inspecting what transforms have already been applied before applying new ones. Returns undefined if the URL is not from a known CDN. ### Parameters - **url** (string | URL) - Required - The CDN image URL to parse. ### Response - **cdn** (string) - The detected CDN provider. - **src** (string) - The canonical source URL of the image. - **operations** (object) - An object containing the currently applied operations and their values. - **options** (object) - Optional - Provider-specific options parsed from the URL. ### Request Example ```ts import { parseUrl } from "unpic"; const result = parseUrl( "https://cdn.shopify.com/static/sample-images/bath_800x600_crop_center.jpeg", ); console.log(result); // { // cdn: "shopify", // src: "https://cdn.shopify.com/static/sample-images/bath.jpeg", // operations: { width: 800, height: 600, crop: "center" } // } // Parse a Cloudinary URL with transformations const cloudinaryResult = parseUrl( "https://res.cloudinary.com/demo/image/upload/w_500,h_300,c_fill,f_auto/sample.jpg", ); console.log(cloudinaryResult); // { // cdn: "cloudinary", // src: "https://res.cloudinary.com/demo/image/upload/sample.jpg", // operations: { w: 500, h: 300, c: "fill", f: "auto" }, // options: { cloudName: "demo", domain: "res.cloudinary.com", privateCdn: false } // } // Returns undefined if URL is not from a known CDN const unknown = parseUrl("https://example.com/image.jpg"); // → undefined ``` ```