@sealpixel/plugin-resize 1.0.0-rc.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 ADDED
@@ -0,0 +1,3 @@
1
+ # @sealpixel/plugin-resize
2
+
3
+ Resize to a target size with contain, cover and fill modes. Part of the Sealpixel image editor.
@@ -0,0 +1,76 @@
1
+ import type { OperationBase } from '@sealpixel/core';
2
+ import { z } from 'zod';
3
+ export type Fit = 'contain' | 'cover' | 'fill';
4
+ export interface ResizeTarget {
5
+ width: number | null;
6
+ height: number | null;
7
+ fit: Fit;
8
+ upscale: boolean;
9
+ }
10
+ export interface ResizeDoc {
11
+ target: ResizeTarget | null;
12
+ }
13
+ export interface ResizeSetOp extends OperationBase<'resize.set'> {
14
+ width?: number | null | undefined;
15
+ height?: number | null | undefined;
16
+ fit?: Fit | undefined;
17
+ upscale?: boolean | undefined;
18
+ }
19
+ export type ResizeClearOp = OperationBase<'resize.clear'>;
20
+ declare module '@sealpixel/core' {
21
+ interface OperationRegistry {
22
+ 'resize.set': ResizeSetOp;
23
+ 'resize.clear': ResizeClearOp;
24
+ }
25
+ interface DocumentRegistry {
26
+ resize: ResizeDoc;
27
+ }
28
+ }
29
+ export declare const resizeSet: import("@sealpixel/core").OperationDef<ResizeDoc, ResizeSetOp>;
30
+ export declare const resizeClear: import("@sealpixel/core").OperationDef<ResizeDoc, ResizeClearOp>;
31
+ export declare const ResizeOptionsSchema: z.ZodObject<{
32
+ presets: z.ZodArray<z.ZodObject<{
33
+ label: z.ZodString;
34
+ width: z.ZodOptional<z.ZodNumber>;
35
+ height: z.ZodOptional<z.ZodNumber>;
36
+ }, z.core.$strict>>;
37
+ max: z.ZodNullable<z.ZodObject<{
38
+ width: z.ZodNumber;
39
+ height: z.ZodNumber;
40
+ }, z.core.$strict>>;
41
+ upscale: z.ZodBoolean;
42
+ fits: z.ZodArray<z.ZodEnum<{
43
+ contain: "contain";
44
+ cover: "cover";
45
+ fill: "fill";
46
+ }>>;
47
+ defaultFit: z.ZodEnum<{
48
+ contain: "contain";
49
+ cover: "cover";
50
+ fill: "fill";
51
+ }>;
52
+ enforce: z.ZodBoolean;
53
+ }, z.core.$strict>;
54
+ /**
55
+ * `presets`: quick picks `{ label, width?, height? }`. `max`: largest output
56
+ * allowed, or null. `upscale`: allow output larger than the source. `fits`:
57
+ * fit modes offered. `defaultFit`: fit a new target starts with.
58
+ */
59
+ export type ResizeOptions = z.infer<typeof ResizeOptionsSchema>;
60
+ export declare const RESIZE_DEFAULT_OPTIONS: ResizeOptions;
61
+ export declare const resizePlugin: import("@sealpixel/plugin-sdk").ConfigurablePlugin<"resize", ResizeDoc, {
62
+ presets: {
63
+ label: string;
64
+ width?: number | undefined;
65
+ height?: number | undefined;
66
+ }[];
67
+ max: {
68
+ width: number;
69
+ height: number;
70
+ } | null;
71
+ upscale: boolean;
72
+ fits: ("contain" | "cover" | "fill")[];
73
+ defaultFit: "contain" | "cover" | "fill";
74
+ enforce: boolean;
75
+ }>;
76
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,GAAG,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,GAAG,EAAE,GAAG,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,WAAY,SAAQ,aAAa,CAAC,YAAY,CAAC;IAC9D,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,GAAG,CAAC,EAAE,GAAG,GAAG,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,MAAM,aAAa,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;AAE1D,OAAO,QAAQ,iBAAiB,CAAC;IAC/B,UAAU,iBAAiB;QACzB,YAAY,EAAE,WAAW,CAAC;QAC1B,cAAc,EAAE,aAAa,CAAC;KAC/B;IACD,UAAU,gBAAgB;QACxB,MAAM,EAAE,SAAS,CAAC;KACnB;CACF;AAKD,eAAO,MAAM,SAAS,gEA2BpB,CAAC;AAEH,eAAO,MAAM,WAAW,kEAItB,CAAC;AAGH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;kBAkBiD,CAAC;AAElF;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,sBAAsB,EAAE,aAOpC,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;EA2CvB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,108 @@
1
+ import { defineOperation, definePlugin } from '@sealpixel/plugin-sdk';
2
+ import { z } from 'zod';
3
+ const px = z.number().int().positive().max(65535);
4
+ const base = { id: z.string().min(1), at: z.number().optional() };
5
+ export const resizeSet = defineOperation({
6
+ type: 'resize.set',
7
+ schema: z
8
+ .object({
9
+ type: z.literal('resize.set'),
10
+ ...base,
11
+ width: px.nullable().optional(),
12
+ height: px.nullable().optional(),
13
+ fit: z.enum(['contain', 'cover', 'fill']).optional(),
14
+ upscale: z.boolean().optional(),
15
+ })
16
+ .strict(),
17
+ reduce: (slice, op) => {
18
+ const prev = slice.target ?? {
19
+ width: null,
20
+ height: null,
21
+ fit: 'contain',
22
+ upscale: false,
23
+ };
24
+ const target = {
25
+ width: op.width === undefined ? prev.width : op.width,
26
+ height: op.height === undefined ? prev.height : op.height,
27
+ fit: op.fit ?? prev.fit,
28
+ upscale: op.upscale ?? prev.upscale,
29
+ };
30
+ return { target: target.width === null && target.height === null ? null : target };
31
+ },
32
+ });
33
+ export const resizeClear = defineOperation({
34
+ type: 'resize.clear',
35
+ schema: z.object({ type: z.literal('resize.clear'), ...base }).strict(),
36
+ reduce: () => ({ target: null }),
37
+ });
38
+ const FitSchema = z.enum(['contain', 'cover', 'fill']);
39
+ export const ResizeOptionsSchema = z
40
+ .object({
41
+ presets: z.array(z
42
+ .object({ label: z.string().min(1), width: px.optional(), height: px.optional() })
43
+ .strict()
44
+ .refine((p) => p.width !== undefined || p.height !== undefined, 'a preset needs width or height')),
45
+ max: z.object({ width: px, height: px }).strict().nullable(),
46
+ upscale: z.boolean(),
47
+ fits: z.array(FitSchema).min(1),
48
+ defaultFit: FitSchema,
49
+ enforce: z.boolean(),
50
+ })
51
+ .strict()
52
+ .refine((o) => o.fits.includes(o.defaultFit), 'defaultFit must be one of fits');
53
+ export const RESIZE_DEFAULT_OPTIONS = {
54
+ presets: [],
55
+ max: null,
56
+ upscale: true,
57
+ fits: ['contain', 'cover', 'fill'],
58
+ defaultFit: 'contain',
59
+ enforce: false,
60
+ };
61
+ export const resizePlugin = definePlugin({
62
+ id: 'resize',
63
+ version: 1,
64
+ operations: [resizeSet, resizeClear],
65
+ initialDocument: { target: null },
66
+ stage: { name: 'resize', order: 800 },
67
+ toPlan: (doc) => {
68
+ const t = doc.target;
69
+ if (t === null)
70
+ return null;
71
+ return {
72
+ ...(t.width === null ? {} : { width: t.width }),
73
+ ...(t.height === null ? {} : { height: t.height }),
74
+ fit: t.fit,
75
+ upscale: t.upscale,
76
+ };
77
+ },
78
+ kernel: { kind: 'core' },
79
+ options: {
80
+ schema: ResizeOptionsSchema,
81
+ defaults: RESIZE_DEFAULT_OPTIONS,
82
+ describe: {
83
+ presets: 'Quick picks: { label, width?, height? }.',
84
+ max: 'Largest output allowed, or null.',
85
+ upscale: 'Allow output larger than the source.',
86
+ fits: 'Fit modes offered.',
87
+ defaultFit: 'Fit a new target starts with.',
88
+ enforce: 'Reject targets above max, disallowed fits or upscaling.',
89
+ },
90
+ },
91
+ validate: (op, { options }) => {
92
+ if (op.type !== 'resize.set' || !options.enforce)
93
+ return null;
94
+ const o = op;
95
+ if (o.fit !== undefined && !options.fits.includes(o.fit))
96
+ return `fit "${o.fit}" is not offered`;
97
+ if (!options.upscale && o.upscale === true)
98
+ return 'upscaling is disabled';
99
+ if (options.max) {
100
+ if (o.width != null && o.width > options.max.width)
101
+ return `width exceeds ${options.max.width}`;
102
+ if (o.height != null && o.height > options.max.height)
103
+ return `height exceeds ${options.max.height}`;
104
+ }
105
+ return null;
106
+ },
107
+ });
108
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@sealpixel/plugin-resize",
3
+ "version": "1.0.0-rc.0",
4
+ "description": "Resize to a target size with contain, cover and fill modes.",
5
+ "license": "BUSL-1.1",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/9feet/sealpixel.git",
9
+ "directory": "packages/plugins/resize"
10
+ },
11
+ "homepage": "https://docs.sealpixel.dev",
12
+ "bugs": "https://github.com/9feet/sealpixel/issues",
13
+ "type": "module",
14
+ "sideEffects": false,
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "keywords": [
20
+ "sealpixel-plugin"
21
+ ],
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ },
27
+ "./package.json": "./package.json"
28
+ },
29
+ "scripts": {
30
+ "build": "tsc -p tsconfig.build.json",
31
+ "typecheck": "tsc -p tsconfig.json --noEmit",
32
+ "test": "vitest run"
33
+ },
34
+ "dependencies": {
35
+ "@sealpixel/plugin-sdk": "workspace:*"
36
+ },
37
+ "peerDependencies": {
38
+ "@sealpixel/core": "workspace:*",
39
+ "zod": "^4.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "@sealpixel/config": "workspace:*",
43
+ "@sealpixel/core": "workspace:*",
44
+ "@types/node": "^24.0.0",
45
+ "typescript": "^5.9.0",
46
+ "vitest": "^4.0.0",
47
+ "zod": "^4.0.0"
48
+ }
49
+ }