@pantheon-systems/p1-media 0.4.2 → 0.4.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/index.mjs CHANGED
@@ -17,6 +17,46 @@ var DEFAULT_MEDIA_PATTERNS = [
17
17
  // src/components/media-field.tsx
18
18
  import { useState as useState5 } from "react";
19
19
 
20
+ // src/crop.ts
21
+ function getBaseUrl(value) {
22
+ return value ? value.split("?")[0] : "";
23
+ }
24
+ function getParams(value) {
25
+ return new URLSearchParams(value.includes("?") ? value.split("?")[1] : "");
26
+ }
27
+ function getCropMode(value) {
28
+ if (!value) return "fit";
29
+ const params = getParams(value);
30
+ if (params.has("trim.left")) return "custom";
31
+ return params.get("fit") === "cover" ? "smart" : "fit";
32
+ }
33
+ function getTrimRect(value) {
34
+ if (!value) return null;
35
+ const params = getParams(value);
36
+ const read = (key) => {
37
+ const raw = params.get(key);
38
+ if (raw === null || raw === "") return null;
39
+ const n2 = Number(raw);
40
+ return Number.isFinite(n2) ? n2 : null;
41
+ };
42
+ const left = read("trim.left");
43
+ const top = read("trim.top");
44
+ const width = read("trim.width");
45
+ const height = read("trim.height");
46
+ if (left === null || top === null || width === null || height === null) return null;
47
+ return { left, top, width, height };
48
+ }
49
+ function buildValueWithCrop(baseUrl, crop) {
50
+ return crop === "smart" ? `${baseUrl}?fit=cover&gravity=auto` : `${baseUrl}?fit=scale-down`;
51
+ }
52
+ function buildValueWithTrim(baseUrl, rect) {
53
+ const left = Math.max(0, Math.round(rect.left));
54
+ const top = Math.max(0, Math.round(rect.top));
55
+ const width = Math.max(1, Math.round(rect.width));
56
+ const height = Math.max(1, Math.round(rect.height));
57
+ return `${baseUrl}?trim.left=${left}&trim.top=${top}&trim.width=${width}&trim.height=${height}`;
58
+ }
59
+
20
60
  // src/components/media-library.tsx
21
61
  import { useState as useState4, useEffect as useEffect4, useRef as useRef4, useCallback } from "react";
22
62
 
@@ -182,6 +222,9 @@ async function runUpload(target, file, metadata, assetId, progress, onStep) {
182
222
  uploaded = true;
183
223
  }
184
224
  const nextProgress = { presigned, uploaded };
225
+ if (presigned === void 0) {
226
+ throw new UploadFlowError("Resume state is missing its presign result", nextProgress);
227
+ }
185
228
  const presignedResult = presigned;
186
229
  onStep("finalizing");
187
230
  const finalizePath = assetId ? `/media/${encodeURIComponent(assetId)}/versions/finalize` : "/media/finalize";
@@ -1284,12 +1327,13 @@ function MediaLibrary({ isOpen, onClose, onSelect, onSelectItem }) {
1284
1327
  onClose();
1285
1328
  };
1286
1329
  const deleteItem = (item) => {
1287
- if (!item.assetId) return;
1330
+ const { assetId } = item;
1331
+ if (!assetId) return;
1288
1332
  (async () => {
1289
1333
  try {
1290
1334
  const params = siteParams(config);
1291
1335
  const response = await fetch(
1292
- config.workerUrl + "/media/" + encodeURIComponent(item.assetId) + "?" + params.toString(),
1336
+ config.workerUrl + "/media/" + encodeURIComponent(assetId) + "?" + params.toString(),
1293
1337
  {
1294
1338
  method: "DELETE",
1295
1339
  headers: await getAuthHeaders()
@@ -1427,46 +1471,6 @@ function MediaLibrary({ isOpen, onClose, onSelect, onSelectItem }) {
1427
1471
  );
1428
1472
  }
1429
1473
 
1430
- // src/crop.ts
1431
- function getBaseUrl(value) {
1432
- return value ? value.split("?")[0] : "";
1433
- }
1434
- function getParams(value) {
1435
- return new URLSearchParams(value.includes("?") ? value.split("?")[1] : "");
1436
- }
1437
- function getCropMode(value) {
1438
- if (!value) return "fit";
1439
- const params = getParams(value);
1440
- if (params.has("trim.left")) return "custom";
1441
- return params.get("fit") === "cover" ? "smart" : "fit";
1442
- }
1443
- function getTrimRect(value) {
1444
- if (!value) return null;
1445
- const params = getParams(value);
1446
- const read = (key) => {
1447
- const raw = params.get(key);
1448
- if (raw === null || raw === "") return null;
1449
- const n2 = Number(raw);
1450
- return Number.isFinite(n2) ? n2 : null;
1451
- };
1452
- const left = read("trim.left");
1453
- const top = read("trim.top");
1454
- const width = read("trim.width");
1455
- const height = read("trim.height");
1456
- if (left === null || top === null || width === null || height === null) return null;
1457
- return { left, top, width, height };
1458
- }
1459
- function buildValueWithCrop(baseUrl, crop) {
1460
- return crop === "smart" ? `${baseUrl}?fit=cover&gravity=auto` : `${baseUrl}?fit=scale-down`;
1461
- }
1462
- function buildValueWithTrim(baseUrl, rect) {
1463
- const left = Math.max(0, Math.round(rect.left));
1464
- const top = Math.max(0, Math.round(rect.top));
1465
- const width = Math.max(1, Math.round(rect.width));
1466
- const height = Math.max(1, Math.round(rect.height));
1467
- return `${baseUrl}?trim.left=${left}&trim.top=${top}&trim.width=${width}&trim.height=${height}`;
1468
- }
1469
-
1470
1474
  // src/components/media-field.tsx
1471
1475
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1472
1476
  function MediaFieldRender(props) {
@@ -1621,10 +1625,73 @@ function MediaFieldRender(props) {
1621
1625
  // src/components/media-object-field.tsx
1622
1626
  import { useState as useState7 } from "react";
1623
1627
 
1628
+ // src/media-value.ts
1629
+ var STRUCTURAL_MEDIA_KEYS = /* @__PURE__ */ new Set([
1630
+ "assetId",
1631
+ "versionId",
1632
+ "url",
1633
+ "metaSchemaVersion"
1634
+ ]);
1635
+ function isMediaValue(value) {
1636
+ return typeof value === "object" && value !== null;
1637
+ }
1638
+ function makeMediaValue(input) {
1639
+ if (!input.assetId || !input.versionId) {
1640
+ return input.url;
1641
+ }
1642
+ const value = {
1643
+ assetId: input.assetId,
1644
+ versionId: input.versionId,
1645
+ url: input.url
1646
+ };
1647
+ if (typeof input.metaSchemaVersion === "number") {
1648
+ value.metaSchemaVersion = input.metaSchemaVersion;
1649
+ }
1650
+ if (input.metadata) {
1651
+ for (const [k, v] of Object.entries(input.metadata)) {
1652
+ if (v === void 0 || v === "") continue;
1653
+ if (STRUCTURAL_MEDIA_KEYS.has(k)) continue;
1654
+ value[k] = v;
1655
+ }
1656
+ }
1657
+ return value;
1658
+ }
1659
+ function buildValueFromAsset(asset, crop) {
1660
+ const metadata = { ...asset.metadata ?? {} };
1661
+ if (typeof asset.width === "number") metadata.width = asset.width;
1662
+ if (typeof asset.height === "number") metadata.height = asset.height;
1663
+ return makeMediaValue({
1664
+ assetId: asset.assetId,
1665
+ versionId: asset.versionId,
1666
+ url: buildValueWithCrop(getBaseUrl(asset.url), crop),
1667
+ metaSchemaVersion: asset.metaSchemaVersion,
1668
+ metadata
1669
+ });
1670
+ }
1671
+ function applyCropToValue(value, crop) {
1672
+ const currentUrl = isMediaValue(value) ? value.url : value;
1673
+ const baseUrl = getBaseUrl(typeof currentUrl === "string" ? currentUrl : "");
1674
+ if (!baseUrl) return value;
1675
+ const url = buildValueWithCrop(baseUrl, crop);
1676
+ return isMediaValue(value) ? { ...value, url } : url;
1677
+ }
1678
+ function applyTrimToValue(value, rect) {
1679
+ const currentUrl = isMediaValue(value) ? value.url : value;
1680
+ const baseUrl = getBaseUrl(typeof currentUrl === "string" ? currentUrl : "");
1681
+ if (!baseUrl) return value;
1682
+ const url = buildValueWithTrim(baseUrl, rect);
1683
+ return isMediaValue(value) ? { ...value, url } : url;
1684
+ }
1685
+ function setMetaOnValue(value, fieldName, fieldValue) {
1686
+ if (!isMediaValue(value)) return value;
1687
+ if (STRUCTURAL_MEDIA_KEYS.has(fieldName)) return value;
1688
+ return { ...value, [fieldName]: fieldValue };
1689
+ }
1690
+
1624
1691
  // src/components/crop-dialog.tsx
1625
1692
  import { useEffect as useEffect5, useRef as useRef5, useState as useState6 } from "react";
1626
1693
 
1627
- // ../../node_modules/.pnpm/react-image-crop@11.1.2_react@19.2.6/node_modules/react-image-crop/dist/index.js
1694
+ // ../../node_modules/.pnpm/react-image-crop@11.1.2_react@19.2.7/node_modules/react-image-crop/dist/index.js
1628
1695
  import e, { PureComponent as t, createRef as n } from "react";
1629
1696
  var r = {
1630
1697
  x: 0,
@@ -2053,7 +2120,7 @@ function styleInject(css, { insertAt } = {}) {
2053
2120
  }
2054
2121
  }
2055
2122
 
2056
- // ../../node_modules/.pnpm/react-image-crop@11.1.2_react@19.2.6/node_modules/react-image-crop/dist/ReactCrop.css
2123
+ // ../../node_modules/.pnpm/react-image-crop@11.1.2_react@19.2.7/node_modules/react-image-crop/dist/ReactCrop.css
2057
2124
  styleInject('@keyframes marching-ants {\n 0% {\n background-position:\n 0 0,\n 0 100%,\n 0 0,\n 100% 0;\n }\n to {\n background-position:\n 20px 0,\n -20px 100%,\n 0 -20px,\n 100% 20px;\n }\n}\n:root {\n --rc-drag-handle-size:12px;\n --rc-drag-handle-mobile-size:24px;\n --rc-drag-handle-bg-colour:#0003;\n --rc-drag-bar-size:6px;\n --rc-border-color:#ffffffb3;\n --rc-focus-color:#08f;\n}\n.ReactCrop {\n cursor: crosshair;\n max-width: 100%;\n display: inline-block;\n position: relative;\n}\n.ReactCrop *,\n.ReactCrop :before,\n.ReactCrop :after {\n box-sizing: border-box;\n}\n.ReactCrop--disabled,\n.ReactCrop--locked {\n cursor: inherit;\n}\n.ReactCrop__child-wrapper {\n max-height: inherit;\n overflow: hidden;\n}\n.ReactCrop__child-wrapper > img,\n.ReactCrop__child-wrapper > video {\n max-width: 100%;\n max-height: inherit;\n display: block;\n}\n.ReactCrop:not(.ReactCrop--disabled) .ReactCrop__child-wrapper > img,\n.ReactCrop:not(.ReactCrop--disabled) .ReactCrop__child-wrapper > video,\n.ReactCrop:not(.ReactCrop--disabled) .ReactCrop__crop-selection {\n touch-action: none;\n}\n.ReactCrop__crop-mask {\n pointer-events: none;\n width: calc(100% + .5px);\n height: calc(100% + .5px);\n position: absolute;\n inset: 0;\n}\n.ReactCrop__crop-selection {\n cursor: move;\n position: absolute;\n top: 0;\n left: 0;\n transform: translate(0, 0);\n}\n.ReactCrop--disabled .ReactCrop__crop-selection {\n cursor: inherit;\n}\n.ReactCrop--circular-crop .ReactCrop__crop-selection {\n border-radius: 50%;\n}\n.ReactCrop--circular-crop .ReactCrop__crop-selection:after {\n pointer-events: none;\n content: "";\n border: 1px solid var(--rc-border-color);\n opacity: .3;\n position: absolute;\n inset: -1px;\n}\n.ReactCrop--no-animate .ReactCrop__crop-selection {\n outline: 1px dashed #fff;\n}\n.ReactCrop__crop-selection:not(.ReactCrop--no-animate .ReactCrop__crop-selection) {\n color: #fff;\n background-image:\n linear-gradient(\n 90deg,\n #fff 50%,\n #444 50%),\n linear-gradient(\n 90deg,\n #fff 50%,\n #444 50%),\n linear-gradient(#fff 50%, #444 50%),\n linear-gradient(#fff 50%, #444 50%);\n background-position:\n 0 0,\n 0 100%,\n 0 0,\n 100% 0;\n background-repeat:\n repeat-x,\n repeat-x,\n repeat-y,\n repeat-y;\n background-size:\n 10px 1px,\n 10px 1px,\n 1px 10px,\n 1px 10px;\n animation: 1s linear infinite marching-ants;\n}\n.ReactCrop__crop-selection:focus {\n outline: 2px solid var(--rc-focus-color);\n outline-offset: -1px;\n}\n.ReactCrop--invisible-crop .ReactCrop__crop-mask,\n.ReactCrop--invisible-crop .ReactCrop__crop-selection {\n display: none;\n}\n.ReactCrop__rule-of-thirds-vt:before,\n.ReactCrop__rule-of-thirds-vt:after,\n.ReactCrop__rule-of-thirds-hz:before,\n.ReactCrop__rule-of-thirds-hz:after {\n content: "";\n background-color: #fff6;\n display: block;\n position: absolute;\n}\n.ReactCrop__rule-of-thirds-vt:before,\n.ReactCrop__rule-of-thirds-vt:after {\n width: 1px;\n height: 100%;\n}\n.ReactCrop__rule-of-thirds-vt:before {\n left: 33.3333%;\n}\n.ReactCrop__rule-of-thirds-vt:after {\n left: 66.6667%;\n}\n.ReactCrop__rule-of-thirds-hz:before,\n.ReactCrop__rule-of-thirds-hz:after {\n width: 100%;\n height: 1px;\n}\n.ReactCrop__rule-of-thirds-hz:before {\n top: 33.3333%;\n}\n.ReactCrop__rule-of-thirds-hz:after {\n top: 66.6667%;\n}\n.ReactCrop__drag-handle {\n width: var(--rc-drag-handle-size);\n height: var(--rc-drag-handle-size);\n background-color: var(--rc-drag-handle-bg-colour);\n border: 1px solid var(--rc-border-color);\n position: absolute;\n}\n.ReactCrop__drag-handle:focus {\n background: var(--rc-focus-color);\n}\n.ReactCrop .ord-nw {\n cursor: nw-resize;\n top: 0;\n left: 0;\n transform: translate(-50%, -50%);\n}\n.ReactCrop .ord-n {\n cursor: n-resize;\n top: 0;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n.ReactCrop .ord-ne {\n cursor: ne-resize;\n top: 0;\n right: 0;\n transform: translate(50%, -50%);\n}\n.ReactCrop .ord-e {\n cursor: e-resize;\n top: 50%;\n right: 0;\n transform: translate(50%, -50%);\n}\n.ReactCrop .ord-se {\n cursor: se-resize;\n bottom: 0;\n right: 0;\n transform: translate(50%, 50%);\n}\n.ReactCrop .ord-s {\n cursor: s-resize;\n bottom: 0;\n left: 50%;\n transform: translate(-50%, 50%);\n}\n.ReactCrop .ord-sw {\n cursor: sw-resize;\n bottom: 0;\n left: 0;\n transform: translate(-50%, 50%);\n}\n.ReactCrop .ord-w {\n cursor: w-resize;\n top: 50%;\n left: 0;\n transform: translate(-50%, -50%);\n}\n.ReactCrop__disabled .ReactCrop__drag-handle {\n cursor: inherit;\n}\n.ReactCrop__drag-bar {\n position: absolute;\n}\n.ReactCrop__drag-bar.ord-n {\n width: 100%;\n height: var(--rc-drag-bar-size);\n top: 0;\n left: 0;\n transform: translateY(-50%);\n}\n.ReactCrop__drag-bar.ord-e {\n width: var(--rc-drag-bar-size);\n height: 100%;\n top: 0;\n right: 0;\n transform: translate(50%);\n}\n.ReactCrop__drag-bar.ord-s {\n width: 100%;\n height: var(--rc-drag-bar-size);\n bottom: 0;\n left: 0;\n transform: translateY(50%);\n}\n.ReactCrop__drag-bar.ord-w {\n width: var(--rc-drag-bar-size);\n height: 100%;\n top: 0;\n left: 0;\n transform: translate(-50%);\n}\n.ReactCrop--new-crop .ReactCrop__drag-bar,\n.ReactCrop--new-crop .ReactCrop__drag-handle,\n.ReactCrop--fixed-aspect .ReactCrop__drag-bar,\n.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-n,\n.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-e,\n.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-s,\n.ReactCrop--fixed-aspect .ReactCrop__drag-handle.ord-w {\n display: none;\n}\n@media (pointer: coarse) {\n .ReactCrop .ord-n,\n .ReactCrop .ord-e,\n .ReactCrop .ord-s,\n .ReactCrop .ord-w {\n display: none;\n }\n .ReactCrop__drag-handle {\n width: var(--rc-drag-handle-mobile-size);\n height: var(--rc-drag-handle-mobile-size);\n }\n}\n');
2058
2125
 
2059
2126
  // src/components/crop-dialog.tsx
@@ -2300,69 +2367,6 @@ function CropDialog(props) {
2300
2367
  );
2301
2368
  }
2302
2369
 
2303
- // src/media-value.ts
2304
- var STRUCTURAL_MEDIA_KEYS = /* @__PURE__ */ new Set([
2305
- "assetId",
2306
- "versionId",
2307
- "url",
2308
- "metaSchemaVersion"
2309
- ]);
2310
- function isMediaValue(value) {
2311
- return typeof value === "object" && value !== null;
2312
- }
2313
- function makeMediaValue(input) {
2314
- if (!input.assetId || !input.versionId) {
2315
- return input.url;
2316
- }
2317
- const value = {
2318
- assetId: input.assetId,
2319
- versionId: input.versionId,
2320
- url: input.url
2321
- };
2322
- if (typeof input.metaSchemaVersion === "number") {
2323
- value.metaSchemaVersion = input.metaSchemaVersion;
2324
- }
2325
- if (input.metadata) {
2326
- for (const [k, v] of Object.entries(input.metadata)) {
2327
- if (v === void 0 || v === "") continue;
2328
- if (STRUCTURAL_MEDIA_KEYS.has(k)) continue;
2329
- value[k] = v;
2330
- }
2331
- }
2332
- return value;
2333
- }
2334
- function buildValueFromAsset(asset, crop) {
2335
- const metadata = { ...asset.metadata ?? {} };
2336
- if (typeof asset.width === "number") metadata.width = asset.width;
2337
- if (typeof asset.height === "number") metadata.height = asset.height;
2338
- return makeMediaValue({
2339
- assetId: asset.assetId,
2340
- versionId: asset.versionId,
2341
- url: buildValueWithCrop(getBaseUrl(asset.url), crop),
2342
- metaSchemaVersion: asset.metaSchemaVersion,
2343
- metadata
2344
- });
2345
- }
2346
- function applyCropToValue(value, crop) {
2347
- const currentUrl = isMediaValue(value) ? value.url : value;
2348
- const baseUrl = getBaseUrl(typeof currentUrl === "string" ? currentUrl : "");
2349
- if (!baseUrl) return value;
2350
- const url = buildValueWithCrop(baseUrl, crop);
2351
- return isMediaValue(value) ? { ...value, url } : url;
2352
- }
2353
- function applyTrimToValue(value, rect) {
2354
- const currentUrl = isMediaValue(value) ? value.url : value;
2355
- const baseUrl = getBaseUrl(typeof currentUrl === "string" ? currentUrl : "");
2356
- if (!baseUrl) return value;
2357
- const url = buildValueWithTrim(baseUrl, rect);
2358
- return isMediaValue(value) ? { ...value, url } : url;
2359
- }
2360
- function setMetaOnValue(value, fieldName, fieldValue) {
2361
- if (!isMediaValue(value)) return value;
2362
- if (STRUCTURAL_MEDIA_KEYS.has(fieldName)) return value;
2363
- return { ...value, [fieldName]: fieldValue };
2364
- }
2365
-
2366
2370
  // src/components/media-object-field.tsx
2367
2371
  import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2368
2372
  function MediaObjectFieldRender(props) {