Skip to content

Commit 731d545

Browse files
authored
feat: enumerate plugin props (#224)
# Description Based on a conversation with @colbyfayock, this adds back enumerated props for each plugin. They're collected via two top-level exports, `cloudinaryPluginProps` and `cloudinaryPluginKeys`, so we can expose which props are handled by cloudinary without all the implementation details of each plugin.
1 parent 6f43022 commit 731d545

26 files changed

+150
-3
lines changed

packages/url-loader/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// URL Construction & Plugins
22

33
export {
4+
cloudinaryPluginKeys,
5+
cloudinaryPluginProps,
46
constructCloudinaryUrl,
57
transformationPlugins,
68
type AnalyticsOptions,

packages/url-loader/src/lib/cloudinary.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,25 @@ import type {
3838
import type { ImageOptions } from "../types/image.js";
3939
import type { PluginOptions, PluginResults } from "../types/plugins.js";
4040
import type { VideoOptions } from "../types/video.js";
41-
import type { OptionsFor, TransformationPlugin } from "./plugin.js";
41+
import type {
42+
CloudinaryKey,
43+
OptionsFor,
44+
TransformationPlugin,
45+
} from "./plugin.js";
4246
import { entriesOf, throwError } from "./utils.js";
4347

48+
export const cloudinaryPluginProps = {} as Record<CloudinaryKey, true>;
49+
4450
const validatePlugins = <const plugins extends readonly TransformationPlugin[]>(
4551
...plugins: plugins extends validatePlugins<plugins>
4652
? plugins
4753
: validatePlugins<plugins>
48-
) => plugins;
54+
) => {
55+
plugins.forEach((plugin) => {
56+
Object.assign(cloudinaryPluginProps, plugin.props);
57+
});
58+
return plugins;
59+
};
4960

5061
export const transformationPlugins = validatePlugins(
5162
// Some features *must* be the first transformation applied
@@ -87,6 +98,11 @@ export const transformationPlugins = validatePlugins(
8798
ZoompanPlugin
8899
);
89100

101+
// important this comes after `validatePlugins` is called so we've collected the props
102+
export const cloudinaryPluginKeys: readonly CloudinaryKey[] = Object.keys(
103+
cloudinaryPluginProps
104+
) as never;
105+
90106
export interface AnalyticsOptions extends IAnalyticsOptions {}
91107

92108
export interface ConfigOptions extends CloudinaryAssetConfiguration {}

packages/url-loader/src/lib/plugin.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import type { PluginResults } from "../types/plugins.js";
44
import type { VideoOptions } from "../types/video.js";
55
import type { CldAsset } from "./cloudinary.js";
66

7-
interface AllOptions extends AssetOptions, ImageOptions, VideoOptions {}
7+
export interface AllOptions extends AssetOptions, ImageOptions, VideoOptions {}
8+
9+
export type CloudinaryKey = keyof AllOptions & {};
810

911
export type SupportedAssetType = "image" | "video" | "all";
1012

@@ -24,6 +26,7 @@ export interface PluginDefinition<
2426
supports: assetType;
2527
apply: PluginApplication<assetType, when>;
2628
inferOwnOptions: options;
29+
props: Record<keyof options, true>;
2730
applyWhen?: when | undefined;
2831
strict?: boolean;
2932
}
@@ -38,6 +41,7 @@ export interface TransformationPlugin<
3841
supports: assetType;
3942
apply: PluginApplication<assetType, when>;
4043
inferOwnOptions: options;
44+
props: Record<keyof options, true>;
4145
applyWhen?: when | undefined;
4246
strict?: boolean;
4347
}

packages/url-loader/src/plugins/abr.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export const AbrPlugin = plugin({
1414
name: "Abr",
1515
supports: "video",
1616
inferOwnOptions: {} as AbrPlugin.Options,
17+
props: {
18+
streamingProfile: true,
19+
},
1720
apply: (asset, opts) => {
1821
if (typeof opts.streamingProfile === "string") {
1922
asset.addTransformation(`sp_${opts.streamingProfile}`);

packages/url-loader/src/plugins/cropping.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ export const CroppingPlugin = plugin({
4444
name: "Cropping",
4545
supports: "all",
4646
inferOwnOptions: {} as CroppingPlugin.Options,
47+
props: {
48+
aspectRatio: true,
49+
crop: true,
50+
gravity: true,
51+
zoom: true,
52+
},
4753
// crop is applied even if the crop key is undefined
4854
apply: (asset, opts) => {
4955
let crops: Array<CroppingPlugin.NestedOptions> = [];

packages/url-loader/src/plugins/default-image.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const DefaultImagePlugin = plugin({
1515
name: "DefaultImage",
1616
supports: "image",
1717
inferOwnOptions: {} as DefaultImagePlugin.Options,
18+
props: { defaultImage: true },
1819
apply: (asset, opts) => {
1920
const { defaultImage } = opts;
2021

packages/url-loader/src/plugins/effects.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,61 @@ export const EffectsPlugin = plugin({
2121
name: "Effects",
2222
supports: "all",
2323
inferOwnOptions: {} as EffectsPlugin.Options,
24+
props: {
25+
angle: true,
26+
art: true,
27+
autoBrightness: true,
28+
autoColor: true,
29+
autoContrast: true,
30+
assistColorblind: true,
31+
background: true,
32+
blackwhite: true,
33+
blur: true,
34+
blurFaces: true,
35+
blurRegion: true,
36+
border: true,
37+
brightness: true,
38+
brightnessHSB: true,
39+
cartoonify: true,
40+
color: true,
41+
colorize: true,
42+
contrast: true,
43+
displace: true,
44+
distort: true,
45+
fillLight: true,
46+
gamma: true,
47+
gradientFade: true,
48+
grayscale: true,
49+
hue: true,
50+
improve: true,
51+
loop: true,
52+
multiply: true,
53+
negate: true,
54+
noise: true,
55+
oilPaint: true,
56+
opacity: true,
57+
outline: true,
58+
pixelate: true,
59+
pixelateFaces: true,
60+
pixelateRegion: true,
61+
radius: true,
62+
redeye: true,
63+
replaceColor: true,
64+
saturation: true,
65+
screen: true,
66+
sepia: true,
67+
shadow: true,
68+
sharpen: true,
69+
shear: true,
70+
simulateColorblind: true,
71+
tint: true,
72+
trim: true,
73+
unsharpMask: true,
74+
vectorize: true,
75+
vibrance: true,
76+
vignette: true,
77+
effects: true,
78+
},
2479
apply: (cldAsset, options) => {
2580
// Handle any top-level effect props
2681

packages/url-loader/src/plugins/enhance.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export const EnhancePlugin = plugin({
1414
name: "Enhance",
1515
supports: "image",
1616
inferOwnOptions: {} as EnhancePlugin.Options,
17+
props: {
18+
enhance: true,
19+
},
1720
apply: (cldAsset, options) => {
1821
if (options.enhance) {
1922
cldAsset.addTransformation("e_enhance");

packages/url-loader/src/plugins/extract.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ export const ExtractPlugin = plugin({
2828
supports: "image",
2929
applyWhen: "extract",
3030
inferOwnOptions: {} as ExtractPlugin.Options,
31+
props: {
32+
extract: true,
33+
},
3134
apply: (cldAsset, { extract }) => {
3235
const properties = [];
3336

packages/url-loader/src/plugins/fill-background.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ export const FillBackgroundPlugin = plugin({
2828
name: "FillBackground",
2929
supports: "image",
3030
inferOwnOptions: {} as FillBackgroundPlugin.Options,
31+
props: {
32+
fillBackground: true,
33+
},
3134
apply: (cldAsset, options) => {
3235
const { fillBackground } = options;
3336

0 commit comments

Comments
 (0)