@nonphoto/sanity-image 4.0.0 → 5.0.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.
- package/dist/index.d.ts +515 -76
- package/dist/index.js +277 -139
- package/package.json +5 -2
- package/src/asset.ts +88 -73
- package/src/constants.ts +7 -19
- package/src/crop.ts +14 -6
- package/src/hotspot.ts +14 -0
- package/src/image.ts +41 -28
- package/src/index.ts +2 -1
- package/src/rect.ts +16 -9
- package/src/transformations.ts +155 -0
- package/src/options.ts +0 -130
package/dist/index.js
CHANGED
|
@@ -1,83 +1,126 @@
|
|
|
1
1
|
// src/asset.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
2
|
+
import {
|
|
3
|
+
is as is5,
|
|
4
|
+
nullish,
|
|
5
|
+
number as number5,
|
|
6
|
+
object as object5,
|
|
7
|
+
string as string2,
|
|
8
|
+
union as union2
|
|
9
|
+
} from "valibot";
|
|
10
|
+
|
|
11
|
+
// src/crop.ts
|
|
12
|
+
import { is, number, object, optional } from "valibot";
|
|
13
|
+
var cropSchema = object({
|
|
14
|
+
top: optional(number()),
|
|
15
|
+
bottom: optional(number()),
|
|
16
|
+
left: optional(number()),
|
|
17
|
+
right: optional(number())
|
|
18
|
+
});
|
|
19
|
+
function isCrop(input) {
|
|
20
|
+
return is(cropSchema, input);
|
|
16
21
|
}
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
|
|
23
|
+
// src/hotspot.ts
|
|
24
|
+
import { is as is2, number as number2, object as object2, optional as optional2 } from "valibot";
|
|
25
|
+
var hotspotSchema = object2({
|
|
26
|
+
x: optional2(number2()),
|
|
27
|
+
y: optional2(number2()),
|
|
28
|
+
width: optional2(number2()),
|
|
29
|
+
height: optional2(number2())
|
|
30
|
+
});
|
|
31
|
+
function isHotspot(input) {
|
|
32
|
+
return is2(hotspotSchema, input);
|
|
19
33
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
extension
|
|
30
|
-
};
|
|
31
|
-
}
|
|
34
|
+
|
|
35
|
+
// src/rect.ts
|
|
36
|
+
import { is as is3, number as number3, object as object3, tuple } from "valibot";
|
|
37
|
+
var rectSchema = object3({
|
|
38
|
+
pos: tuple([number3(), number3()]),
|
|
39
|
+
size: tuple([number3(), number3()])
|
|
40
|
+
});
|
|
41
|
+
function isRect(input) {
|
|
42
|
+
return is3(rectSchema, input);
|
|
32
43
|
}
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
function rectFromCrop(asset, crop) {
|
|
45
|
+
const left = Math.max(crop.left ?? 0, 0);
|
|
46
|
+
const right = Math.max(crop.right ?? 0, 0);
|
|
47
|
+
const top = Math.max(crop.top ?? 0, 0);
|
|
48
|
+
const bottom = Math.max(crop.bottom ?? 0, 0);
|
|
49
|
+
return {
|
|
50
|
+
pos: [left * asset.width, top * asset.height],
|
|
51
|
+
size: [(1 - left - right) * asset.width, (1 - top - bottom) * asset.height]
|
|
52
|
+
};
|
|
40
53
|
}
|
|
41
54
|
|
|
42
|
-
// src/
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
55
|
+
// src/transformations.ts
|
|
56
|
+
import {
|
|
57
|
+
boolean,
|
|
58
|
+
is as is4,
|
|
59
|
+
literal,
|
|
60
|
+
number as number4,
|
|
61
|
+
object as object4,
|
|
62
|
+
partial,
|
|
63
|
+
string,
|
|
64
|
+
tuple as tuple2,
|
|
65
|
+
union
|
|
66
|
+
} from "valibot";
|
|
67
|
+
var transformationsSchema = partial(
|
|
68
|
+
object4({
|
|
69
|
+
auto: literal("format"),
|
|
70
|
+
background: string(),
|
|
71
|
+
blur: number4(),
|
|
72
|
+
crop: union([
|
|
73
|
+
literal("top"),
|
|
74
|
+
literal("bottom"),
|
|
75
|
+
literal("left"),
|
|
76
|
+
literal("right"),
|
|
77
|
+
literal("center"),
|
|
78
|
+
literal("focalpoint"),
|
|
79
|
+
literal("entropy")
|
|
80
|
+
]),
|
|
81
|
+
download: union([string(), boolean()]),
|
|
82
|
+
dpr: union([literal(1), literal(2), literal(3)]),
|
|
83
|
+
fit: union([
|
|
84
|
+
literal("clip"),
|
|
85
|
+
literal("crop"),
|
|
86
|
+
literal("fill"),
|
|
87
|
+
literal("fillmax"),
|
|
88
|
+
literal("max"),
|
|
89
|
+
literal("scale"),
|
|
90
|
+
literal("min")
|
|
91
|
+
]),
|
|
92
|
+
flipHorizontal: boolean(),
|
|
93
|
+
flipVertical: boolean(),
|
|
94
|
+
focalPoint: tuple2([number4(), number4()]),
|
|
95
|
+
format: union([
|
|
96
|
+
literal("jpg"),
|
|
97
|
+
literal("pjpg"),
|
|
98
|
+
literal("png"),
|
|
99
|
+
literal("webp")
|
|
100
|
+
]),
|
|
101
|
+
frame: number4(),
|
|
102
|
+
height: number4(),
|
|
103
|
+
invert: boolean(),
|
|
104
|
+
maxHeight: number4(),
|
|
105
|
+
maxWidth: number4(),
|
|
106
|
+
minHeight: number4(),
|
|
107
|
+
minWidth: number4(),
|
|
108
|
+
orientation: union([literal(0), literal(90), literal(180), literal(270)]),
|
|
109
|
+
pad: number4(),
|
|
110
|
+
quality: number4(),
|
|
111
|
+
rect: rectSchema,
|
|
112
|
+
saturation: number4(),
|
|
113
|
+
sharpen: number4(),
|
|
114
|
+
width: number4()
|
|
115
|
+
})
|
|
116
|
+
);
|
|
117
|
+
function isTransformations(input) {
|
|
118
|
+
return is4(transformationsSchema, input);
|
|
79
119
|
}
|
|
80
|
-
function
|
|
120
|
+
function entry(key, value) {
|
|
121
|
+
return value == null || value === false ? void 0 : [key, String(typeof value === "number" ? Math.round(value) : value)];
|
|
122
|
+
}
|
|
123
|
+
function transformationsToURLSearch({
|
|
81
124
|
auto,
|
|
82
125
|
background,
|
|
83
126
|
blur,
|
|
@@ -104,92 +147,187 @@ function imageOptionsToSearchParamEntries({
|
|
|
104
147
|
sharpen,
|
|
105
148
|
width
|
|
106
149
|
}) {
|
|
107
|
-
return
|
|
108
|
-
auto,
|
|
109
|
-
bg
|
|
110
|
-
blur,
|
|
111
|
-
crop,
|
|
112
|
-
dl
|
|
113
|
-
dpr,
|
|
114
|
-
fit,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
150
|
+
return "?" + [
|
|
151
|
+
entry("auto", auto),
|
|
152
|
+
entry("bg", background),
|
|
153
|
+
entry("blur", blur),
|
|
154
|
+
entry("crop", crop),
|
|
155
|
+
entry("dl", download),
|
|
156
|
+
entry("dpr", dpr),
|
|
157
|
+
entry("fit", fit),
|
|
158
|
+
entry(
|
|
159
|
+
"flip",
|
|
160
|
+
flipHorizontal || flipVertical ? [flipHorizontal && "h", flipVertical && "v"].filter(Boolean).join("") : void 0
|
|
161
|
+
),
|
|
162
|
+
entry("fm", format),
|
|
163
|
+
entry("fp-x", focalPoint?.[0]),
|
|
164
|
+
entry("fp-y", focalPoint?.[1]),
|
|
165
|
+
entry("frame", frame),
|
|
166
|
+
entry("h", height),
|
|
167
|
+
entry("invert", invert),
|
|
168
|
+
entry("max-h", maxHeight),
|
|
169
|
+
entry("max-w", maxWidth),
|
|
170
|
+
entry("min-h", minHeight),
|
|
171
|
+
entry("min-w", minWidth),
|
|
172
|
+
entry("or", orientation),
|
|
173
|
+
entry("pad", pad),
|
|
174
|
+
entry("q", quality),
|
|
175
|
+
entry(
|
|
176
|
+
"rect",
|
|
177
|
+
rect ? [rect.pos[0], rect.pos[1], rect.size[0], rect.size[1]].map(Math.round).join(",") : void 0
|
|
178
|
+
),
|
|
179
|
+
entry("sat", saturation),
|
|
180
|
+
entry("sharp", sharpen),
|
|
181
|
+
entry("w", width)
|
|
182
|
+
].filter((entry2) => entry2 != null).map((entry2) => entry2.join("=")).join("&");
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/asset.ts
|
|
186
|
+
var assetLikeSchema = object5({
|
|
187
|
+
_id: string2()
|
|
188
|
+
});
|
|
189
|
+
var referenceLikeSchema = object5({
|
|
190
|
+
_ref: string2()
|
|
191
|
+
});
|
|
192
|
+
var imageObjectSchema = object5({
|
|
193
|
+
asset: nullish(union2([assetLikeSchema, referenceLikeSchema, string2()])),
|
|
194
|
+
crop: nullish(cropSchema),
|
|
195
|
+
hotspot: nullish(hotspotSchema)
|
|
196
|
+
});
|
|
197
|
+
var imageAssetSchema = object5({
|
|
198
|
+
_id: string2(),
|
|
199
|
+
assetId: string2(),
|
|
200
|
+
width: number5(),
|
|
201
|
+
height: number5(),
|
|
202
|
+
extension: string2(),
|
|
203
|
+
vanityName: nullish(string2()),
|
|
204
|
+
transformations: nullish(transformationsSchema)
|
|
205
|
+
});
|
|
206
|
+
function isAssetLike(input) {
|
|
207
|
+
return is5(assetLikeSchema, input);
|
|
208
|
+
}
|
|
209
|
+
function isReferenceLike(input) {
|
|
210
|
+
return is5(referenceLikeSchema, input);
|
|
211
|
+
}
|
|
212
|
+
function isImageObject(input) {
|
|
213
|
+
return is5(imageObjectSchema, input);
|
|
214
|
+
}
|
|
215
|
+
function isImageAsset(input) {
|
|
216
|
+
return is5(imageAssetSchema, input);
|
|
137
217
|
}
|
|
218
|
+
function assetIdFromSource(source) {
|
|
219
|
+
return typeof source === "string" ? source : isAssetLike(source) ? source._id : isReferenceLike(source) ? source._ref : isImageObject(source) && source.asset ? assetIdFromSource(source.asset) : void 0;
|
|
220
|
+
}
|
|
221
|
+
function parseAssetId(id) {
|
|
222
|
+
const matches = id.match(/^image-(\w+)-(\d+)x(\d+)-(\w+)$/);
|
|
223
|
+
if (matches) {
|
|
224
|
+
const [, assetId, width, height, extension] = matches;
|
|
225
|
+
return {
|
|
226
|
+
_id: id,
|
|
227
|
+
assetId,
|
|
228
|
+
width: Number(width),
|
|
229
|
+
height: Number(height),
|
|
230
|
+
extension
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function imageAssetFromSource(source) {
|
|
235
|
+
if (typeof source === "object" && "assetId" in source) {
|
|
236
|
+
return source;
|
|
237
|
+
} else {
|
|
238
|
+
const id = assetIdFromSource(source);
|
|
239
|
+
const asset = id ? parseAssetId(id) : void 0;
|
|
240
|
+
return asset ? imageAssetWithTransformations(asset, {
|
|
241
|
+
rect: typeof source === "object" && "crop" in source && source.crop ? rectFromCrop(asset, source.crop) : void 0
|
|
242
|
+
}) : void 0;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function imageAssetWithTransformations(asset, transformations) {
|
|
246
|
+
return {
|
|
247
|
+
...asset,
|
|
248
|
+
transformations: { ...asset.transformations, ...transformations }
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// src/constants.ts
|
|
253
|
+
var srcsetWidths = {
|
|
254
|
+
default: [2560, 1920, 1280, 960, 640, 480, 360, 240],
|
|
255
|
+
expanded: [
|
|
256
|
+
3840,
|
|
257
|
+
3200,
|
|
258
|
+
2560,
|
|
259
|
+
2048,
|
|
260
|
+
1920,
|
|
261
|
+
1668,
|
|
262
|
+
1280,
|
|
263
|
+
1080,
|
|
264
|
+
960,
|
|
265
|
+
720,
|
|
266
|
+
640,
|
|
267
|
+
480,
|
|
268
|
+
360,
|
|
269
|
+
240
|
|
270
|
+
]
|
|
271
|
+
};
|
|
138
272
|
|
|
139
273
|
// src/image.ts
|
|
140
|
-
function imageUrl(client, asset
|
|
274
|
+
function imageUrl(client, asset) {
|
|
141
275
|
const url = new URL(
|
|
142
276
|
[
|
|
143
|
-
|
|
277
|
+
"https://cdn.sanity.io/images",
|
|
144
278
|
client.projectId,
|
|
145
279
|
client.dataset,
|
|
146
280
|
`${asset.assetId}-${asset.width}x${asset.height}.${asset.extension}`,
|
|
147
|
-
|
|
281
|
+
asset.vanityName
|
|
148
282
|
].filter(Boolean).join("/")
|
|
149
283
|
);
|
|
150
|
-
if (
|
|
151
|
-
url.search =
|
|
152
|
-
imageOptionsToSearchParamEntries(options)
|
|
153
|
-
).toString();
|
|
284
|
+
if (asset.transformations) {
|
|
285
|
+
url.search = transformationsToURLSearch(asset.transformations);
|
|
154
286
|
}
|
|
155
287
|
return url.href;
|
|
156
288
|
}
|
|
157
|
-
function imageSrcset(client, asset,
|
|
158
|
-
return
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
});
|
|
289
|
+
function imageSrcset(client, asset, widths = srcsetWidths.default) {
|
|
290
|
+
return widths.sort((a, b) => a - b).filter((width) => width < asset.width).map(Math.round).map((width) => {
|
|
291
|
+
const url = imageUrl(
|
|
292
|
+
client,
|
|
293
|
+
imageAssetWithTransformations(asset, {
|
|
294
|
+
width
|
|
295
|
+
})
|
|
296
|
+
);
|
|
166
297
|
return `${url} ${width}w`;
|
|
167
298
|
}).join(",");
|
|
168
299
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const top = crop.top ?? 0;
|
|
175
|
-
const bottom = crop.bottom ?? 0;
|
|
176
|
-
return {
|
|
177
|
-
pos: [left * asset.width, right * asset.width],
|
|
178
|
-
size: [(1 - left - right) * asset.width, (1 - top - bottom) * asset.height]
|
|
179
|
-
};
|
|
300
|
+
function imageAspectRatio(asset) {
|
|
301
|
+
const size = asset.transformations && ["crop", "fill", "fillmax", "scale", "min"].includes(
|
|
302
|
+
asset.transformations.fit ?? ""
|
|
303
|
+
) && asset.transformations.width != null && asset.transformations.height != null ? [asset.transformations.width, asset.transformations.height] : asset.transformations?.rect ? asset.transformations.rect.size : [asset.width, asset.height];
|
|
304
|
+
return size[0] / size[1];
|
|
180
305
|
}
|
|
181
306
|
export {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
307
|
+
assetIdFromSource,
|
|
308
|
+
assetLikeSchema,
|
|
309
|
+
cropSchema,
|
|
310
|
+
hotspotSchema,
|
|
311
|
+
imageAspectRatio,
|
|
312
|
+
imageAssetFromSource,
|
|
313
|
+
imageAssetSchema,
|
|
314
|
+
imageAssetWithTransformations,
|
|
315
|
+
imageObjectSchema,
|
|
189
316
|
imageSrcset,
|
|
190
317
|
imageUrl,
|
|
191
318
|
isAssetLike,
|
|
319
|
+
isCrop,
|
|
320
|
+
isHotspot,
|
|
192
321
|
isImageAsset,
|
|
193
|
-
|
|
194
|
-
|
|
322
|
+
isImageObject,
|
|
323
|
+
isRect,
|
|
324
|
+
isReferenceLike,
|
|
325
|
+
isTransformations,
|
|
326
|
+
parseAssetId,
|
|
327
|
+
rectFromCrop,
|
|
328
|
+
rectSchema,
|
|
329
|
+
referenceLikeSchema,
|
|
330
|
+
srcsetWidths,
|
|
331
|
+
transformationsSchema,
|
|
332
|
+
transformationsToURLSearch
|
|
195
333
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nonphoto/sanity-image",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"author": "Jonas Luebbers <jonas@jonasluebbers.com> (https://www.jonasluebbers.com)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,5 +36,8 @@
|
|
|
36
36
|
"engines": {
|
|
37
37
|
"node": ">=20"
|
|
38
38
|
},
|
|
39
|
-
"packageManager": "pnpm@10.12.1"
|
|
39
|
+
"packageManager": "pnpm@10.12.1",
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"valibot": "^1.1.0"
|
|
42
|
+
}
|
|
40
43
|
}
|
package/src/asset.ts
CHANGED
|
@@ -1,90 +1,85 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
extension: string;
|
|
15
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
InferOutput,
|
|
3
|
+
is,
|
|
4
|
+
nullish,
|
|
5
|
+
number,
|
|
6
|
+
object,
|
|
7
|
+
string,
|
|
8
|
+
union,
|
|
9
|
+
} from "valibot";
|
|
10
|
+
import { cropSchema } from "./crop";
|
|
11
|
+
import { hotspotSchema } from "./hotspot";
|
|
12
|
+
import { rectFromCrop } from "./rect";
|
|
13
|
+
import { Transformations, transformationsSchema } from "./transformations";
|
|
16
14
|
|
|
17
|
-
export type
|
|
18
|
-
|
|
|
19
|
-
asset: ImageAssetSource;
|
|
20
|
-
}
|
|
15
|
+
export type ImageSource =
|
|
16
|
+
| ImageObject
|
|
21
17
|
| ImageAsset
|
|
22
18
|
| AssetLike
|
|
23
|
-
|
|
|
19
|
+
| ReferenceLike
|
|
24
20
|
| string;
|
|
25
21
|
|
|
22
|
+
export type AssetLike = InferOutput<typeof assetLikeSchema>;
|
|
23
|
+
|
|
24
|
+
export type ReferenceLike = InferOutput<typeof referenceLikeSchema>;
|
|
25
|
+
|
|
26
|
+
export type ImageObject = InferOutput<typeof imageObjectSchema>;
|
|
27
|
+
|
|
28
|
+
export type ImageAsset = InferOutput<typeof imageAssetSchema>;
|
|
29
|
+
|
|
30
|
+
export const assetLikeSchema = object({
|
|
31
|
+
_id: string(),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export const referenceLikeSchema = object({
|
|
35
|
+
_ref: string(),
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const imageObjectSchema = object({
|
|
39
|
+
asset: nullish(union([assetLikeSchema, referenceLikeSchema, string()])),
|
|
40
|
+
crop: nullish(cropSchema),
|
|
41
|
+
hotspot: nullish(hotspotSchema),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const imageAssetSchema = object({
|
|
45
|
+
_id: string(),
|
|
46
|
+
assetId: string(),
|
|
47
|
+
width: number(),
|
|
48
|
+
height: number(),
|
|
49
|
+
extension: string(),
|
|
50
|
+
vanityName: nullish(string()),
|
|
51
|
+
transformations: nullish(transformationsSchema),
|
|
52
|
+
});
|
|
53
|
+
|
|
26
54
|
export function isAssetLike(input: unknown): input is AssetLike {
|
|
27
|
-
return (
|
|
28
|
-
input != null &&
|
|
29
|
-
typeof input === "object" &&
|
|
30
|
-
"_id" in input &&
|
|
31
|
-
typeof input._id === "string"
|
|
32
|
-
);
|
|
55
|
+
return is(assetLikeSchema, input);
|
|
33
56
|
}
|
|
34
57
|
|
|
35
|
-
export function
|
|
36
|
-
return (
|
|
37
|
-
input != null &&
|
|
38
|
-
typeof input === "object" &&
|
|
39
|
-
"_ref" in input &&
|
|
40
|
-
typeof input._ref === "string"
|
|
41
|
-
);
|
|
58
|
+
export function isReferenceLike(input: unknown): input is ReferenceLike {
|
|
59
|
+
return is(referenceLikeSchema, input);
|
|
42
60
|
}
|
|
43
61
|
|
|
44
|
-
export function
|
|
45
|
-
return (
|
|
46
|
-
input != null &&
|
|
47
|
-
typeof input === "object" &&
|
|
48
|
-
"assetId" in input &&
|
|
49
|
-
typeof input.assetId === "string" &&
|
|
50
|
-
"width" in input &&
|
|
51
|
-
typeof input.width === "number" &&
|
|
52
|
-
"height" in input &&
|
|
53
|
-
typeof input.height === "number" &&
|
|
54
|
-
"extension" in input &&
|
|
55
|
-
typeof input.extension === "string"
|
|
56
|
-
);
|
|
62
|
+
export function isImageObject(input: unknown): input is ImageObject {
|
|
63
|
+
return is(imageObjectSchema, input);
|
|
57
64
|
}
|
|
58
65
|
|
|
59
|
-
export function
|
|
60
|
-
|
|
61
|
-
): input is { asset: NonNullable<unknown> } {
|
|
62
|
-
return input != null && typeof input === "object" && "asset" in input;
|
|
66
|
+
export function isImageAsset(input: unknown): input is ImageAsset {
|
|
67
|
+
return is(imageAssetSchema, input);
|
|
63
68
|
}
|
|
64
69
|
|
|
65
|
-
export function
|
|
70
|
+
export function assetIdFromSource(source: ImageSource): string | undefined {
|
|
66
71
|
return typeof source === "string"
|
|
67
72
|
? source
|
|
68
|
-
:
|
|
69
|
-
? source.
|
|
70
|
-
:
|
|
71
|
-
? source.
|
|
72
|
-
:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
export function imageIdFromUnknown(input: unknown): string | undefined {
|
|
76
|
-
return typeof input === "string"
|
|
77
|
-
? input
|
|
78
|
-
: isReference(input)
|
|
79
|
-
? input._ref
|
|
80
|
-
: isAssetLike(input)
|
|
81
|
-
? input._id
|
|
82
|
-
: hasAssetProp(input)
|
|
83
|
-
? imageIdFromUnknown(input.asset)
|
|
73
|
+
: isAssetLike(source)
|
|
74
|
+
? source._id
|
|
75
|
+
: isReferenceLike(source)
|
|
76
|
+
? source._ref
|
|
77
|
+
: isImageObject(source) && source.asset
|
|
78
|
+
? assetIdFromSource(source.asset)
|
|
84
79
|
: undefined;
|
|
85
80
|
}
|
|
86
81
|
|
|
87
|
-
export function
|
|
82
|
+
export function parseAssetId(id: string): ImageAsset | undefined {
|
|
88
83
|
const matches = id.match(/^image-(\w+)-(\d+)x(\d+)-(\w+)$/);
|
|
89
84
|
if (matches) {
|
|
90
85
|
const [, assetId, width, height, extension] = matches;
|
|
@@ -98,11 +93,31 @@ export function imageAsset(id: string): ImageAsset | undefined {
|
|
|
98
93
|
}
|
|
99
94
|
}
|
|
100
95
|
|
|
101
|
-
export function
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
export function imageAssetFromSource(
|
|
97
|
+
source: ImageSource,
|
|
98
|
+
): ImageAsset | undefined {
|
|
99
|
+
if (typeof source === "object" && "assetId" in source) {
|
|
100
|
+
return source;
|
|
104
101
|
} else {
|
|
105
|
-
const id =
|
|
106
|
-
|
|
102
|
+
const id = assetIdFromSource(source);
|
|
103
|
+
const asset = id ? parseAssetId(id) : undefined;
|
|
104
|
+
return asset
|
|
105
|
+
? imageAssetWithTransformations(asset, {
|
|
106
|
+
rect:
|
|
107
|
+
typeof source === "object" && "crop" in source && source.crop
|
|
108
|
+
? rectFromCrop(asset, source.crop)
|
|
109
|
+
: undefined,
|
|
110
|
+
})
|
|
111
|
+
: undefined;
|
|
107
112
|
}
|
|
108
113
|
}
|
|
114
|
+
|
|
115
|
+
export function imageAssetWithTransformations(
|
|
116
|
+
asset: ImageAsset,
|
|
117
|
+
transformations: Transformations,
|
|
118
|
+
): ImageAsset {
|
|
119
|
+
return {
|
|
120
|
+
...asset,
|
|
121
|
+
transformations: { ...asset.transformations, ...transformations },
|
|
122
|
+
};
|
|
123
|
+
}
|