@frogbotai/piece-image-helper 0.22.0 → 0.24.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/README.md +29 -0
- package/dist/actions/compress.d.ts +41 -0
- package/dist/actions/compress.d.ts.map +1 -0
- package/dist/actions/compress.js +30 -0
- package/dist/actions/compress.js.map +1 -0
- package/dist/actions/convertFormat.d.ts +51 -0
- package/dist/actions/convertFormat.d.ts.map +1 -0
- package/dist/actions/convertFormat.js +56 -0
- package/dist/actions/convertFormat.js.map +1 -0
- package/dist/actions/crop.d.ts +39 -0
- package/dist/actions/crop.d.ts.map +1 -0
- package/dist/actions/crop.js +31 -0
- package/dist/actions/crop.js.map +1 -0
- package/dist/actions/getMetadata.d.ts +21 -0
- package/dist/actions/getMetadata.d.ts.map +1 -0
- package/dist/actions/getMetadata.js +19 -0
- package/dist/actions/getMetadata.js.map +1 -0
- package/dist/actions/imageToBase64.d.ts +19 -0
- package/dist/actions/imageToBase64.d.ts.map +1 -0
- package/dist/actions/imageToBase64.js +18 -0
- package/dist/actions/imageToBase64.js.map +1 -0
- package/dist/actions/resize.d.ts +37 -0
- package/dist/actions/resize.d.ts.map +1 -0
- package/dist/actions/resize.js +30 -0
- package/dist/actions/resize.js.map +1 -0
- package/dist/actions/rotate.d.ts +33 -0
- package/dist/actions/rotate.d.ts.map +1 -0
- package/dist/actions/rotate.js +28 -0
- package/dist/actions/rotate.js.map +1 -0
- package/dist/files.d.ts +30 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +85 -0
- package/dist/files.js.map +1 -0
- package/dist/index.d.ts +207 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -37
- package/dist/index.js.map +1 -1
- package/package.json +12 -5
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# `@frogbotai/piece-image-helper`
|
|
2
|
+
|
|
3
|
+
Inspect, transform, compress, and convert images stored in FrogBot's files collection.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { createImageHelper } from '@frogbotai/piece-image-helper';
|
|
9
|
+
|
|
10
|
+
export const imageHelper = createImageHelper();
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Actions
|
|
14
|
+
|
|
15
|
+
| Upstream action slug | Previous wrapper export | Native action | Notes |
|
|
16
|
+
| ---------------------- | ----------------------- | --------------- | -------------------------------------------------------------- |
|
|
17
|
+
| `image_to_base64` | `imageToBase64` | `imageToBase64` | Returns a Base64 data URL. |
|
|
18
|
+
| `get_meta_data` | `getMetaData` | `getMetadata` | Returns embedded image metadata. |
|
|
19
|
+
| `crop_image` | `cropImage` | `crop` | Saves the cropped image to the files collection. |
|
|
20
|
+
| `rotate_image` | `rotateImage` | `rotate` | Saves the clockwise-rotated image to the files collection. |
|
|
21
|
+
| `resize_image` | `resizeImage` | `resize` | Saves the resized image to the files collection. |
|
|
22
|
+
| `compress_image` | `compressImage` | `compress` | Saves a JPEG or PNG to the files collection. |
|
|
23
|
+
| `convert_image_format` | `convertImageFormat` | `convertFormat` | Saves a JPEG, PNG, TIFF, BMP, or AVIF to the files collection. |
|
|
24
|
+
|
|
25
|
+
## Triggers
|
|
26
|
+
|
|
27
|
+
| Upstream trigger slug | Native trigger | Type | Notes |
|
|
28
|
+
| --------------------- | -------------- | ---- | ----------------------------------------- |
|
|
29
|
+
| None | None | None | The upstream piece registers no triggers. |
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type PieceRunArgs } from 'frogbot/pieces';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
declare const inputSchema: z.ZodObject<{
|
|
4
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
5
|
+
quality: z.ZodUnion<readonly [z.ZodLiteral<90>, z.ZodLiteral<60>]>;
|
|
6
|
+
format: z.ZodEnum<{
|
|
7
|
+
jpg: "jpg";
|
|
8
|
+
png: "png";
|
|
9
|
+
}>;
|
|
10
|
+
resultFileName: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export declare const compress: {
|
|
13
|
+
slug: string;
|
|
14
|
+
label: string;
|
|
15
|
+
description: string;
|
|
16
|
+
input: z.ZodObject<{
|
|
17
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
18
|
+
quality: z.ZodUnion<readonly [z.ZodLiteral<90>, z.ZodLiteral<60>]>;
|
|
19
|
+
format: z.ZodEnum<{
|
|
20
|
+
jpg: "jpg";
|
|
21
|
+
png: "png";
|
|
22
|
+
}>;
|
|
23
|
+
resultFileName: z.ZodOptional<z.ZodString>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
output: z.ZodObject<{
|
|
26
|
+
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
27
|
+
name: z.ZodString;
|
|
28
|
+
mimeType: z.ZodString;
|
|
29
|
+
size: z.ZodNumber;
|
|
30
|
+
url: z.ZodOptional<z.ZodString>;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
run({ input, req }: PieceRunArgs<z.output<typeof inputSchema>, object, undefined>): Promise<{
|
|
33
|
+
id: string | number;
|
|
34
|
+
name: string;
|
|
35
|
+
mimeType: string;
|
|
36
|
+
size: number;
|
|
37
|
+
url: string | undefined;
|
|
38
|
+
}>;
|
|
39
|
+
};
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=compress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../../src/actions/compress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,WAAW;;;;;;;;iBAKf,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;wBAMO,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC;;;;;;;CAgBxF,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import Jimp from 'jimp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { imageFile, loadImage, savedImage, saveImage } from '../files.js';
|
|
4
|
+
const inputSchema = z.object({
|
|
5
|
+
image: imageFile.meta({ label: 'Image' }),
|
|
6
|
+
quality: z.union([z.literal(90), z.literal(60)]),
|
|
7
|
+
format: z.enum(['jpg', 'png']),
|
|
8
|
+
resultFileName: z.string().min(1).optional(),
|
|
9
|
+
});
|
|
10
|
+
export const compress = {
|
|
11
|
+
slug: 'compress',
|
|
12
|
+
label: 'Compress image',
|
|
13
|
+
description: 'Compress an image with the selected quality.',
|
|
14
|
+
input: inputSchema,
|
|
15
|
+
output: savedImage,
|
|
16
|
+
async run({ input, req }) {
|
|
17
|
+
const source = await loadImage(req, input.image);
|
|
18
|
+
const image = await Jimp.read(source.data);
|
|
19
|
+
const mimeType = input.format === 'jpg' ? Jimp.MIME_JPEG : Jimp.MIME_PNG;
|
|
20
|
+
image.quality(input.quality);
|
|
21
|
+
const data = await image.getBufferAsync(mimeType);
|
|
22
|
+
return saveImage({
|
|
23
|
+
req,
|
|
24
|
+
data,
|
|
25
|
+
name: `${input.resultFileName ?? 'image'}.${input.format}`,
|
|
26
|
+
mimeType,
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=compress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress.js","sourceRoot":"","sources":["../../src/actions/compress.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1E,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9B,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,gBAAgB;IACvB,WAAW,EAAE,8CAA8C;IAC3D,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,UAAU;IAClB,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAiE;QACrF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;QAEzE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE7B,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAElD,OAAO,SAAS,CAAC;YACf,GAAG;YACH,IAAI;YACJ,IAAI,EAAE,GAAG,KAAK,CAAC,cAAc,IAAI,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;YAC1D,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type PieceRunArgs } from 'frogbot/pieces';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
declare const inputSchema: z.ZodObject<{
|
|
4
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
5
|
+
outputFormat: z.ZodEnum<{
|
|
6
|
+
JPEG: "JPEG";
|
|
7
|
+
PNG: "PNG";
|
|
8
|
+
TIFF: "TIFF";
|
|
9
|
+
BMP: "BMP";
|
|
10
|
+
AVIF: "AVIF";
|
|
11
|
+
}>;
|
|
12
|
+
resultFileName: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export declare const convertFormat: {
|
|
15
|
+
slug: string;
|
|
16
|
+
label: string;
|
|
17
|
+
description: string;
|
|
18
|
+
input: z.ZodObject<{
|
|
19
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
20
|
+
outputFormat: z.ZodEnum<{
|
|
21
|
+
JPEG: "JPEG";
|
|
22
|
+
PNG: "PNG";
|
|
23
|
+
TIFF: "TIFF";
|
|
24
|
+
BMP: "BMP";
|
|
25
|
+
AVIF: "AVIF";
|
|
26
|
+
}>;
|
|
27
|
+
resultFileName: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
output: z.ZodObject<{
|
|
30
|
+
file: z.ZodObject<{
|
|
31
|
+
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
32
|
+
name: z.ZodString;
|
|
33
|
+
mimeType: z.ZodString;
|
|
34
|
+
size: z.ZodNumber;
|
|
35
|
+
url: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
sourceMimeType: z.ZodString;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
run({ input, req }: PieceRunArgs<z.output<typeof inputSchema>, object, undefined>): Promise<{
|
|
40
|
+
file: {
|
|
41
|
+
id: string | number;
|
|
42
|
+
name: string;
|
|
43
|
+
mimeType: string;
|
|
44
|
+
size: number;
|
|
45
|
+
url: string | undefined;
|
|
46
|
+
};
|
|
47
|
+
sourceMimeType: string;
|
|
48
|
+
}>;
|
|
49
|
+
};
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=convertFormat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convertFormat.d.ts","sourceRoot":"","sources":["../../src/actions/convertFormat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAInD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,WAAW;;;;;;;;;;iBAIf,CAAC;AAgBH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;wBAME,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC;;;;;;;;;;CAgCxF,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import convertHeic from 'heic-convert';
|
|
2
|
+
import Jimp from 'jimp';
|
|
3
|
+
import sharp from 'sharp';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { imageFile, loadImage, savedImage, saveImage } from '../files.js';
|
|
6
|
+
const inputSchema = z.object({
|
|
7
|
+
image: imageFile.meta({ label: 'Image' }),
|
|
8
|
+
outputFormat: z.enum(['JPEG', 'PNG', 'TIFF', 'BMP', 'AVIF']),
|
|
9
|
+
resultFileName: z.string().min(1).optional(),
|
|
10
|
+
});
|
|
11
|
+
const output = z.object({
|
|
12
|
+
file: savedImage,
|
|
13
|
+
sourceMimeType: z.string().min(1),
|
|
14
|
+
});
|
|
15
|
+
const formats = {
|
|
16
|
+
JPEG: { extension: 'jpg', mimeType: Jimp.MIME_JPEG },
|
|
17
|
+
PNG: { extension: 'png', mimeType: Jimp.MIME_PNG },
|
|
18
|
+
TIFF: { extension: 'tiff', mimeType: Jimp.MIME_TIFF },
|
|
19
|
+
BMP: { extension: 'bmp', mimeType: Jimp.MIME_BMP },
|
|
20
|
+
};
|
|
21
|
+
export const convertFormat = {
|
|
22
|
+
slug: 'convertFormat',
|
|
23
|
+
label: 'Convert image format',
|
|
24
|
+
description: 'Convert an image to JPEG, PNG, TIFF, BMP, or AVIF.',
|
|
25
|
+
input: inputSchema,
|
|
26
|
+
output,
|
|
27
|
+
async run({ input, req }) {
|
|
28
|
+
const source = await loadImage(req, input.image);
|
|
29
|
+
const sourceData = ['image/heic', 'image/heif'].includes(source.mimeType)
|
|
30
|
+
? Buffer.from(await convertHeic({ buffer: source.data, format: 'PNG' }))
|
|
31
|
+
: source.data;
|
|
32
|
+
let data;
|
|
33
|
+
let extension;
|
|
34
|
+
let mimeType;
|
|
35
|
+
if (input.outputFormat === 'AVIF') {
|
|
36
|
+
data = await sharp(sourceData).avif().toBuffer();
|
|
37
|
+
extension = 'avif';
|
|
38
|
+
mimeType = 'image/avif';
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const format = formats[input.outputFormat];
|
|
42
|
+
const image = await Jimp.read(sourceData);
|
|
43
|
+
data = await image.getBufferAsync(format.mimeType);
|
|
44
|
+
extension = format.extension;
|
|
45
|
+
mimeType = format.mimeType;
|
|
46
|
+
}
|
|
47
|
+
const file = await saveImage({
|
|
48
|
+
req,
|
|
49
|
+
data,
|
|
50
|
+
name: `${input.resultFileName ?? 'image'}.${extension}`,
|
|
51
|
+
mimeType,
|
|
52
|
+
});
|
|
53
|
+
return { file, sourceMimeType: source.mimeType };
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=convertFormat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convertFormat.js","sourceRoot":"","sources":["../../src/actions/convertFormat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type PieceRunArgs } from 'frogbot/pieces';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
declare const inputSchema: z.ZodObject<{
|
|
4
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
5
|
+
left: z.ZodNumber;
|
|
6
|
+
top: z.ZodNumber;
|
|
7
|
+
width: z.ZodNumber;
|
|
8
|
+
height: z.ZodNumber;
|
|
9
|
+
resultFileName: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export declare const crop: {
|
|
12
|
+
slug: string;
|
|
13
|
+
label: string;
|
|
14
|
+
description: string;
|
|
15
|
+
input: z.ZodObject<{
|
|
16
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
17
|
+
left: z.ZodNumber;
|
|
18
|
+
top: z.ZodNumber;
|
|
19
|
+
width: z.ZodNumber;
|
|
20
|
+
height: z.ZodNumber;
|
|
21
|
+
resultFileName: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
output: z.ZodObject<{
|
|
24
|
+
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
25
|
+
name: z.ZodString;
|
|
26
|
+
mimeType: z.ZodString;
|
|
27
|
+
size: z.ZodNumber;
|
|
28
|
+
url: z.ZodOptional<z.ZodString>;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
run({ input, req }: PieceRunArgs<z.output<typeof inputSchema>, object, undefined>): Promise<{
|
|
31
|
+
id: string | number;
|
|
32
|
+
name: string;
|
|
33
|
+
mimeType: string;
|
|
34
|
+
size: number;
|
|
35
|
+
url: string | undefined;
|
|
36
|
+
}>;
|
|
37
|
+
};
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=crop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crop.d.ts","sourceRoot":"","sources":["../../src/actions/crop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,WAAW;;;;;;;iBAOf,CAAC;AAEH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;wBAMW,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC;;;;;;;CAexF,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import Jimp from 'jimp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { imageFile, loadImage, savedImage, saveImage } from '../files.js';
|
|
4
|
+
const inputSchema = z.object({
|
|
5
|
+
image: imageFile.meta({ label: 'Image' }),
|
|
6
|
+
left: z.number().int().nonnegative(),
|
|
7
|
+
top: z.number().int().nonnegative(),
|
|
8
|
+
width: z.number().int().positive(),
|
|
9
|
+
height: z.number().int().positive(),
|
|
10
|
+
resultFileName: z.string().min(1).optional(),
|
|
11
|
+
});
|
|
12
|
+
export const crop = {
|
|
13
|
+
slug: 'crop',
|
|
14
|
+
label: 'Crop image',
|
|
15
|
+
description: 'Crop a rectangular region from an image.',
|
|
16
|
+
input: inputSchema,
|
|
17
|
+
output: savedImage,
|
|
18
|
+
async run({ input, req }) {
|
|
19
|
+
const source = await loadImage(req, input.image);
|
|
20
|
+
const image = await Jimp.read(source.data);
|
|
21
|
+
image.crop(input.left, input.top, input.width, input.height);
|
|
22
|
+
const data = await image.getBufferAsync(image.getMIME());
|
|
23
|
+
return saveImage({
|
|
24
|
+
req,
|
|
25
|
+
data,
|
|
26
|
+
name: `${input.resultFileName ?? 'image'}.${image.getExtension()}`,
|
|
27
|
+
mimeType: image.getMIME(),
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=crop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crop.js","sourceRoot":"","sources":["../../src/actions/crop.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1E,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACpC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAClC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACnC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,YAAY;IACnB,WAAW,EAAE,0CAA0C;IACvD,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,UAAU;IAClB,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAiE;QACrF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE3C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAE7D,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAEzD,OAAO,SAAS,CAAC;YACf,GAAG;YACH,IAAI;YACJ,IAAI,EAAE,GAAG,KAAK,CAAC,cAAc,IAAI,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE;YAClE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE;SAC1B,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import ExifReader from 'exifreader';
|
|
2
|
+
import { type PieceRunArgs } from 'frogbot/pieces';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
declare const inputSchema: z.ZodObject<{
|
|
5
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
export declare const getMetadata: {
|
|
8
|
+
slug: string;
|
|
9
|
+
label: string;
|
|
10
|
+
description: string;
|
|
11
|
+
input: z.ZodObject<{
|
|
12
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
output: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
15
|
+
value: z.ZodUnknown;
|
|
16
|
+
description: z.ZodOptional<z.ZodString>;
|
|
17
|
+
}, z.core.$strip>>;
|
|
18
|
+
run({ input, req }: PieceRunArgs<z.output<typeof inputSchema>, object, undefined>): Promise<ExifReader.Tags>;
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=getMetadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getMetadata.d.ts","sourceRoot":"","sources":["../../src/actions/getMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,WAAW;;iBAA0D,CAAC;AAE5E,eAAO,MAAM,WAAW;;;;;;;;;;;wBAYI,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC;CAKxF,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import ExifReader from 'exifreader';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { imageFile, loadImage } from '../files.js';
|
|
4
|
+
const inputSchema = z.object({ image: imageFile.meta({ label: 'Image' }) });
|
|
5
|
+
export const getMetadata = {
|
|
6
|
+
slug: 'getMetadata',
|
|
7
|
+
label: 'Get image metadata',
|
|
8
|
+
description: 'Read metadata embedded in an image.',
|
|
9
|
+
input: inputSchema,
|
|
10
|
+
output: z.record(z.string(), z.object({
|
|
11
|
+
value: z.unknown(),
|
|
12
|
+
description: z.string().optional(),
|
|
13
|
+
})),
|
|
14
|
+
async run({ input, req }) {
|
|
15
|
+
const image = await loadImage(req, input.image);
|
|
16
|
+
return ExifReader.load(image.data);
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=getMetadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getMetadata.js","sourceRoot":"","sources":["../../src/actions/getMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAE5E,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,oBAAoB;IAC3B,WAAW,EAAE,qCAAqC;IAClD,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,CAAC,CAAC,MAAM,CACd,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,MAAM,CAAC;QACP,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE;QAClB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KACnC,CAAC,CACH;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAiE;QACrF,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAEhD,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type PieceRunArgs } from 'frogbot/pieces';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
declare const inputSchema: z.ZodObject<{
|
|
4
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
5
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
export declare const imageToBase64: {
|
|
8
|
+
slug: string;
|
|
9
|
+
label: string;
|
|
10
|
+
description: string;
|
|
11
|
+
input: z.ZodObject<{
|
|
12
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
13
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
output: z.ZodString;
|
|
16
|
+
run({ input, req }: PieceRunArgs<z.output<typeof inputSchema>, object, undefined>): Promise<string>;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=imageToBase64.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imageToBase64.d.ts","sourceRoot":"","sources":["../../src/actions/imageToBase64.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,WAAW;;;iBAGf,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;;;;wBAME,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC;CAKxF,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { imageFile, loadImage } from '../files.js';
|
|
3
|
+
const inputSchema = z.object({
|
|
4
|
+
image: imageFile.meta({ label: 'Image' }),
|
|
5
|
+
mimeType: z.string().min(1).optional().meta({ label: 'Override MIME type' }),
|
|
6
|
+
});
|
|
7
|
+
export const imageToBase64 = {
|
|
8
|
+
slug: 'imageToBase64',
|
|
9
|
+
label: 'Convert image to Base64',
|
|
10
|
+
description: 'Convert an image to a Base64 data URL.',
|
|
11
|
+
input: inputSchema,
|
|
12
|
+
output: z.string().regex(/^data:[^;,]+;base64,[A-Za-z0-9+/]*={0,2}$/),
|
|
13
|
+
async run({ input, req }) {
|
|
14
|
+
const image = await loadImage(req, input.image);
|
|
15
|
+
return `data:${input.mimeType ?? image.mimeType};base64,${image.data.toString('base64')}`;
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=imageToBase64.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imageToBase64.js","sourceRoot":"","sources":["../../src/actions/imageToBase64.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;CAC7E,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,yBAAyB;IAChC,WAAW,EAAE,wCAAwC;IACrD,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,2CAA2C,CAAC;IACrE,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAiE;QACrF,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAEhD,OAAO,QAAQ,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,WAAW,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC5F,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type PieceRunArgs } from 'frogbot/pieces';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
declare const inputSchema: z.ZodObject<{
|
|
4
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
5
|
+
width: z.ZodNumber;
|
|
6
|
+
height: z.ZodNumber;
|
|
7
|
+
maintainAspectRatio: z.ZodDefault<z.ZodBoolean>;
|
|
8
|
+
resultFileName: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
export declare const resize: {
|
|
11
|
+
slug: string;
|
|
12
|
+
label: string;
|
|
13
|
+
description: string;
|
|
14
|
+
input: z.ZodObject<{
|
|
15
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
16
|
+
width: z.ZodNumber;
|
|
17
|
+
height: z.ZodNumber;
|
|
18
|
+
maintainAspectRatio: z.ZodDefault<z.ZodBoolean>;
|
|
19
|
+
resultFileName: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
output: z.ZodObject<{
|
|
22
|
+
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
23
|
+
name: z.ZodString;
|
|
24
|
+
mimeType: z.ZodString;
|
|
25
|
+
size: z.ZodNumber;
|
|
26
|
+
url: z.ZodOptional<z.ZodString>;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
run({ input, req }: PieceRunArgs<z.output<typeof inputSchema>, object, undefined>): Promise<{
|
|
29
|
+
id: string | number;
|
|
30
|
+
name: string;
|
|
31
|
+
mimeType: string;
|
|
32
|
+
size: number;
|
|
33
|
+
url: string | undefined;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=resize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize.d.ts","sourceRoot":"","sources":["../../src/actions/resize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,WAAW;;;;;;iBAMf,CAAC;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;wBAMS,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC;;;;;;;CAexF,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import Jimp from 'jimp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { imageFile, loadImage, savedImage, saveImage } from '../files.js';
|
|
4
|
+
const inputSchema = z.object({
|
|
5
|
+
image: imageFile.meta({ label: 'Image' }),
|
|
6
|
+
width: z.number().int().positive(),
|
|
7
|
+
height: z.number().int().positive(),
|
|
8
|
+
maintainAspectRatio: z.boolean().default(false),
|
|
9
|
+
resultFileName: z.string().min(1).optional(),
|
|
10
|
+
});
|
|
11
|
+
export const resize = {
|
|
12
|
+
slug: 'resize',
|
|
13
|
+
label: 'Resize image',
|
|
14
|
+
description: 'Resize an image to the requested dimensions.',
|
|
15
|
+
input: inputSchema,
|
|
16
|
+
output: savedImage,
|
|
17
|
+
async run({ input, req }) {
|
|
18
|
+
const source = await loadImage(req, input.image);
|
|
19
|
+
const image = await Jimp.read(source.data);
|
|
20
|
+
image.resize(input.width, input.maintainAspectRatio ? Jimp.AUTO : input.height);
|
|
21
|
+
const data = await image.getBufferAsync(image.getMIME());
|
|
22
|
+
return saveImage({
|
|
23
|
+
req,
|
|
24
|
+
data,
|
|
25
|
+
name: `${input.resultFileName ?? 'image'}.${image.getExtension()}`,
|
|
26
|
+
mimeType: image.getMIME(),
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=resize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize.js","sourceRoot":"","sources":["../../src/actions/resize.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1E,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACzC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAClC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACnC,mBAAmB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC/C,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,cAAc;IACrB,WAAW,EAAE,8CAA8C;IAC3D,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,UAAU;IAClB,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAiE;QACrF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE3C,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEhF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAEzD,OAAO,SAAS,CAAC;YACf,GAAG;YACH,IAAI;YACJ,IAAI,EAAE,GAAG,KAAK,CAAC,cAAc,IAAI,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE;YAClE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE;SAC1B,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type PieceRunArgs } from 'frogbot/pieces';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
declare const inputSchema: z.ZodObject<{
|
|
4
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
5
|
+
degrees: z.ZodUnion<readonly [z.ZodLiteral<90>, z.ZodLiteral<180>, z.ZodLiteral<270>]>;
|
|
6
|
+
resultFileName: z.ZodOptional<z.ZodString>;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
export declare const rotate: {
|
|
9
|
+
slug: string;
|
|
10
|
+
label: string;
|
|
11
|
+
description: string;
|
|
12
|
+
input: z.ZodObject<{
|
|
13
|
+
image: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
14
|
+
degrees: z.ZodUnion<readonly [z.ZodLiteral<90>, z.ZodLiteral<180>, z.ZodLiteral<270>]>;
|
|
15
|
+
resultFileName: z.ZodOptional<z.ZodString>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
output: z.ZodObject<{
|
|
18
|
+
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
19
|
+
name: z.ZodString;
|
|
20
|
+
mimeType: z.ZodString;
|
|
21
|
+
size: z.ZodNumber;
|
|
22
|
+
url: z.ZodOptional<z.ZodString>;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
run({ input, req }: PieceRunArgs<z.output<typeof inputSchema>, object, undefined>): Promise<{
|
|
25
|
+
id: string | number;
|
|
26
|
+
name: string;
|
|
27
|
+
mimeType: string;
|
|
28
|
+
size: number;
|
|
29
|
+
url: string | undefined;
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=rotate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rotate.d.ts","sourceRoot":"","sources":["../../src/actions/rotate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,WAAW;;;;iBAIf,CAAC;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;wBAMS,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC;;;;;;;CAexF,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import Jimp from 'jimp';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { imageFile, loadImage, savedImage, saveImage } from '../files.js';
|
|
4
|
+
const inputSchema = z.object({
|
|
5
|
+
image: imageFile.meta({ label: 'Image' }),
|
|
6
|
+
degrees: z.union([z.literal(90), z.literal(180), z.literal(270)]),
|
|
7
|
+
resultFileName: z.string().min(1).optional(),
|
|
8
|
+
});
|
|
9
|
+
export const rotate = {
|
|
10
|
+
slug: 'rotate',
|
|
11
|
+
label: 'Rotate image',
|
|
12
|
+
description: 'Rotate an image clockwise.',
|
|
13
|
+
input: inputSchema,
|
|
14
|
+
output: savedImage,
|
|
15
|
+
async run({ input, req }) {
|
|
16
|
+
const source = await loadImage(req, input.image);
|
|
17
|
+
const image = await Jimp.read(source.data);
|
|
18
|
+
image.rotate(-input.degrees);
|
|
19
|
+
const data = await image.getBufferAsync(image.getMIME());
|
|
20
|
+
return saveImage({
|
|
21
|
+
req,
|
|
22
|
+
data,
|
|
23
|
+
name: `${input.resultFileName ?? 'image'}.${image.getExtension()}`,
|
|
24
|
+
mimeType: image.getMIME(),
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=rotate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rotate.js","sourceRoot":"","sources":["../../src/actions/rotate.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1E,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,cAAc;IACrB,WAAW,EAAE,4BAA4B;IACzC,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,UAAU;IAClB,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAiE;QACrF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE3C,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE7B,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAEzD,OAAO,SAAS,CAAC;YACf,GAAG;YACH,IAAI;YACJ,IAAI,EAAE,GAAG,KAAK,CAAC,cAAc,IAAI,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE;YAClE,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE;SAC1B,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
package/dist/files.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { FrogbotRequest } from 'frogbot';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare const imageFile: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
4
|
+
export declare const savedImage: z.ZodObject<{
|
|
5
|
+
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
6
|
+
name: z.ZodString;
|
|
7
|
+
mimeType: z.ZodString;
|
|
8
|
+
size: z.ZodNumber;
|
|
9
|
+
url: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type LoadedImage = {
|
|
12
|
+
data: Buffer;
|
|
13
|
+
name: string;
|
|
14
|
+
extension?: string;
|
|
15
|
+
mimeType: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function loadImage(req: FrogbotRequest, id: string | number): Promise<LoadedImage>;
|
|
18
|
+
export declare function saveImage({ req, data, name, mimeType, }: {
|
|
19
|
+
req: FrogbotRequest;
|
|
20
|
+
data: Buffer;
|
|
21
|
+
name: string;
|
|
22
|
+
mimeType: string;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
id: string | number;
|
|
25
|
+
name: string;
|
|
26
|
+
mimeType: string;
|
|
27
|
+
size: number;
|
|
28
|
+
url: string | undefined;
|
|
29
|
+
}>;
|
|
30
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,SAAS,iDAAoC,CAAC;AAE3D,eAAO,MAAM,UAAU;;;;;;iBAMrB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAYF,wBAAsB,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA6D9F;AAED,wBAAsB,SAAS,CAAC,EAC9B,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,GAAG,EAAE,cAAc,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;;;;;;GAkBA"}
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { lookup } from 'mime-types';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export const imageFile = z.union([z.string(), z.number()]);
|
|
4
|
+
export const savedImage = z.object({
|
|
5
|
+
id: z.union([z.string().min(1), z.number()]),
|
|
6
|
+
name: z.string().min(1),
|
|
7
|
+
mimeType: z.string().min(1),
|
|
8
|
+
size: z.number().int().nonnegative(),
|
|
9
|
+
url: z.string().min(1).optional(),
|
|
10
|
+
});
|
|
11
|
+
function filesCollection(req) {
|
|
12
|
+
const collection = req.frogbot.config.files?.slug;
|
|
13
|
+
if (!collection) {
|
|
14
|
+
throw new Error('[frogbot] Image Helper requires the files collection to be configured.');
|
|
15
|
+
}
|
|
16
|
+
return collection;
|
|
17
|
+
}
|
|
18
|
+
export async function loadImage(req, id) {
|
|
19
|
+
req.signal?.throwIfAborted();
|
|
20
|
+
const doc = await req.frogbot.findByID({
|
|
21
|
+
collection: filesCollection(req),
|
|
22
|
+
id,
|
|
23
|
+
depth: 0,
|
|
24
|
+
req,
|
|
25
|
+
overrideAccess: false,
|
|
26
|
+
});
|
|
27
|
+
if (typeof doc.url !== 'string') {
|
|
28
|
+
throw new Error(`[frogbot] Image '${id}' is unavailable.`);
|
|
29
|
+
}
|
|
30
|
+
const config = await req.frogbot.config._internal.payloadConfig;
|
|
31
|
+
const originURL = config.serverURL || req.url;
|
|
32
|
+
if (!originURL)
|
|
33
|
+
throw new Error('[frogbot] Image requests require a server URL.');
|
|
34
|
+
const origin = new URL(originURL);
|
|
35
|
+
const url = new URL(doc.url, origin);
|
|
36
|
+
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password) {
|
|
37
|
+
throw new Error(`[frogbot] Image '${id}' has an invalid URL.`);
|
|
38
|
+
}
|
|
39
|
+
const headers = new Headers();
|
|
40
|
+
if (url.origin === origin.origin) {
|
|
41
|
+
for (const name of ['authorization', 'cookie']) {
|
|
42
|
+
const value = req.headers.get(name);
|
|
43
|
+
if (value)
|
|
44
|
+
headers.set(name, value);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const timeout = AbortSignal.timeout(30_000);
|
|
48
|
+
const response = await fetch(url, {
|
|
49
|
+
headers,
|
|
50
|
+
redirect: 'error',
|
|
51
|
+
signal: req.signal ? AbortSignal.any([req.signal, timeout]) : timeout,
|
|
52
|
+
});
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new Error(`[frogbot] Image '${id}' is unavailable (${response.status}).`);
|
|
55
|
+
}
|
|
56
|
+
const name = typeof doc.filename === 'string' ? doc.filename : 'image';
|
|
57
|
+
const extension = name.includes('.') ? name.split('.').pop()?.toLowerCase() : undefined;
|
|
58
|
+
const mimeType = typeof doc.mimeType === 'string'
|
|
59
|
+
? doc.mimeType
|
|
60
|
+
: (extension && lookup(extension)) || 'application/octet-stream';
|
|
61
|
+
return {
|
|
62
|
+
data: Buffer.from(await response.arrayBuffer()),
|
|
63
|
+
name,
|
|
64
|
+
extension,
|
|
65
|
+
mimeType,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export async function saveImage({ req, data, name, mimeType, }) {
|
|
69
|
+
req.signal?.throwIfAborted();
|
|
70
|
+
const doc = await req.frogbot.create({
|
|
71
|
+
collection: filesCollection(req),
|
|
72
|
+
data: {},
|
|
73
|
+
file: { data, name, mimetype: mimeType, size: data.length },
|
|
74
|
+
req,
|
|
75
|
+
overrideAccess: false,
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
id: doc.id,
|
|
79
|
+
name,
|
|
80
|
+
mimeType,
|
|
81
|
+
size: data.length,
|
|
82
|
+
url: typeof doc.url === 'string' ? doc.url : undefined,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,208 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
export declare const createImageHelper: import("frogbot").PieceFactory<{
|
|
2
|
+
readonly slug: "image-helper";
|
|
3
|
+
readonly label: "Image Helper";
|
|
4
|
+
readonly admin: {
|
|
5
|
+
readonly description: "Inspect, transform, and convert images";
|
|
6
|
+
readonly group: "Core";
|
|
7
|
+
};
|
|
8
|
+
readonly actions: readonly [{
|
|
9
|
+
slug: string;
|
|
10
|
+
label: string;
|
|
11
|
+
description: string;
|
|
12
|
+
input: import("zod").ZodObject<{
|
|
13
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
14
|
+
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
15
|
+
}, import("zod/v4/core").$strip>;
|
|
16
|
+
output: import("zod").ZodString;
|
|
17
|
+
run({ input, req }: import("frogbot").PieceRunArgs<import("zod").infer<import("zod").ZodObject<{
|
|
18
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
19
|
+
mimeType: import("zod").ZodOptional<import("zod").ZodString>;
|
|
20
|
+
}, import("zod/v4/core").$strip>>, object, undefined>): Promise<string>;
|
|
21
|
+
}, {
|
|
22
|
+
slug: string;
|
|
23
|
+
label: string;
|
|
24
|
+
description: string;
|
|
25
|
+
input: import("zod").ZodObject<{
|
|
26
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
27
|
+
}, import("zod/v4/core").$strip>;
|
|
28
|
+
output: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodObject<{
|
|
29
|
+
value: import("zod").ZodUnknown;
|
|
30
|
+
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
31
|
+
}, import("zod/v4/core").$strip>>;
|
|
32
|
+
run({ input, req }: import("frogbot").PieceRunArgs<import("zod").infer<import("zod").ZodObject<{
|
|
33
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
34
|
+
}, import("zod/v4/core").$strip>>, object, undefined>): Promise<import("exifreader").Tags>;
|
|
35
|
+
}, {
|
|
36
|
+
slug: string;
|
|
37
|
+
label: string;
|
|
38
|
+
description: string;
|
|
39
|
+
input: import("zod").ZodObject<{
|
|
40
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
41
|
+
left: import("zod").ZodNumber;
|
|
42
|
+
top: import("zod").ZodNumber;
|
|
43
|
+
width: import("zod").ZodNumber;
|
|
44
|
+
height: import("zod").ZodNumber;
|
|
45
|
+
resultFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
46
|
+
}, import("zod/v4/core").$strip>;
|
|
47
|
+
output: import("zod").ZodObject<{
|
|
48
|
+
id: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
49
|
+
name: import("zod").ZodString;
|
|
50
|
+
mimeType: import("zod").ZodString;
|
|
51
|
+
size: import("zod").ZodNumber;
|
|
52
|
+
url: import("zod").ZodOptional<import("zod").ZodString>;
|
|
53
|
+
}, import("zod/v4/core").$strip>;
|
|
54
|
+
run({ input, req }: import("frogbot").PieceRunArgs<import("zod").infer<import("zod").ZodObject<{
|
|
55
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
56
|
+
left: import("zod").ZodNumber;
|
|
57
|
+
top: import("zod").ZodNumber;
|
|
58
|
+
width: import("zod").ZodNumber;
|
|
59
|
+
height: import("zod").ZodNumber;
|
|
60
|
+
resultFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
61
|
+
}, import("zod/v4/core").$strip>>, object, undefined>): Promise<{
|
|
62
|
+
id: string | number;
|
|
63
|
+
name: string;
|
|
64
|
+
mimeType: string;
|
|
65
|
+
size: number;
|
|
66
|
+
url: string | undefined;
|
|
67
|
+
}>;
|
|
68
|
+
}, {
|
|
69
|
+
slug: string;
|
|
70
|
+
label: string;
|
|
71
|
+
description: string;
|
|
72
|
+
input: import("zod").ZodObject<{
|
|
73
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
74
|
+
degrees: import("zod").ZodUnion<readonly [import("zod").ZodLiteral<90>, import("zod").ZodLiteral<180>, import("zod").ZodLiteral<270>]>;
|
|
75
|
+
resultFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
76
|
+
}, import("zod/v4/core").$strip>;
|
|
77
|
+
output: import("zod").ZodObject<{
|
|
78
|
+
id: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
79
|
+
name: import("zod").ZodString;
|
|
80
|
+
mimeType: import("zod").ZodString;
|
|
81
|
+
size: import("zod").ZodNumber;
|
|
82
|
+
url: import("zod").ZodOptional<import("zod").ZodString>;
|
|
83
|
+
}, import("zod/v4/core").$strip>;
|
|
84
|
+
run({ input, req }: import("frogbot").PieceRunArgs<import("zod").infer<import("zod").ZodObject<{
|
|
85
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
86
|
+
degrees: import("zod").ZodUnion<readonly [import("zod").ZodLiteral<90>, import("zod").ZodLiteral<180>, import("zod").ZodLiteral<270>]>;
|
|
87
|
+
resultFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
88
|
+
}, import("zod/v4/core").$strip>>, object, undefined>): Promise<{
|
|
89
|
+
id: string | number;
|
|
90
|
+
name: string;
|
|
91
|
+
mimeType: string;
|
|
92
|
+
size: number;
|
|
93
|
+
url: string | undefined;
|
|
94
|
+
}>;
|
|
95
|
+
}, {
|
|
96
|
+
slug: string;
|
|
97
|
+
label: string;
|
|
98
|
+
description: string;
|
|
99
|
+
input: import("zod").ZodObject<{
|
|
100
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
101
|
+
width: import("zod").ZodNumber;
|
|
102
|
+
height: import("zod").ZodNumber;
|
|
103
|
+
maintainAspectRatio: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
104
|
+
resultFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
105
|
+
}, import("zod/v4/core").$strip>;
|
|
106
|
+
output: import("zod").ZodObject<{
|
|
107
|
+
id: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
108
|
+
name: import("zod").ZodString;
|
|
109
|
+
mimeType: import("zod").ZodString;
|
|
110
|
+
size: import("zod").ZodNumber;
|
|
111
|
+
url: import("zod").ZodOptional<import("zod").ZodString>;
|
|
112
|
+
}, import("zod/v4/core").$strip>;
|
|
113
|
+
run({ input, req }: import("frogbot").PieceRunArgs<import("zod").infer<import("zod").ZodObject<{
|
|
114
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
115
|
+
width: import("zod").ZodNumber;
|
|
116
|
+
height: import("zod").ZodNumber;
|
|
117
|
+
maintainAspectRatio: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
118
|
+
resultFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
119
|
+
}, import("zod/v4/core").$strip>>, object, undefined>): Promise<{
|
|
120
|
+
id: string | number;
|
|
121
|
+
name: string;
|
|
122
|
+
mimeType: string;
|
|
123
|
+
size: number;
|
|
124
|
+
url: string | undefined;
|
|
125
|
+
}>;
|
|
126
|
+
}, {
|
|
127
|
+
slug: string;
|
|
128
|
+
label: string;
|
|
129
|
+
description: string;
|
|
130
|
+
input: import("zod").ZodObject<{
|
|
131
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
132
|
+
quality: import("zod").ZodUnion<readonly [import("zod").ZodLiteral<90>, import("zod").ZodLiteral<60>]>;
|
|
133
|
+
format: import("zod").ZodEnum<{
|
|
134
|
+
jpg: "jpg";
|
|
135
|
+
png: "png";
|
|
136
|
+
}>;
|
|
137
|
+
resultFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
138
|
+
}, import("zod/v4/core").$strip>;
|
|
139
|
+
output: import("zod").ZodObject<{
|
|
140
|
+
id: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
141
|
+
name: import("zod").ZodString;
|
|
142
|
+
mimeType: import("zod").ZodString;
|
|
143
|
+
size: import("zod").ZodNumber;
|
|
144
|
+
url: import("zod").ZodOptional<import("zod").ZodString>;
|
|
145
|
+
}, import("zod/v4/core").$strip>;
|
|
146
|
+
run({ input, req }: import("frogbot").PieceRunArgs<import("zod").infer<import("zod").ZodObject<{
|
|
147
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
148
|
+
quality: import("zod").ZodUnion<readonly [import("zod").ZodLiteral<90>, import("zod").ZodLiteral<60>]>;
|
|
149
|
+
format: import("zod").ZodEnum<{
|
|
150
|
+
jpg: "jpg";
|
|
151
|
+
png: "png";
|
|
152
|
+
}>;
|
|
153
|
+
resultFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
154
|
+
}, import("zod/v4/core").$strip>>, object, undefined>): Promise<{
|
|
155
|
+
id: string | number;
|
|
156
|
+
name: string;
|
|
157
|
+
mimeType: string;
|
|
158
|
+
size: number;
|
|
159
|
+
url: string | undefined;
|
|
160
|
+
}>;
|
|
161
|
+
}, {
|
|
162
|
+
slug: string;
|
|
163
|
+
label: string;
|
|
164
|
+
description: string;
|
|
165
|
+
input: import("zod").ZodObject<{
|
|
166
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
167
|
+
outputFormat: import("zod").ZodEnum<{
|
|
168
|
+
JPEG: "JPEG";
|
|
169
|
+
PNG: "PNG";
|
|
170
|
+
TIFF: "TIFF";
|
|
171
|
+
BMP: "BMP";
|
|
172
|
+
AVIF: "AVIF";
|
|
173
|
+
}>;
|
|
174
|
+
resultFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
175
|
+
}, import("zod/v4/core").$strip>;
|
|
176
|
+
output: import("zod").ZodObject<{
|
|
177
|
+
file: import("zod").ZodObject<{
|
|
178
|
+
id: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
179
|
+
name: import("zod").ZodString;
|
|
180
|
+
mimeType: import("zod").ZodString;
|
|
181
|
+
size: import("zod").ZodNumber;
|
|
182
|
+
url: import("zod").ZodOptional<import("zod").ZodString>;
|
|
183
|
+
}, import("zod/v4/core").$strip>;
|
|
184
|
+
sourceMimeType: import("zod").ZodString;
|
|
185
|
+
}, import("zod/v4/core").$strip>;
|
|
186
|
+
run({ input, req }: import("frogbot").PieceRunArgs<import("zod").infer<import("zod").ZodObject<{
|
|
187
|
+
image: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
|
|
188
|
+
outputFormat: import("zod").ZodEnum<{
|
|
189
|
+
JPEG: "JPEG";
|
|
190
|
+
PNG: "PNG";
|
|
191
|
+
TIFF: "TIFF";
|
|
192
|
+
BMP: "BMP";
|
|
193
|
+
AVIF: "AVIF";
|
|
194
|
+
}>;
|
|
195
|
+
resultFileName: import("zod").ZodOptional<import("zod").ZodString>;
|
|
196
|
+
}, import("zod/v4/core").$strip>>, object, undefined>): Promise<{
|
|
197
|
+
file: {
|
|
198
|
+
id: string | number;
|
|
199
|
+
name: string;
|
|
200
|
+
mimeType: string;
|
|
201
|
+
size: number;
|
|
202
|
+
url: string | undefined;
|
|
203
|
+
};
|
|
204
|
+
sourceMimeType: string;
|
|
205
|
+
}>;
|
|
206
|
+
}];
|
|
207
|
+
}>;
|
|
20
208
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK5B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,38 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
service: 'image_helper',
|
|
16
|
-
credentialType: 'none',
|
|
17
|
-
defaultActions: imageHelperActions,
|
|
18
|
-
scopes: imageHelperScopes,
|
|
19
|
-
config,
|
|
20
|
-
});
|
|
21
|
-
return Object.assign(piece, {
|
|
22
|
-
/** Image to Base64: Converts an image to an url-like Base64 string */
|
|
23
|
-
imageToBase64: piece.tool('image_to_base64'),
|
|
24
|
-
/** Get image metadata: Gets metadata from an image */
|
|
25
|
-
getMetaData: piece.tool('get_meta_data'),
|
|
26
|
-
/** Crop an image: Crops an image */
|
|
27
|
-
cropImage: piece.tool('crop_image'),
|
|
28
|
-
/** Rotate an image: Rotates an image */
|
|
29
|
-
rotateImage: piece.tool('rotate_image'),
|
|
30
|
-
/** Resize an image: Resizes an image */
|
|
31
|
-
resizeImage: piece.tool('resize_image'),
|
|
32
|
-
/** Compresses an image: Compresses an image */
|
|
33
|
-
compressImage: piece.tool('compress_image'),
|
|
34
|
-
/** Image Conversion Helper: Converts a image to supported formats */
|
|
35
|
-
convertImageFormat: piece.tool('convert_image_format'),
|
|
36
|
-
});
|
|
37
|
-
}
|
|
1
|
+
import { definePiece } from 'frogbot/pieces';
|
|
2
|
+
import { compress } from './actions/compress.js';
|
|
3
|
+
import { convertFormat } from './actions/convertFormat.js';
|
|
4
|
+
import { crop } from './actions/crop.js';
|
|
5
|
+
import { getMetadata } from './actions/getMetadata.js';
|
|
6
|
+
import { imageToBase64 } from './actions/imageToBase64.js';
|
|
7
|
+
import { resize } from './actions/resize.js';
|
|
8
|
+
import { rotate } from './actions/rotate.js';
|
|
9
|
+
export const createImageHelper = definePiece({
|
|
10
|
+
slug: 'image-helper',
|
|
11
|
+
label: 'Image Helper',
|
|
12
|
+
admin: { description: 'Inspect, transform, and convert images', group: 'Core' },
|
|
13
|
+
actions: [imageToBase64, getMetadata, crop, rotate, resize, compress, convertFormat],
|
|
14
|
+
});
|
|
38
15
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAC;IAC3C,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,cAAc;IACrB,KAAK,EAAE,EAAE,WAAW,EAAE,wCAAwC,EAAE,KAAK,EAAE,MAAM,EAAE;IAC/E,OAAO,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC;CACrF,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frogbotai/piece-image-helper",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.24.0",
|
|
4
|
+
"description": "image-helper tools for FrogBot.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Colby Gilbert",
|
|
7
7
|
"type": "module",
|
|
@@ -19,14 +19,21 @@
|
|
|
19
19
|
],
|
|
20
20
|
"sideEffects": false,
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"
|
|
22
|
+
"exifreader": "4.39.0",
|
|
23
|
+
"heic-convert": "2.1.0",
|
|
24
|
+
"jimp": "0.22.12",
|
|
25
|
+
"mime-types": "2.1.35",
|
|
26
|
+
"sharp": "0.35.2",
|
|
27
|
+
"zod": "^4.3.6"
|
|
23
28
|
},
|
|
24
29
|
"peerDependencies": {
|
|
25
|
-
"frogbot": "0.
|
|
30
|
+
"frogbot": "0.24.0"
|
|
26
31
|
},
|
|
27
32
|
"devDependencies": {
|
|
33
|
+
"@types/heic-convert": "2.1.1",
|
|
34
|
+
"@types/mime-types": "2.1.1",
|
|
28
35
|
"typescript": "5.6.2",
|
|
29
|
-
"frogbot": "0.
|
|
36
|
+
"frogbot": "0.24.0"
|
|
30
37
|
},
|
|
31
38
|
"publishConfig": {
|
|
32
39
|
"access": "public"
|