@webstudio-is/image 0.56.0 → 0.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,8 +41,10 @@ const cloudflareImageLoader = (loaderOptions) => ({ width, src, quality }) => {
41
41
  "Width must be only from allowed values"
42
42
  );
43
43
  }
44
+ const cdnUrl = loaderOptions?.cdnUrl ?? "/";
45
+ const imageUrl = `${cdnUrl}${src}`;
44
46
  const options = `width=${width},quality=${quality},format=auto`;
45
- const pathname = `/cdn-cgi/image/${options}/${src}`;
47
+ const pathname = `/cdn-cgi/image/${options}/${imageUrl}`;
46
48
  if (loaderOptions?.resizeOrigin != null) {
47
49
  const url = new URL(pathname, loaderOptions.resizeOrigin);
48
50
  return url.href;
@@ -7,8 +7,10 @@ const cloudflareImageLoader = (loaderOptions) => ({ width, src, quality }) => {
7
7
  "Width must be only from allowed values"
8
8
  );
9
9
  }
10
+ const cdnUrl = loaderOptions?.cdnUrl ?? "/";
11
+ const imageUrl = `${cdnUrl}${src}`;
10
12
  const options = `width=${width},quality=${quality},format=auto`;
11
- const pathname = `/cdn-cgi/image/${options}/${src}`;
13
+ const pathname = `/cdn-cgi/image/${options}/${imageUrl}`;
12
14
  if (loaderOptions?.resizeOrigin != null) {
13
15
  const url = new URL(pathname, loaderOptions.resizeOrigin);
14
16
  return url.href;
@@ -1,10 +1,10 @@
1
1
  import type * as React from "react";
2
2
  import type { ComponentMeta, ComponentStory } from "@storybook/react";
3
- declare const _default: ComponentMeta<React.ForwardRefExoticComponent<Pick<React.ClassAttributes<HTMLImageElement> & React.ImgHTMLAttributes<HTMLImageElement> & {
3
+ declare const _default: ComponentMeta<React.ForwardRefExoticComponent<Omit<React.ClassAttributes<HTMLImageElement> & React.ImgHTMLAttributes<HTMLImageElement> & {
4
4
  quality?: number | undefined;
5
5
  optimize?: boolean | undefined;
6
6
  loader: import("./image-optimize").ImageLoader;
7
- }, "quality" | "loader" | "key" | keyof React.ImgHTMLAttributes<HTMLImageElement> | "optimize"> & React.RefAttributes<HTMLImageElement>>>;
7
+ }, "ref"> & React.RefAttributes<HTMLImageElement>>>;
8
8
  export default _default;
9
9
  /**
10
10
  * Load images depending on image width and device per pixel ratio.
@@ -1,12 +1,13 @@
1
1
  import { type ImageLoader } from "./image-optimize";
2
2
  export type CloudflareImageLoaderOptions = {
3
3
  resizeOrigin?: string | null;
4
+ cdnUrl?: string;
4
5
  };
5
6
  /**
6
7
  * Default image loader in case of no loader provided
7
8
  * https://developers.cloudflare.com/images/image-resizing/url-format/
8
9
  **/
9
- export declare const cloudflareImageLoader: (ops: CloudflareImageLoaderOptions | null) => ImageLoader;
10
+ export declare const cloudflareImageLoader: (loaderOptions: CloudflareImageLoaderOptions | null) => ImageLoader;
10
11
  type LocalImageLoaderOptions = {
11
12
  publicPath?: string;
12
13
  };
@@ -6,5 +6,5 @@ type ImageProps = ComponentProps<typeof defaultTag> & {
6
6
  optimize?: boolean;
7
7
  loader: ImageLoader;
8
8
  };
9
- export declare const Image: import("react").ForwardRefExoticComponent<Pick<ImageProps, "quality" | "loader" | "key" | keyof import("react").ImgHTMLAttributes<HTMLImageElement> | "optimize"> & import("react").RefAttributes<HTMLImageElement>>;
9
+ export declare const Image: import("react").ForwardRefExoticComponent<Omit<ImageProps, "ref"> & import("react").RefAttributes<HTMLImageElement>>;
10
10
  export {};
package/package.json CHANGED
@@ -1,29 +1,31 @@
1
1
  {
2
2
  "name": "@webstudio-is/image",
3
- "version": "0.56.0",
3
+ "version": "0.58.0",
4
4
  "description": "Image optimization",
5
5
  "author": "Webstudio <github@webstudio.is>",
6
6
  "homepage": "https://webstudio.is",
7
7
  "type": "module",
8
8
  "dependencies": {
9
- "react": "^17.0.2",
9
+ "react": "^18.2.0",
10
10
  "warn-once": "^0.1.1",
11
- "@webstudio-is/generate-arg-types": "^0.56.0"
11
+ "@webstudio-is/generate-arg-types": "^0.58.0"
12
12
  },
13
13
  "devDependencies": {
14
14
  "@jest/globals": "^29.3.1",
15
15
  "@storybook/react": "^6.5.16",
16
- "@types/react": "^17.0.24",
16
+ "@types/react": "^18.0.35",
17
17
  "jest": "^29.3.1",
18
+ "react": "^18.2.0",
19
+ "react-dom": "^18.2.0",
18
20
  "typescript": "5.0.3",
19
- "@webstudio-is/jest-config": "^1.0.2",
21
+ "@webstudio-is/jest-config": "^1.0.5",
20
22
  "@webstudio-is/scripts": "^0.0.0",
21
23
  "@webstudio-is/storybook-config": "^0.0.0",
22
- "@webstudio-is/tsconfig": "^1.0.3"
24
+ "@webstudio-is/tsconfig": "^1.0.5"
23
25
  },
24
26
  "peerDependencies": {
25
- "react": "^17.0.2",
26
- "react-dom": "^17.0.2"
27
+ "react": "^18.2.0",
28
+ "react-dom": "^18.2.0"
27
29
  },
28
30
  "module": "./lib/index.js",
29
31
  "exports": {
@@ -41,13 +43,13 @@
41
43
  "private": false,
42
44
  "sideEffects": false,
43
45
  "scripts": {
44
- "typecheck": "tsc --noEmit",
46
+ "typecheck": "tsc --noEmit --emitDeclarationOnly false",
45
47
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
46
48
  "checks": "pnpm typecheck && pnpm lint && pnpm test",
47
49
  "dev": "build-package --watch",
48
50
  "build": "build-package",
49
51
  "build:args": "generate-arg-types './src/*.tsx !./src/**/*.stories.tsx !./src/**/*.ws.tsx' && prettier --write \"**/*.props.ts\"",
50
- "dts": "tsc --emitDeclarationOnly --declaration --declarationDir lib/types",
52
+ "dts": "tsc --declarationDir lib/types",
51
53
  "lint": "eslint ./src --ext .ts,.tsx --max-warnings 0",
52
54
  "storybook:run": "start-storybook -p 6006",
53
55
  "storybook:build": "build-storybook",
@@ -2,17 +2,18 @@ import warnOnce from "warn-once";
2
2
  import { allSizes, type ImageLoader } from "./image-optimize";
3
3
 
4
4
  export type CloudflareImageLoaderOptions = {
5
+ // origin of transformation wrapper
5
6
  resizeOrigin?: string | null;
7
+ // origin of cdn serving image
8
+ cdnUrl?: string;
6
9
  };
7
10
 
8
11
  /**
9
12
  * Default image loader in case of no loader provided
10
13
  * https://developers.cloudflare.com/images/image-resizing/url-format/
11
14
  **/
12
- export const cloudflareImageLoader: (
13
- ops: CloudflareImageLoaderOptions | null
14
- ) => ImageLoader =
15
- (loaderOptions) =>
15
+ export const cloudflareImageLoader =
16
+ (loaderOptions: CloudflareImageLoaderOptions | null): ImageLoader =>
16
17
  ({ width, src, quality }) => {
17
18
  if (process.env.NODE_ENV !== "production") {
18
19
  warnOnce(
@@ -21,9 +22,12 @@ export const cloudflareImageLoader: (
21
22
  );
22
23
  }
23
24
 
25
+ const cdnUrl = loaderOptions?.cdnUrl ?? "/";
26
+ const imageUrl = `${cdnUrl}${src}`;
27
+
24
28
  const options = `width=${width},quality=${quality},format=auto`;
25
29
  // Cloudflare docs say that we don't need to urlencode the path params
26
- const pathname = `/cdn-cgi/image/${options}/${src}`;
30
+ const pathname = `/cdn-cgi/image/${options}/${imageUrl}`;
27
31
 
28
32
  if (loaderOptions?.resizeOrigin != null) {
29
33
  const url = new URL(pathname, loaderOptions.resizeOrigin);
@@ -7,11 +7,14 @@ describe("Image optimizations applied", () => {
7
7
  const imgAttr = getImageAttributes({
8
8
  optimize: true,
9
9
  width: 100,
10
- src: "https://webstudio.is/logo.webp",
10
+ src: "logo.webp",
11
11
  srcSet: undefined,
12
12
  sizes: undefined,
13
13
  quality: 100,
14
- loader: cloudflareImageLoader({ resizeOrigin: null }),
14
+ loader: cloudflareImageLoader({
15
+ resizeOrigin: null,
16
+ cdnUrl: "https://webstudio.is/",
17
+ }),
15
18
  });
16
19
 
17
20
  expect(imgAttr).toMatchInlineSnapshot(`
@@ -27,11 +30,14 @@ describe("Image optimizations applied", () => {
27
30
  const imgAttr = getImageAttributes({
28
31
  optimize: true,
29
32
  width: undefined,
30
- src: "https://webstudio.is/logo.webp",
33
+ src: "logo.webp",
31
34
  srcSet: undefined,
32
35
  sizes: undefined,
33
36
  quality: 90,
34
- loader: cloudflareImageLoader({ resizeOrigin: null }),
37
+ loader: cloudflareImageLoader({
38
+ resizeOrigin: null,
39
+ cdnUrl: "https://webstudio.is/",
40
+ }),
35
41
  });
36
42
 
37
43
  expect(imgAttr).toMatchInlineSnapshot(`
@@ -47,11 +53,14 @@ describe("Image optimizations applied", () => {
47
53
  const imgAttr = getImageAttributes({
48
54
  optimize: true,
49
55
  width: undefined,
50
- src: "https://webstudio.is/logo.webp",
56
+ src: "logo.webp",
51
57
  srcSet: undefined,
52
58
  sizes: "100vw",
53
59
  quality: 70,
54
- loader: cloudflareImageLoader({ resizeOrigin: null }),
60
+ loader: cloudflareImageLoader({
61
+ resizeOrigin: null,
62
+ cdnUrl: "https://webstudio.is/",
63
+ }),
55
64
  });
56
65
 
57
66
  expect(imgAttr).toMatchInlineSnapshot(`
@@ -67,12 +76,13 @@ describe("Image optimizations applied", () => {
67
76
  const imgAttr = getImageAttributes({
68
77
  optimize: true,
69
78
  width: undefined,
70
- src: "https://webstudio.is/logo.webp",
79
+ src: "logo.webp",
71
80
  srcSet: undefined,
72
81
  sizes: "100vw",
73
82
  quality: 70,
74
83
  loader: cloudflareImageLoader({
75
84
  resizeOrigin: "https://resize-origin.is",
85
+ cdnUrl: "https://webstudio.is/",
76
86
  }),
77
87
  });
78
88