@lonik/oh-image 2.1.1 → 2.1.3

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.
package/dist/react.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { t as assertProps } from "./prop-asserts-ZcucnyC7.js";
1
2
  import * as ReactDOM from "react-dom";
2
3
  import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
3
4
  import { jsx } from "react/jsx-runtime";
@@ -165,45 +166,6 @@ function resolvePlaceholder(prop, src) {
165
166
  return null;
166
167
  }
167
168
 
168
- //#endregion
169
- //#region src/react/prop-asserts.ts
170
- function assertProps(prop) {
171
- try {
172
- if (prop.asap !== void 0) console.warn("The `asap` prop is deprecated and will be removed in a future version. Please use `priority` instead.");
173
- assertLoadingProp(prop);
174
- assertDecodingProp(prop);
175
- assertFetchPriorityProp(prop);
176
- assertBreakpointsProp(prop);
177
- assertFillProp(prop);
178
- assertDimensionsProp(prop);
179
- } catch (err) {
180
- const message = err instanceof Error ? err.message : err;
181
- console.warn(message);
182
- }
183
- }
184
- function assert(assertion, message) {
185
- if (assertion()) throw new Error(message || void 0);
186
- }
187
- function assertLoadingProp(prop) {
188
- assert(() => prop.loading && (prop.priority || prop.asap), `Do not use \`loading\` on a priority image — priority images are always eagerly loaded.`);
189
- }
190
- function assertDecodingProp(prop) {
191
- assert(() => prop.decoding && (prop.priority || prop.asap), `Do not use \`decoding\` on a priority image — priority images always use async decoding.`);
192
- }
193
- function assertFetchPriorityProp(prop) {
194
- assert(() => prop.fetchPriority && (prop.priority || prop.asap), `Do not use \`fetchPriority\` on a priority image — priority images always use high fetch priority.`);
195
- }
196
- function assertBreakpointsProp(prop) {
197
- assert(() => prop.breakpoints && typeof prop.src === "object", `Do not use \`breakpoints\` when \`src\` is an imported image — the image's built-in srcSets are used instead.`);
198
- assert(() => prop.breakpoints && typeof prop.src === "string" && !prop.loader, `Do not use \`breakpoints\` without a \`loader\` — breakpoints require a loader to generate srcSet entries.`);
199
- }
200
- function assertFillProp(prop) {
201
- assert(() => prop.fill && (prop.width !== void 0 || prop.height !== void 0), `Do not use \`width\` or \`height\` with \`fill\` — fill mode makes the image fill its container.`);
202
- }
203
- function assertDimensionsProp(prop) {
204
- assert(() => typeof prop.src === "string" && !prop.fill && prop.width === void 0 && prop.height === void 0, `Image is missing \`width\` and \`height\` props. Either provide dimensions, use \`fill\`, or use an imported image source.`);
205
- }
206
-
207
169
  //#endregion
208
170
  //#region src/react/image-context.tsx
209
171
  const ImageContext = createContext({
@@ -289,373 +251,4 @@ function Image(props) {
289
251
  }
290
252
 
291
253
  //#endregion
292
- //#region src/react/loaders/loader-utils.ts
293
- function resolveOption(key, value, separator) {
294
- return `${key}${separator}${value}`;
295
- }
296
- function resolveDeprecatedParams(source, separator) {
297
- const params = [];
298
- for (const key of Object.keys(params)) {
299
- const value = source[key];
300
- if (value !== void 0) params.push(resolveOption(key, value, separator));
301
- }
302
- return params;
303
- }
304
-
305
- //#endregion
306
- //#region src/react/loaders/imgproxy/create-imgproxy-url.ts
307
- const stringifyOptions = (opCode, values) => {
308
- return [opCode, ...values.map((v) => v == null ? "" : encodeURIComponent(v))].join(":").replace(/:+$/, "");
309
- };
310
- const resolveObjectParam = (key, source) => {
311
- if (source === void 0) return;
312
- if (key === "size") {
313
- const tSource = source;
314
- if (!tSource) return;
315
- return stringifyOptions(key, [
316
- tSource.width,
317
- tSource.height,
318
- tSource.enlarge,
319
- tSource.extend
320
- ]);
321
- }
322
- if (key === "resize") {
323
- const tSource = source;
324
- if (!tSource) return;
325
- return stringifyOptions(key, [
326
- tSource.resizing_type,
327
- tSource.width,
328
- tSource.height,
329
- tSource.enlarge,
330
- tSource.extend
331
- ]);
332
- }
333
- if (key === "extend") {
334
- const tSource = source;
335
- if (!tSource) return;
336
- if (typeof tSource === "boolean") return stringifyOptions(key, [tSource]);
337
- return stringifyOptions(key, [tSource.extend, tSource.gravity]);
338
- }
339
- if (key === "gravity") {
340
- const tSource = source;
341
- if (!tSource) return;
342
- return stringifyOptions(key, [
343
- tSource.type,
344
- tSource.x_offset,
345
- tSource.y_offset
346
- ]);
347
- }
348
- if (key === "crop") {
349
- const tSource = source;
350
- if (!tSource) return;
351
- return stringifyOptions(key, [
352
- tSource.width,
353
- tSource.height,
354
- tSource.gravity
355
- ]);
356
- }
357
- if (key === "trim") {
358
- const tSource = source;
359
- if (!tSource) return;
360
- return stringifyOptions(key, [
361
- tSource.threshold,
362
- tSource.color,
363
- tSource.equal_hor,
364
- tSource.equal_ver
365
- ]);
366
- }
367
- if (key === "padding") {
368
- const tSource = source;
369
- if (!tSource) return;
370
- return stringifyOptions(key, [
371
- tSource.top,
372
- tSource.right,
373
- tSource.bottom,
374
- tSource.left
375
- ]);
376
- }
377
- if (key === "background") {
378
- const tSource = source;
379
- if (!tSource) return;
380
- if (typeof tSource === "string") return stringifyOptions(key, [tSource]);
381
- return stringifyOptions(key, [
382
- tSource.r,
383
- tSource.g,
384
- tSource.b
385
- ]);
386
- }
387
- if (key === "adjust") {
388
- const tSource = source;
389
- if (!tSource) return;
390
- return stringifyOptions(key, [
391
- tSource.brightness,
392
- tSource.contrast,
393
- tSource.saturation
394
- ]);
395
- }
396
- if (key === "blur_detections") {
397
- const tSource = source;
398
- if (!tSource) return;
399
- return stringifyOptions(key, [tSource.sigma, ...tSource.class_names]);
400
- }
401
- if (key === "draw_detections") {
402
- const tSource = source;
403
- if (!tSource) return;
404
- return stringifyOptions(key, [tSource.draw, ...tSource.class_names]);
405
- }
406
- if (key === "watermark") {
407
- const tSource = source;
408
- if (!tSource) return;
409
- return stringifyOptions(key, [
410
- tSource.opacity,
411
- tSource.position,
412
- tSource.x_offset,
413
- tSource.y_offset,
414
- tSource.scale
415
- ]);
416
- }
417
- if (key === "watermark_size") {
418
- const tSource = source;
419
- if (!tSource) return;
420
- return stringifyOptions(key, [tSource.width, tSource.height]);
421
- }
422
- if (key === "unsharpening") {
423
- const tSource = source;
424
- if (!tSource) return;
425
- return stringifyOptions(key, [
426
- tSource.mode,
427
- tSource.weight,
428
- tSource.dividor
429
- ]);
430
- }
431
- if (key === "autoquality") {
432
- const tSource = source;
433
- if (!tSource) return;
434
- return stringifyOptions(key, [
435
- tSource.method,
436
- tSource.target,
437
- tSource.min_quality,
438
- tSource.max_quality,
439
- tSource.allowed_error
440
- ]);
441
- }
442
- if (key === "jpeg_options") {
443
- const tSource = source;
444
- if (!tSource) return;
445
- return stringifyOptions(key, [
446
- tSource.progressive,
447
- tSource.no_subsample,
448
- tSource.trellis_quant,
449
- tSource.overshoot_deringing,
450
- tSource.optimize_scans,
451
- tSource.quant_table
452
- ]);
453
- }
454
- if (key === "png_options") {
455
- const tSource = source;
456
- if (!tSource) return;
457
- return stringifyOptions(key, [
458
- tSource.interlaced,
459
- tSource.quantize,
460
- tSource.quantization_colors
461
- ]);
462
- }
463
- if (key === "zoom") {
464
- const tSource = source;
465
- if (!tSource) return;
466
- if (typeof tSource === "number") return stringifyOptions(key, [tSource]);
467
- return stringifyOptions(key, [tSource.x, tSource.y]);
468
- }
469
- };
470
- const resolveTransforms = (transforms) => {
471
- if (!transforms) return "";
472
- const params = [];
473
- for (const key of Object.keys(transforms)) {
474
- const value = transforms[key];
475
- const keyCast = key;
476
- if (value === void 0) continue;
477
- if (typeof value === "object") {
478
- const objectParams = resolveObjectParam(keyCast, value);
479
- if (objectParams) params.push(objectParams);
480
- } else params.push(stringifyOptions(key, [value]));
481
- }
482
- return params;
483
- };
484
- function createImgproxyUrl(path, transforms, imageOptions) {
485
- if (!path) throw new Error("Path must be provided");
486
- const params = [];
487
- if (imageOptions.width) params.push(stringifyOptions("width", [imageOptions.width]));
488
- if (imageOptions.height) params.push(stringifyOptions("height", [imageOptions.height]));
489
- params.push(...resolveTransforms(transforms));
490
- if (params) params.push(...resolveDeprecatedParams(params, ":"));
491
- return `${path}/${params.join("/")}/plain/${imageOptions.src}`;
492
- }
493
-
494
- //#endregion
495
- //#region src/react/loaders/imgproxy/imgproxy-context.tsx
496
- const ImgproxyContext = createContext({
497
- transforms: { format: "webp" },
498
- placeholderTransforms: {
499
- quality: 10,
500
- format: "webp"
501
- }
502
- });
503
- function useImgproxyContext() {
504
- return useContext(ImgproxyContext);
505
- }
506
- function ImgproxyLoaderProvider({ children, ...props }) {
507
- const ctx = useImgproxyContext();
508
- return /* @__PURE__ */ jsx(ImgproxyContext.Provider, {
509
- value: {
510
- ...ctx,
511
- ...props
512
- },
513
- children
514
- });
515
- }
516
-
517
- //#endregion
518
- //#region src/react/loaders/imgproxy/use-imgproxy-loader.tsx
519
- function useImgproxyLoader(options) {
520
- const context = useImgproxyContext();
521
- const path = options?.path || context.path;
522
- const transforms = {
523
- ...context.transforms,
524
- ...options?.transforms
525
- };
526
- return (imageOptions) => createImgproxyUrl(path, transforms, imageOptions);
527
- }
528
-
529
- //#endregion
530
- //#region src/react/loaders/imgproxy/use-imgproxy-placeholder.tsx
531
- function useImgproxyPlaceholder(options) {
532
- const context = useImgproxyContext();
533
- const path = options?.path || context.path;
534
- const transforms = {
535
- ...context.placeholderTransforms,
536
- ...options?.transforms
537
- };
538
- return (imageOptions) => createImgproxyUrl(path, transforms, imageOptions);
539
- }
540
-
541
- //#endregion
542
- //#region src/react/loaders/image-loader-utils.ts
543
- function normalizeLoaderParams(params, separator) {
544
- return Object.entries(params).map(([key, value]) => `${key}${separator}${value}`);
545
- }
546
- function isAbsoluteUrl(src) {
547
- return /^https?:\/\//.test(src);
548
- }
549
- function assertPath(path) {
550
- assert(() => !path?.trim(), import.meta.env.DEV && `Path is required`);
551
- assert(() => {
552
- try {
553
- new URL(path);
554
- return !isAbsoluteUrl(path);
555
- } catch {
556
- return true;
557
- }
558
- }, import.meta.env.DEV && `Path is invalid url: ${path}`);
559
- }
560
-
561
- //#endregion
562
- //#region src/react/loaders/cloudflare-loader.tsx
563
- const CloudflareContext = createContext({
564
- path: "",
565
- placeholder: true,
566
- format: "auto",
567
- placeholderParams: { quality: "low" }
568
- });
569
- function useCloudflareContext() {
570
- return useContext(CloudflareContext);
571
- }
572
- function CloudflareLoaderProvider({ children, ...props }) {
573
- const ctx = useCloudflareContext();
574
- return /* @__PURE__ */ jsx(CloudflareContext.Provider, {
575
- value: {
576
- ...ctx,
577
- ...props
578
- },
579
- children
580
- });
581
- }
582
- function useCloudflareLoader(options) {
583
- const resolvedOptions = {
584
- ...useCloudflareContext(),
585
- ...options
586
- };
587
- assertPath(resolvedOptions.path);
588
- return (imageOptions) => {
589
- const parts = [];
590
- const format = resolvedOptions.format;
591
- if (format) parts.push(`format=${format}`);
592
- if (imageOptions.width) parts.push(`width=${imageOptions.width}`);
593
- if (imageOptions.height) parts.push(`height=${imageOptions.height}`);
594
- if (resolvedOptions.params) parts.push(...normalizeLoaderParams(resolvedOptions.params, "="));
595
- if (imageOptions.isPlaceholder) {
596
- if (resolvedOptions.placeholderParams) {
597
- const placeholderParams = normalizeLoaderParams(resolvedOptions.placeholderParams, "=");
598
- parts.push(...placeholderParams);
599
- }
600
- } else if (resolvedOptions.params) {
601
- const params = normalizeLoaderParams(resolvedOptions.params, "=");
602
- parts.push(...params);
603
- }
604
- const processingOptions = parts.join(",");
605
- return `${resolvedOptions.path}/cdn-cgi/image/${processingOptions}/${imageOptions.src}`;
606
- };
607
- }
608
-
609
- //#endregion
610
- //#region src/react/loaders/cloudinary-loader.tsx
611
- const CloudinaryContext = createContext({
612
- path: "",
613
- placeholder: true,
614
- format: "auto",
615
- placeholderParams: {
616
- e_blur: ":1000",
617
- q: "_1"
618
- }
619
- });
620
- function useCloudinaryContext() {
621
- return useContext(CloudinaryContext);
622
- }
623
- function CloudinaryLoaderProvider({ children, ...props }) {
624
- const ctx = useCloudinaryContext();
625
- return /* @__PURE__ */ jsx(CloudinaryContext.Provider, {
626
- value: {
627
- ...ctx,
628
- ...props
629
- },
630
- children
631
- });
632
- }
633
- function useCloudinaryLoader(options) {
634
- const resolvedOptions = {
635
- ...useCloudinaryContext(),
636
- ...options
637
- };
638
- assertPath(resolvedOptions.path);
639
- return (imageOptions) => {
640
- const parts = [];
641
- const format = `f_${resolvedOptions.format}`;
642
- parts.push(`${format}`);
643
- if (imageOptions.width) parts.push(`w_${imageOptions.width}`);
644
- if (imageOptions.height) parts.push(`h_${imageOptions.height}`);
645
- if (imageOptions.isPlaceholder) {
646
- if (resolvedOptions.placeholderParams) {
647
- const placeholderParams = normalizeLoaderParams(resolvedOptions.placeholderParams, "");
648
- parts.push(...placeholderParams);
649
- }
650
- } else if (resolvedOptions.params) {
651
- const params = normalizeLoaderParams(resolvedOptions.params, "");
652
- parts.push(...params);
653
- }
654
- let src = imageOptions.src;
655
- if (src.startsWith("/")) src = src.slice(1);
656
- return `${resolvedOptions.path.endsWith("/") ? resolvedOptions.path.slice(0, -1) : resolvedOptions.path}/image/upload/${parts.join(",")}/${src}`;
657
- };
658
- }
659
-
660
- //#endregion
661
- export { CloudflareLoaderProvider, CloudinaryLoaderProvider, Image, ImageProvider, ImgproxyLoaderProvider, useCloudflareContext, useCloudflareLoader, useCloudinaryContext, useCloudinaryLoader, useImageContext, useImgLoaded, useImgproxyContext, useImgproxyLoader, useImgproxyPlaceholder };
254
+ export { Image, ImageProvider, useImageContext, useImgLoaded };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lonik/oh-image",
3
3
  "type": "module",
4
- "version": "2.1.1",
4
+ "version": "2.1.3",
5
5
  "description": "A React component library for optimized image handling.",
6
6
  "author": "Luka Onikadze <lukonik@gmail.com>",
7
7
  "license": "MIT",
@@ -24,6 +24,18 @@
24
24
  "types": "./dist/react.d.ts",
25
25
  "default": "./dist/react.js"
26
26
  },
27
+ "./cloudflare": {
28
+ "types": "./dist/cloudflare.d.ts",
29
+ "default": "./dist/cloudflare.js"
30
+ },
31
+ "./cloudinary": {
32
+ "types": "./dist/cloudinary.d.ts",
33
+ "default": "./dist/cloudinary.js"
34
+ },
35
+ "./imgproxy": {
36
+ "types": "./dist/imgproxy.d.ts",
37
+ "default": "./dist/imgproxy.js"
38
+ },
27
39
  "./client": {
28
40
  "types": "./dist/client.d.ts"
29
41
  }
@@ -55,6 +67,7 @@
55
67
  "devDependencies": {
56
68
  "@commitlint/config-conventional": "^20.4.1",
57
69
  "@eslint/js": "^9.39.2",
70
+ "@tailwindcss/vite": "^4.1.18",
58
71
  "@tanstack/react-router": "^1.160.0",
59
72
  "@tanstack/router-plugin": "^1.160.0",
60
73
  "@testing-library/jest-dom": "^6.9.1",
@@ -74,16 +87,15 @@
74
87
  "eslint-plugin-react-refresh": "^0.5.0",
75
88
  "globals": "^17.3.0",
76
89
  "happy-dom": "^20.6.0",
90
+ "json-edit-react": "^1.29.0",
77
91
  "memfs": "^4.56.10",
78
92
  "supertest": "^7.2.2",
93
+ "tailwindcss": "^4.1.18",
79
94
  "tsdown": "^0.18.1",
80
95
  "typescript": "^5.9.3",
81
96
  "typescript-eslint": "^8.54.0",
82
97
  "vite": "^7.3.0",
83
- "vitest": "^4.0.16",
84
- "tailwindcss": "^4.1.18",
85
- "@tailwindcss/vite": "^4.1.18",
86
- "json-edit-react": "^1.29.0"
98
+ "vitest": "^4.0.16"
87
99
  },
88
100
  "dependencies": {
89
101
  "p-limit": "^7.3.0",