diff --git a/packages/plugin-ai-audio-generation-web/src/elevenlabs/ElevenMultilingualV2.ts b/packages/plugin-ai-audio-generation-web/src/elevenlabs/ElevenMultilingualV2.ts index 8629f312..1723dbe2 100644 --- a/packages/plugin-ai-audio-generation-web/src/elevenlabs/ElevenMultilingualV2.ts +++ b/packages/plugin-ai-audio-generation-web/src/elevenlabs/ElevenMultilingualV2.ts @@ -2,7 +2,8 @@ import { type Provider, type AudioOutput, CommonProviderConfiguration, - getPanelId + getPanelId, + normalizeBaseURL } from '@imgly/plugin-ai-generation-web'; import CreativeEditorSDK from '@cesdk/cesdk-js'; import schema from './ElevenMultilingualV2.json'; @@ -45,9 +46,11 @@ function getProvider( cesdk: CreativeEditorSDK, config: ProviderConfiguration ): Provider<'audio', ElevenlabsInput, AudioOutput> { - const baseURL = + // Normalize baseURL to ensure exactly one trailing slash + const baseURL = normalizeBaseURL( config.baseURL ?? - 'https://cdn.img.ly/assets/plugins/plugin-ai-audio-generation-web/v1/elevenlabs/'; + 'https://cdn.img.ly/assets/plugins/plugin-ai-audio-generation-web/v1/elevenlabs/' + ); const prefix = 'ly.img.ai.audio-generation.speech.elevenlabs'; const voiceSelectionPanelId = `${prefix}.voiceSelection`; diff --git a/packages/plugin-ai-generation-web/src/index.ts b/packages/plugin-ai-generation-web/src/index.ts index 87826f4f..9feb5038 100644 --- a/packages/plugin-ai-generation-web/src/index.ts +++ b/packages/plugin-ai-generation-web/src/index.ts @@ -79,7 +79,8 @@ export { getThumbnailForVideo, getLabelFromId, isAsyncGenerator, - addIconSetOnce + addIconSetOnce, + normalizeBaseURL } from './utils/utils'; export { checkAiPluginVersion } from './utils/checkAiPluginVersion'; diff --git a/packages/plugin-ai-generation-web/src/utils/utils.ts b/packages/plugin-ai-generation-web/src/utils/utils.ts index ff22463f..d6ac4eca 100644 --- a/packages/plugin-ai-generation-web/src/utils/utils.ts +++ b/packages/plugin-ai-generation-web/src/utils/utils.ts @@ -312,3 +312,18 @@ export function addIconSetOnce( cesdk.ui.experimental.setGlobalStateValue(globalStateIconSetAddedId, true); } } + +/** + * Normalizes a base URL to ensure it has exactly one trailing slash. + * + * @param url - The base URL to normalize + * @returns The normalized URL with exactly one trailing slash + * + * @example + * normalizeBaseURL('https://example.com') // 'https://example.com/' + * normalizeBaseURL('https://example.com/') // 'https://example.com/' + * normalizeBaseURL('https://example.com//') // 'https://example.com/' + */ +export function normalizeBaseURL(url: string): string { + return `${url.replace(/\/+$/, '')}/`; +} diff --git a/packages/plugin-ai-image-generation-web/src/fal-ai/Recraft20b.constants.ts b/packages/plugin-ai-image-generation-web/src/fal-ai/Recraft20b.constants.ts index aa5aaeac..7c861582 100644 --- a/packages/plugin-ai-image-generation-web/src/fal-ai/Recraft20b.constants.ts +++ b/packages/plugin-ai-image-generation-web/src/fal-ai/Recraft20b.constants.ts @@ -226,101 +226,101 @@ export const STYLE_ICON_DEFAULT = STYLES_ICON[0]; // prettier-ignore const STYLE_THUMBNAILS: (baseURL: string) => ({ [key in StyleId]?: string }) = (baseURL) => ({ -'realistic_image': `${baseURL}/realistic_image.webp`, -'digital_illustration': `${baseURL}/digital_illustration.webp`, -'realistic_image/b_and_w': `${baseURL}/realistic_image_black_&_white.webp`, -'realistic_image/hard_flash': `${baseURL}/realistic_image_hard_flash.webp`, -'realistic_image/hdr': `${baseURL}/realistic_image_hdr.webp`, -'realistic_image/natural_light': `${baseURL}/realistic_image_natural_light.webp`, -'realistic_image/studio_portrait': `${baseURL}/realistic_image_studio_portrait.webp`, -'realistic_image/enterprise': `${baseURL}/realistic_image_enterprise.webp`, -'realistic_image/motion_blur': `${baseURL}/realistic_image_motion_blur.webp`, -'digital_illustration/pixel_art': `${baseURL}/digital_illustration_pixel_art.webp`, -'digital_illustration/hand_drawn': `${baseURL}/digital_illustration_hand_drawn.webp`, -'digital_illustration/grain': `${baseURL}/digital_illustration_grain.webp`, -'digital_illustration/infantile_sketch': `${baseURL}/digital_illustration_infantile_sketch.webp`, -'digital_illustration/2d_art_poster': `${baseURL}/digital_illustration_2d_art_poster.webp`, -'digital_illustration/handmade_3d': `${baseURL}/digital_illustration_handmade_3d.webp`, -'digital_illustration/hand_drawn_outline': `${baseURL}/digital_illustration_handdrawn_outline.webp`, -'digital_illustration/engraving_color': `${baseURL}/digital_illustration_engraving_color.webp`, -'digital_illustration/2d_art_poster_2': `${baseURL}/digital_illustration_2d_artposter_2.webp`, -'vector_illustration': `${baseURL}/vector_illustration.svg`, -'vector_illustration/bold_stroke': `${baseURL}/vector_illustration_bold_stroke.svg`, -'vector_illustration/chemistry': `${baseURL}/vector_illustration_chemistry.svg`, -'vector_illustration/colored_stencil': `${baseURL}/vector_illustration_colored_stencil.svg`, -'vector_illustration/contour_pop_art': `${baseURL}/vector_illustration_contour_pop_art.svg`, -'vector_illustration/cosmics': `${baseURL}/vector_illustration_cosmics.svg`, -'vector_illustration/cutout': `${baseURL}/vector_illustration_cutout.svg`, -'vector_illustration/depressive': `${baseURL}/vector_illustration_depressive.svg`, -'vector_illustration/editorial': `${baseURL}/vector_illustration_editorial.svg`, -'vector_illustration/emotional_flat': `${baseURL}/vector_illustration_emotional_flat.svg`, -'vector_illustration/infographical': `${baseURL}/vector_illustration_infographical.svg`, -'vector_illustration/marker_outline': `${baseURL}/vector_illustration_marker_outline.svg`, -'vector_illustration/mosaic': `${baseURL}/vector_illustration_mosaic.svg`, -'vector_illustration/naivector': `${baseURL}/vector_illustration_naivector.svg`, -'vector_illustration/roundish_flat': `${baseURL}/vector_illustration_roundish_flat.svg`, -'vector_illustration/segmented_colors': `${baseURL}/vector_illustration_segmented_colors.svg`, -'vector_illustration/sharp_contrast': `${baseURL}/vector_illustration_sharp_contrast.svg`, -'vector_illustration/thin': `${baseURL}/vector_illustration_thin.svg`, -'vector_illustration/vector_photo': `${baseURL}/vector_illustration_vector_photo.svg`, -'vector_illustration/vivid_shapes': `${baseURL}/vector_illustration_vivid_shapes.svg`, -'vector_illustration/engraving': `${baseURL}/vector_illustration_engraving.svg`, -'vector_illustration/line_art': `${baseURL}/vector_illustration_line_art.svg`, -'vector_illustration/line_circuit': `${baseURL}/vector_illustration_line_circuit.svg`, -'vector_illustration/linocut': `${baseURL}/vector_illustration_linocut.svg`, -'realistic_image/evening_light': `${baseURL}/realistic_image_evening_light.webp`, -'realistic_image/faded_nostalgia': `${baseURL}/realistic_image_faded_nostalgia.webp`, -'realistic_image/forest_life': `${baseURL}/realistic_image_forest_life.webp`, -'realistic_image/mystic_naturalism': `${baseURL}/realistic_image_mystic_naturalism.webp`, -'realistic_image/natural_tones': `${baseURL}/realistic_image_natural_tones.webp`, -'realistic_image/organic_calm': `${baseURL}/realistic_image_organic_calm.webp`, -'realistic_image/real_life_glow': `${baseURL}/realistic_image_real_life_glow.webp`, -'realistic_image/retro_realism': `${baseURL}/realistic_image_retro_realism.webp`, -'realistic_image/retro_snapshot': `${baseURL}/realistic_image_retro_snapshot.webp`, -'realistic_image/urban_drama': `${baseURL}/realistic_image_urban_drama.webp`, -'realistic_image/village_realism': `${baseURL}/realistic_image_village_realism.webp`, -'realistic_image/warm_folk': `${baseURL}/realistic_image_warm_folk.webp`, -'digital_illustration/antiquarian': `${baseURL}/digital_illustration_antiquarian.webp`, -'digital_illustration/bold_fantasy': `${baseURL}/digital_illustration_bold_fantasy.webp`, -'digital_illustration/child_book': `${baseURL}/digital_illustration_child_book.webp`, -'digital_illustration/child_books': `${baseURL}/digital_illustration_child_books.webp`, -'digital_illustration/cover': `${baseURL}/digital_illustration_cover.webp`, -'digital_illustration/crosshatch': `${baseURL}/digital_illustration_crosshatch.webp`, -'digital_illustration/digital_engraving': `${baseURL}/digital_illustration_digital_engraving.webp`, -'digital_illustration/expressionism': `${baseURL}/digital_illustration_expressionism.webp`, -'digital_illustration/freehand_details': `${baseURL}/digital_illustration_freehand_details.webp`, -'digital_illustration/grain_20': `${baseURL}/digital_illustration_grain_20.webp`, -'digital_illustration/graphic_intensity': `${baseURL}/digital_illustration_graphic_intensity.webp`, -'digital_illustration/hard_comics': `${baseURL}/digital_illustration_hard_comics.webp`, -'digital_illustration/long_shadow': `${baseURL}/digital_illustration_long_shadow.webp`, -'digital_illustration/modern_folk': `${baseURL}/digital_illustration_modern_folk.webp`, -'digital_illustration/multicolor': `${baseURL}/digital_illustration_multicolor.webp`, -'digital_illustration/neon_calm': `${baseURL}/digital_illustration_neon_calm.webp`, -'digital_illustration/noir': `${baseURL}/digital_illustration_noir.webp`, -'digital_illustration/nostalgic_pastel': `${baseURL}/digital_illustration_nostalgic_pastel.webp`, -'digital_illustration/outline_details': `${baseURL}/digital_illustration_outline_details.webp`, -'digital_illustration/pastel_gradient': `${baseURL}/digital_illustration_pastel_gradient.webp`, -'digital_illustration/pastel_sketch': `${baseURL}/digital_illustration_pastel_sketch.webp`, -'digital_illustration/pop_art': `${baseURL}/digital_illustration_pop_art.webp`, -'digital_illustration/pop_renaissance': `${baseURL}/digital_illustration_pop_renaissance.webp`, -'digital_illustration/street_art': `${baseURL}/digital_illustration_street_art.webp`, -'digital_illustration/tablet_sketch': `${baseURL}/digital_illustration_tablet_sketch.webp`, -'digital_illustration/urban_glow': `${baseURL}/digital_illustration_urban_glow.webp`, -'digital_illustration/urban_sketching': `${baseURL}/digital_illustration_urban_sketching.webp`, -'digital_illustration/vanilla_dreams': `${baseURL}/digital_illustration_vanilla_dreams.webp`, -'digital_illustration/young_adult_book': `${baseURL}/digital_illustration_young_adult_book.webp`, -'digital_illustration/young_adult_book_2': `${baseURL}/digital_illustration_young_adult_book_2.webp`, +'realistic_image': `${baseURL}realistic_image.webp`, +'digital_illustration': `${baseURL}digital_illustration.webp`, +'realistic_image/b_and_w': `${baseURL}realistic_image_black_&_white.webp`, +'realistic_image/hard_flash': `${baseURL}realistic_image_hard_flash.webp`, +'realistic_image/hdr': `${baseURL}realistic_image_hdr.webp`, +'realistic_image/natural_light': `${baseURL}realistic_image_natural_light.webp`, +'realistic_image/studio_portrait': `${baseURL}realistic_image_studio_portrait.webp`, +'realistic_image/enterprise': `${baseURL}realistic_image_enterprise.webp`, +'realistic_image/motion_blur': `${baseURL}realistic_image_motion_blur.webp`, +'digital_illustration/pixel_art': `${baseURL}digital_illustration_pixel_art.webp`, +'digital_illustration/hand_drawn': `${baseURL}digital_illustration_hand_drawn.webp`, +'digital_illustration/grain': `${baseURL}digital_illustration_grain.webp`, +'digital_illustration/infantile_sketch': `${baseURL}digital_illustration_infantile_sketch.webp`, +'digital_illustration/2d_art_poster': `${baseURL}digital_illustration_2d_art_poster.webp`, +'digital_illustration/handmade_3d': `${baseURL}digital_illustration_handmade_3d.webp`, +'digital_illustration/hand_drawn_outline': `${baseURL}digital_illustration_handdrawn_outline.webp`, +'digital_illustration/engraving_color': `${baseURL}digital_illustration_engraving_color.webp`, +'digital_illustration/2d_art_poster_2': `${baseURL}digital_illustration_2d_artposter_2.webp`, +'vector_illustration': `${baseURL}vector_illustration.svg`, +'vector_illustration/bold_stroke': `${baseURL}vector_illustration_bold_stroke.svg`, +'vector_illustration/chemistry': `${baseURL}vector_illustration_chemistry.svg`, +'vector_illustration/colored_stencil': `${baseURL}vector_illustration_colored_stencil.svg`, +'vector_illustration/contour_pop_art': `${baseURL}vector_illustration_contour_pop_art.svg`, +'vector_illustration/cosmics': `${baseURL}vector_illustration_cosmics.svg`, +'vector_illustration/cutout': `${baseURL}vector_illustration_cutout.svg`, +'vector_illustration/depressive': `${baseURL}vector_illustration_depressive.svg`, +'vector_illustration/editorial': `${baseURL}vector_illustration_editorial.svg`, +'vector_illustration/emotional_flat': `${baseURL}vector_illustration_emotional_flat.svg`, +'vector_illustration/infographical': `${baseURL}vector_illustration_infographical.svg`, +'vector_illustration/marker_outline': `${baseURL}vector_illustration_marker_outline.svg`, +'vector_illustration/mosaic': `${baseURL}vector_illustration_mosaic.svg`, +'vector_illustration/naivector': `${baseURL}vector_illustration_naivector.svg`, +'vector_illustration/roundish_flat': `${baseURL}vector_illustration_roundish_flat.svg`, +'vector_illustration/segmented_colors': `${baseURL}vector_illustration_segmented_colors.svg`, +'vector_illustration/sharp_contrast': `${baseURL}vector_illustration_sharp_contrast.svg`, +'vector_illustration/thin': `${baseURL}vector_illustration_thin.svg`, +'vector_illustration/vector_photo': `${baseURL}vector_illustration_vector_photo.svg`, +'vector_illustration/vivid_shapes': `${baseURL}vector_illustration_vivid_shapes.svg`, +'vector_illustration/engraving': `${baseURL}vector_illustration_engraving.svg`, +'vector_illustration/line_art': `${baseURL}vector_illustration_line_art.svg`, +'vector_illustration/line_circuit': `${baseURL}vector_illustration_line_circuit.svg`, +'vector_illustration/linocut': `${baseURL}vector_illustration_linocut.svg`, +'realistic_image/evening_light': `${baseURL}realistic_image_evening_light.webp`, +'realistic_image/faded_nostalgia': `${baseURL}realistic_image_faded_nostalgia.webp`, +'realistic_image/forest_life': `${baseURL}realistic_image_forest_life.webp`, +'realistic_image/mystic_naturalism': `${baseURL}realistic_image_mystic_naturalism.webp`, +'realistic_image/natural_tones': `${baseURL}realistic_image_natural_tones.webp`, +'realistic_image/organic_calm': `${baseURL}realistic_image_organic_calm.webp`, +'realistic_image/real_life_glow': `${baseURL}realistic_image_real_life_glow.webp`, +'realistic_image/retro_realism': `${baseURL}realistic_image_retro_realism.webp`, +'realistic_image/retro_snapshot': `${baseURL}realistic_image_retro_snapshot.webp`, +'realistic_image/urban_drama': `${baseURL}realistic_image_urban_drama.webp`, +'realistic_image/village_realism': `${baseURL}realistic_image_village_realism.webp`, +'realistic_image/warm_folk': `${baseURL}realistic_image_warm_folk.webp`, +'digital_illustration/antiquarian': `${baseURL}digital_illustration_antiquarian.webp`, +'digital_illustration/bold_fantasy': `${baseURL}digital_illustration_bold_fantasy.webp`, +'digital_illustration/child_book': `${baseURL}digital_illustration_child_book.webp`, +'digital_illustration/child_books': `${baseURL}digital_illustration_child_books.webp`, +'digital_illustration/cover': `${baseURL}digital_illustration_cover.webp`, +'digital_illustration/crosshatch': `${baseURL}digital_illustration_crosshatch.webp`, +'digital_illustration/digital_engraving': `${baseURL}digital_illustration_digital_engraving.webp`, +'digital_illustration/expressionism': `${baseURL}digital_illustration_expressionism.webp`, +'digital_illustration/freehand_details': `${baseURL}digital_illustration_freehand_details.webp`, +'digital_illustration/grain_20': `${baseURL}digital_illustration_grain_20.webp`, +'digital_illustration/graphic_intensity': `${baseURL}digital_illustration_graphic_intensity.webp`, +'digital_illustration/hard_comics': `${baseURL}digital_illustration_hard_comics.webp`, +'digital_illustration/long_shadow': `${baseURL}digital_illustration_long_shadow.webp`, +'digital_illustration/modern_folk': `${baseURL}digital_illustration_modern_folk.webp`, +'digital_illustration/multicolor': `${baseURL}digital_illustration_multicolor.webp`, +'digital_illustration/neon_calm': `${baseURL}digital_illustration_neon_calm.webp`, +'digital_illustration/noir': `${baseURL}digital_illustration_noir.webp`, +'digital_illustration/nostalgic_pastel': `${baseURL}digital_illustration_nostalgic_pastel.webp`, +'digital_illustration/outline_details': `${baseURL}digital_illustration_outline_details.webp`, +'digital_illustration/pastel_gradient': `${baseURL}digital_illustration_pastel_gradient.webp`, +'digital_illustration/pastel_sketch': `${baseURL}digital_illustration_pastel_sketch.webp`, +'digital_illustration/pop_art': `${baseURL}digital_illustration_pop_art.webp`, +'digital_illustration/pop_renaissance': `${baseURL}digital_illustration_pop_renaissance.webp`, +'digital_illustration/street_art': `${baseURL}digital_illustration_street_art.webp`, +'digital_illustration/tablet_sketch': `${baseURL}digital_illustration_tablet_sketch.webp`, +'digital_illustration/urban_glow': `${baseURL}digital_illustration_urban_glow.webp`, +'digital_illustration/urban_sketching': `${baseURL}digital_illustration_urban_sketching.webp`, +'digital_illustration/vanilla_dreams': `${baseURL}digital_illustration_vanilla_dreams.webp`, +'digital_illustration/young_adult_book': `${baseURL}digital_illustration_young_adult_book.webp`, +'digital_illustration/young_adult_book_2': `${baseURL}digital_illustration_young_adult_book_2.webp`, // Icon style thumbnails (using SVG format like vector styles) -'icon/broken_line': `${baseURL}/icon_broken_line.svg`, -'icon/colored_outline': `${baseURL}/icon_colored_outline.svg`, -'icon/colored_shapes': `${baseURL}/icon_colored_shapes.svg`, -'icon/colored_shapes_gradient': `${baseURL}/icon_colored_shapes_gradient.svg`, -'icon/doodle_fill': `${baseURL}/icon_doodle_fill.svg`, -'icon/doodle_offset_fill': `${baseURL}/icon_doodle_offset_fill.svg`, -'icon/offset_fill': `${baseURL}/icon_offset_fill.svg`, -'icon/outline': `${baseURL}/icon_outline.svg`, -'icon/outline_gradient': `${baseURL}/icon_outline_gradient.svg`, -'icon/uneven_fill': `${baseURL}/icon_uneven_fill.svg`, +'icon/broken_line': `${baseURL}icon_broken_line.svg`, +'icon/colored_outline': `${baseURL}icon_colored_outline.svg`, +'icon/colored_shapes': `${baseURL}icon_colored_shapes.svg`, +'icon/colored_shapes_gradient': `${baseURL}icon_colored_shapes_gradient.svg`, +'icon/doodle_fill': `${baseURL}icon_doodle_fill.svg`, +'icon/doodle_offset_fill': `${baseURL}icon_doodle_offset_fill.svg`, +'icon/offset_fill': `${baseURL}icon_offset_fill.svg`, +'icon/outline': `${baseURL}icon_outline.svg`, +'icon/outline_gradient': `${baseURL}icon_outline_gradient.svg`, +'icon/uneven_fill': `${baseURL}icon_uneven_fill.svg`, }) export function getStyleThumbnail( diff --git a/packages/plugin-ai-image-generation-web/src/fal-ai/Recraft20b.ts b/packages/plugin-ai-image-generation-web/src/fal-ai/Recraft20b.ts index 3c76911e..b0209c46 100644 --- a/packages/plugin-ai-image-generation-web/src/fal-ai/Recraft20b.ts +++ b/packages/plugin-ai-image-generation-web/src/fal-ai/Recraft20b.ts @@ -2,7 +2,8 @@ import { Icons, CustomAssetSource } from '@imgly/plugin-utils'; import { type Provider, getPanelId, - createTranslationCallback + createTranslationCallback, + normalizeBaseURL } from '@imgly/plugin-ai-generation-web'; import Recraft20bSchema from './Recraft20b.json'; import CreativeEditorSDK, { AssetResult } from '@cesdk/cesdk-js'; @@ -73,9 +74,11 @@ function getProvider( const styleImageAssetSourceId = `${modelKey}/styles/image`; const styleVectorAssetSourceId = `${modelKey}/styles/vector`; const styleIconAssetSourceId = `${modelKey}/styles/icon`; - const baseURL = + // Normalize baseURL to ensure exactly one trailing slash + const baseURL = normalizeBaseURL( config.baseURL ?? - 'https://cdn.img.ly/assets/plugins/plugin-ai-image-generation-web/v1/recraft-v3/'; + 'https://cdn.img.ly/assets/plugins/plugin-ai-image-generation-web/v1/recraft-v3/' + ); // Initialize feature flags for style groups cesdk.feature.enable( diff --git a/packages/plugin-ai-image-generation-web/src/fal-ai/RecraftV3.constants.ts b/packages/plugin-ai-image-generation-web/src/fal-ai/RecraftV3.constants.ts index 7e60db07..734d1ca5 100644 --- a/packages/plugin-ai-image-generation-web/src/fal-ai/RecraftV3.constants.ts +++ b/packages/plugin-ai-image-generation-web/src/fal-ai/RecraftV3.constants.ts @@ -117,90 +117,90 @@ export const STYLE_VECTOR_DEFAULT = STYLES_VECTOR[0]; // prettier-ignore const STYLE_THUMBNAILS: (baseURL: string) => ({ [key in StyleId]?: string }) = (baseURL) => ({ -'realistic_image': `${baseURL}/realistic_image.webp`, -'digital_illustration': `${baseURL}/digital_illustration.webp`, -'realistic_image/b_and_w': `${baseURL}/realistic_image_black_&_white.webp`, -'realistic_image/hard_flash': `${baseURL}/realistic_image_hard_flash.webp`, -'realistic_image/hdr': `${baseURL}/realistic_image_hdr.webp`, -'realistic_image/natural_light': `${baseURL}/realistic_image_natural_light.webp`, -'realistic_image/studio_portrait': `${baseURL}/realistic_image_studio_portrait.webp`, -'realistic_image/enterprise': `${baseURL}/realistic_image_enterprise.webp`, -'realistic_image/motion_blur': `${baseURL}/realistic_image_motion_blur.webp`, -'digital_illustration/pixel_art': `${baseURL}/digital_illustration_pixel_art.webp`, -'digital_illustration/hand_drawn': `${baseURL}/digital_illustration_hand_drawn.webp`, -'digital_illustration/grain': `${baseURL}/digital_illustration_grain.webp`, -'digital_illustration/infantile_sketch': `${baseURL}/digital_illustration_infantile_sketch.webp`, -'digital_illustration/2d_art_poster': `${baseURL}/digital_illustration_2d_art_poster.webp`, -'digital_illustration/handmade_3d': `${baseURL}/digital_illustration_handmade_3d.webp`, -'digital_illustration/hand_drawn_outline': `${baseURL}/digital_illustration_handdrawn_outline.webp`, -'digital_illustration/engraving_color': `${baseURL}/digital_illustration_engraving_color.webp`, -'digital_illustration/2d_art_poster_2': `${baseURL}/digital_illustration_2d_artposter_2.webp`, -'vector_illustration': `${baseURL}/vector_illustration.svg`, -'vector_illustration/bold_stroke': `${baseURL}/vector_illustration_bold_stroke.svg`, -'vector_illustration/chemistry': `${baseURL}/vector_illustration_chemistry.svg`, -'vector_illustration/colored_stencil': `${baseURL}/vector_illustration_colored_stencil.svg`, -'vector_illustration/contour_pop_art': `${baseURL}/vector_illustration_contour_pop_art.svg`, -'vector_illustration/cosmics': `${baseURL}/vector_illustration_cosmics.svg`, -'vector_illustration/cutout': `${baseURL}/vector_illustration_cutout.svg`, -'vector_illustration/depressive': `${baseURL}/vector_illustration_depressive.svg`, -'vector_illustration/editorial': `${baseURL}/vector_illustration_editorial.svg`, -'vector_illustration/emotional_flat': `${baseURL}/vector_illustration_emotional_flat.svg`, -'vector_illustration/infographical': `${baseURL}/vector_illustration_infographical.svg`, -'vector_illustration/marker_outline': `${baseURL}/vector_illustration_marker_outline.svg`, -'vector_illustration/mosaic': `${baseURL}/vector_illustration_mosaic.svg`, -'vector_illustration/naivector': `${baseURL}/vector_illustration_naivector.svg`, -'vector_illustration/roundish_flat': `${baseURL}/vector_illustration_roundish_flat.svg`, -'vector_illustration/segmented_colors': `${baseURL}/vector_illustration_segmented_colors.svg`, -'vector_illustration/sharp_contrast': `${baseURL}/vector_illustration_sharp_contrast.svg`, -'vector_illustration/thin': `${baseURL}/vector_illustration_thin.svg`, -'vector_illustration/vector_photo': `${baseURL}/vector_illustration_vector_photo.svg`, -'vector_illustration/vivid_shapes': `${baseURL}/vector_illustration_vivid_shapes.svg`, -'vector_illustration/engraving': `${baseURL}/vector_illustration_engraving.svg`, -'vector_illustration/line_art': `${baseURL}/vector_illustration_line_art.svg`, -'vector_illustration/line_circuit': `${baseURL}/vector_illustration_line_circuit.svg`, -'vector_illustration/linocut': `${baseURL}/vector_illustration_linocut.svg`, -'realistic_image/evening_light': `${baseURL}/realistic_image_evening_light.webp`, -'realistic_image/faded_nostalgia': `${baseURL}/realistic_image_faded_nostalgia.webp`, -'realistic_image/forest_life': `${baseURL}/realistic_image_forest_life.webp`, -'realistic_image/mystic_naturalism': `${baseURL}/realistic_image_mystic_naturalism.webp`, -'realistic_image/natural_tones': `${baseURL}/realistic_image_natural_tones.webp`, -'realistic_image/organic_calm': `${baseURL}/realistic_image_organic_calm.webp`, -'realistic_image/real_life_glow': `${baseURL}/realistic_image_real_life_glow.webp`, -'realistic_image/retro_realism': `${baseURL}/realistic_image_retro_realism.webp`, -'realistic_image/retro_snapshot': `${baseURL}/realistic_image_retro_snapshot.webp`, -'realistic_image/urban_drama': `${baseURL}/realistic_image_urban_drama.webp`, -'realistic_image/village_realism': `${baseURL}/realistic_image_village_realism.webp`, -'realistic_image/warm_folk': `${baseURL}/realistic_image_warm_folk.webp`, -'digital_illustration/antiquarian': `${baseURL}/digital_illustration_antiquarian.webp`, -'digital_illustration/bold_fantasy': `${baseURL}/digital_illustration_bold_fantasy.webp`, -'digital_illustration/child_book': `${baseURL}/digital_illustration_child_book.webp`, -'digital_illustration/child_books': `${baseURL}/digital_illustration_child_books.webp`, -'digital_illustration/cover': `${baseURL}/digital_illustration_cover.webp`, -'digital_illustration/crosshatch': `${baseURL}/digital_illustration_crosshatch.webp`, -'digital_illustration/digital_engraving': `${baseURL}/digital_illustration_digital_engraving.webp`, -'digital_illustration/expressionism': `${baseURL}/digital_illustration_expressionism.webp`, -'digital_illustration/freehand_details': `${baseURL}/digital_illustration_freehand_details.webp`, -'digital_illustration/grain_20': `${baseURL}/digital_illustration_grain_20.webp`, -'digital_illustration/graphic_intensity': `${baseURL}/digital_illustration_graphic_intensity.webp`, -'digital_illustration/hard_comics': `${baseURL}/digital_illustration_hard_comics.webp`, -'digital_illustration/long_shadow': `${baseURL}/digital_illustration_long_shadow.webp`, -'digital_illustration/modern_folk': `${baseURL}/digital_illustration_modern_folk.webp`, -'digital_illustration/multicolor': `${baseURL}/digital_illustration_multicolor.webp`, -'digital_illustration/neon_calm': `${baseURL}/digital_illustration_neon_calm.webp`, -'digital_illustration/noir': `${baseURL}/digital_illustration_noir.webp`, -'digital_illustration/nostalgic_pastel': `${baseURL}/digital_illustration_nostalgic_pastel.webp`, -'digital_illustration/outline_details': `${baseURL}/digital_illustration_outline_details.webp`, -'digital_illustration/pastel_gradient': `${baseURL}/digital_illustration_pastel_gradient.webp`, -'digital_illustration/pastel_sketch': `${baseURL}/digital_illustration_pastel_sketch.webp`, -'digital_illustration/pop_art': `${baseURL}/digital_illustration_pop_art.webp`, -'digital_illustration/pop_renaissance': `${baseURL}/digital_illustration_pop_renaissance.webp`, -'digital_illustration/street_art': `${baseURL}/digital_illustration_street_art.webp`, -'digital_illustration/tablet_sketch': `${baseURL}/digital_illustration_tablet_sketch.webp`, -'digital_illustration/urban_glow': `${baseURL}/digital_illustration_urban_glow.webp`, -'digital_illustration/urban_sketching': `${baseURL}/digital_illustration_urban_sketching.webp`, -'digital_illustration/vanilla_dreams': `${baseURL}/digital_illustration_vanilla_dreams.webp`, -'digital_illustration/young_adult_book': `${baseURL}/digital_illustration_young_adult_book.webp`, -'digital_illustration/young_adult_book_2': `${baseURL}/digital_illustration_young_adult_book_2.webp`, +'realistic_image': `${baseURL}realistic_image.webp`, +'digital_illustration': `${baseURL}digital_illustration.webp`, +'realistic_image/b_and_w': `${baseURL}realistic_image_black_&_white.webp`, +'realistic_image/hard_flash': `${baseURL}realistic_image_hard_flash.webp`, +'realistic_image/hdr': `${baseURL}realistic_image_hdr.webp`, +'realistic_image/natural_light': `${baseURL}realistic_image_natural_light.webp`, +'realistic_image/studio_portrait': `${baseURL}realistic_image_studio_portrait.webp`, +'realistic_image/enterprise': `${baseURL}realistic_image_enterprise.webp`, +'realistic_image/motion_blur': `${baseURL}realistic_image_motion_blur.webp`, +'digital_illustration/pixel_art': `${baseURL}digital_illustration_pixel_art.webp`, +'digital_illustration/hand_drawn': `${baseURL}digital_illustration_hand_drawn.webp`, +'digital_illustration/grain': `${baseURL}digital_illustration_grain.webp`, +'digital_illustration/infantile_sketch': `${baseURL}digital_illustration_infantile_sketch.webp`, +'digital_illustration/2d_art_poster': `${baseURL}digital_illustration_2d_art_poster.webp`, +'digital_illustration/handmade_3d': `${baseURL}digital_illustration_handmade_3d.webp`, +'digital_illustration/hand_drawn_outline': `${baseURL}digital_illustration_handdrawn_outline.webp`, +'digital_illustration/engraving_color': `${baseURL}digital_illustration_engraving_color.webp`, +'digital_illustration/2d_art_poster_2': `${baseURL}digital_illustration_2d_artposter_2.webp`, +'vector_illustration': `${baseURL}vector_illustration.svg`, +'vector_illustration/bold_stroke': `${baseURL}vector_illustration_bold_stroke.svg`, +'vector_illustration/chemistry': `${baseURL}vector_illustration_chemistry.svg`, +'vector_illustration/colored_stencil': `${baseURL}vector_illustration_colored_stencil.svg`, +'vector_illustration/contour_pop_art': `${baseURL}vector_illustration_contour_pop_art.svg`, +'vector_illustration/cosmics': `${baseURL}vector_illustration_cosmics.svg`, +'vector_illustration/cutout': `${baseURL}vector_illustration_cutout.svg`, +'vector_illustration/depressive': `${baseURL}vector_illustration_depressive.svg`, +'vector_illustration/editorial': `${baseURL}vector_illustration_editorial.svg`, +'vector_illustration/emotional_flat': `${baseURL}vector_illustration_emotional_flat.svg`, +'vector_illustration/infographical': `${baseURL}vector_illustration_infographical.svg`, +'vector_illustration/marker_outline': `${baseURL}vector_illustration_marker_outline.svg`, +'vector_illustration/mosaic': `${baseURL}vector_illustration_mosaic.svg`, +'vector_illustration/naivector': `${baseURL}vector_illustration_naivector.svg`, +'vector_illustration/roundish_flat': `${baseURL}vector_illustration_roundish_flat.svg`, +'vector_illustration/segmented_colors': `${baseURL}vector_illustration_segmented_colors.svg`, +'vector_illustration/sharp_contrast': `${baseURL}vector_illustration_sharp_contrast.svg`, +'vector_illustration/thin': `${baseURL}vector_illustration_thin.svg`, +'vector_illustration/vector_photo': `${baseURL}vector_illustration_vector_photo.svg`, +'vector_illustration/vivid_shapes': `${baseURL}vector_illustration_vivid_shapes.svg`, +'vector_illustration/engraving': `${baseURL}vector_illustration_engraving.svg`, +'vector_illustration/line_art': `${baseURL}vector_illustration_line_art.svg`, +'vector_illustration/line_circuit': `${baseURL}vector_illustration_line_circuit.svg`, +'vector_illustration/linocut': `${baseURL}vector_illustration_linocut.svg`, +'realistic_image/evening_light': `${baseURL}realistic_image_evening_light.webp`, +'realistic_image/faded_nostalgia': `${baseURL}realistic_image_faded_nostalgia.webp`, +'realistic_image/forest_life': `${baseURL}realistic_image_forest_life.webp`, +'realistic_image/mystic_naturalism': `${baseURL}realistic_image_mystic_naturalism.webp`, +'realistic_image/natural_tones': `${baseURL}realistic_image_natural_tones.webp`, +'realistic_image/organic_calm': `${baseURL}realistic_image_organic_calm.webp`, +'realistic_image/real_life_glow': `${baseURL}realistic_image_real_life_glow.webp`, +'realistic_image/retro_realism': `${baseURL}realistic_image_retro_realism.webp`, +'realistic_image/retro_snapshot': `${baseURL}realistic_image_retro_snapshot.webp`, +'realistic_image/urban_drama': `${baseURL}realistic_image_urban_drama.webp`, +'realistic_image/village_realism': `${baseURL}realistic_image_village_realism.webp`, +'realistic_image/warm_folk': `${baseURL}realistic_image_warm_folk.webp`, +'digital_illustration/antiquarian': `${baseURL}digital_illustration_antiquarian.webp`, +'digital_illustration/bold_fantasy': `${baseURL}digital_illustration_bold_fantasy.webp`, +'digital_illustration/child_book': `${baseURL}digital_illustration_child_book.webp`, +'digital_illustration/child_books': `${baseURL}digital_illustration_child_books.webp`, +'digital_illustration/cover': `${baseURL}digital_illustration_cover.webp`, +'digital_illustration/crosshatch': `${baseURL}digital_illustration_crosshatch.webp`, +'digital_illustration/digital_engraving': `${baseURL}digital_illustration_digital_engraving.webp`, +'digital_illustration/expressionism': `${baseURL}digital_illustration_expressionism.webp`, +'digital_illustration/freehand_details': `${baseURL}digital_illustration_freehand_details.webp`, +'digital_illustration/grain_20': `${baseURL}digital_illustration_grain_20.webp`, +'digital_illustration/graphic_intensity': `${baseURL}digital_illustration_graphic_intensity.webp`, +'digital_illustration/hard_comics': `${baseURL}digital_illustration_hard_comics.webp`, +'digital_illustration/long_shadow': `${baseURL}digital_illustration_long_shadow.webp`, +'digital_illustration/modern_folk': `${baseURL}digital_illustration_modern_folk.webp`, +'digital_illustration/multicolor': `${baseURL}digital_illustration_multicolor.webp`, +'digital_illustration/neon_calm': `${baseURL}digital_illustration_neon_calm.webp`, +'digital_illustration/noir': `${baseURL}digital_illustration_noir.webp`, +'digital_illustration/nostalgic_pastel': `${baseURL}digital_illustration_nostalgic_pastel.webp`, +'digital_illustration/outline_details': `${baseURL}digital_illustration_outline_details.webp`, +'digital_illustration/pastel_gradient': `${baseURL}digital_illustration_pastel_gradient.webp`, +'digital_illustration/pastel_sketch': `${baseURL}digital_illustration_pastel_sketch.webp`, +'digital_illustration/pop_art': `${baseURL}digital_illustration_pop_art.webp`, +'digital_illustration/pop_renaissance': `${baseURL}digital_illustration_pop_renaissance.webp`, +'digital_illustration/street_art': `${baseURL}digital_illustration_street_art.webp`, +'digital_illustration/tablet_sketch': `${baseURL}digital_illustration_tablet_sketch.webp`, +'digital_illustration/urban_glow': `${baseURL}digital_illustration_urban_glow.webp`, +'digital_illustration/urban_sketching': `${baseURL}digital_illustration_urban_sketching.webp`, +'digital_illustration/vanilla_dreams': `${baseURL}digital_illustration_vanilla_dreams.webp`, +'digital_illustration/young_adult_book': `${baseURL}digital_illustration_young_adult_book.webp`, +'digital_illustration/young_adult_book_2': `${baseURL}digital_illustration_young_adult_book_2.webp`, }) export function getStyleThumbnail( diff --git a/packages/plugin-ai-image-generation-web/src/fal-ai/RecraftV3.ts b/packages/plugin-ai-image-generation-web/src/fal-ai/RecraftV3.ts index c857ce02..957f394f 100644 --- a/packages/plugin-ai-image-generation-web/src/fal-ai/RecraftV3.ts +++ b/packages/plugin-ai-image-generation-web/src/fal-ai/RecraftV3.ts @@ -2,7 +2,8 @@ import { Icons, CustomAssetSource } from '@imgly/plugin-utils'; import { type Provider, getPanelId, - createTranslationCallback + createTranslationCallback, + normalizeBaseURL } from '@imgly/plugin-ai-generation-web'; import { type RecraftV3TextToImageInput } from '@fal-ai/client/endpoints'; import RecraftV3Schema from './RecraftV3.json'; @@ -55,9 +56,11 @@ function getProvider( const modelKey = 'fal-ai/recraft-v3'; const styleImageAssetSourceId = `${modelKey}/styles/image`; const styleVectorAssetSourceId = `${modelKey}/styles/vector`; - const baseURL = + // Normalize baseURL to ensure exactly one trailing slash + const baseURL = normalizeBaseURL( config.baseURL ?? - 'https://cdn.img.ly/assets/plugins/plugin-ai-image-generation-web/v1/recraft-v3/'; + 'https://cdn.img.ly/assets/plugins/plugin-ai-image-generation-web/v1/recraft-v3/' + ); // Initialize feature flags for style groups cesdk.feature.enable( diff --git a/packages/plugin-ai-sticker-generation-web/src/fal-ai/Recraft20b.constants.ts b/packages/plugin-ai-sticker-generation-web/src/fal-ai/Recraft20b.constants.ts index aa5aaeac..7c861582 100644 --- a/packages/plugin-ai-sticker-generation-web/src/fal-ai/Recraft20b.constants.ts +++ b/packages/plugin-ai-sticker-generation-web/src/fal-ai/Recraft20b.constants.ts @@ -226,101 +226,101 @@ export const STYLE_ICON_DEFAULT = STYLES_ICON[0]; // prettier-ignore const STYLE_THUMBNAILS: (baseURL: string) => ({ [key in StyleId]?: string }) = (baseURL) => ({ -'realistic_image': `${baseURL}/realistic_image.webp`, -'digital_illustration': `${baseURL}/digital_illustration.webp`, -'realistic_image/b_and_w': `${baseURL}/realistic_image_black_&_white.webp`, -'realistic_image/hard_flash': `${baseURL}/realistic_image_hard_flash.webp`, -'realistic_image/hdr': `${baseURL}/realistic_image_hdr.webp`, -'realistic_image/natural_light': `${baseURL}/realistic_image_natural_light.webp`, -'realistic_image/studio_portrait': `${baseURL}/realistic_image_studio_portrait.webp`, -'realistic_image/enterprise': `${baseURL}/realistic_image_enterprise.webp`, -'realistic_image/motion_blur': `${baseURL}/realistic_image_motion_blur.webp`, -'digital_illustration/pixel_art': `${baseURL}/digital_illustration_pixel_art.webp`, -'digital_illustration/hand_drawn': `${baseURL}/digital_illustration_hand_drawn.webp`, -'digital_illustration/grain': `${baseURL}/digital_illustration_grain.webp`, -'digital_illustration/infantile_sketch': `${baseURL}/digital_illustration_infantile_sketch.webp`, -'digital_illustration/2d_art_poster': `${baseURL}/digital_illustration_2d_art_poster.webp`, -'digital_illustration/handmade_3d': `${baseURL}/digital_illustration_handmade_3d.webp`, -'digital_illustration/hand_drawn_outline': `${baseURL}/digital_illustration_handdrawn_outline.webp`, -'digital_illustration/engraving_color': `${baseURL}/digital_illustration_engraving_color.webp`, -'digital_illustration/2d_art_poster_2': `${baseURL}/digital_illustration_2d_artposter_2.webp`, -'vector_illustration': `${baseURL}/vector_illustration.svg`, -'vector_illustration/bold_stroke': `${baseURL}/vector_illustration_bold_stroke.svg`, -'vector_illustration/chemistry': `${baseURL}/vector_illustration_chemistry.svg`, -'vector_illustration/colored_stencil': `${baseURL}/vector_illustration_colored_stencil.svg`, -'vector_illustration/contour_pop_art': `${baseURL}/vector_illustration_contour_pop_art.svg`, -'vector_illustration/cosmics': `${baseURL}/vector_illustration_cosmics.svg`, -'vector_illustration/cutout': `${baseURL}/vector_illustration_cutout.svg`, -'vector_illustration/depressive': `${baseURL}/vector_illustration_depressive.svg`, -'vector_illustration/editorial': `${baseURL}/vector_illustration_editorial.svg`, -'vector_illustration/emotional_flat': `${baseURL}/vector_illustration_emotional_flat.svg`, -'vector_illustration/infographical': `${baseURL}/vector_illustration_infographical.svg`, -'vector_illustration/marker_outline': `${baseURL}/vector_illustration_marker_outline.svg`, -'vector_illustration/mosaic': `${baseURL}/vector_illustration_mosaic.svg`, -'vector_illustration/naivector': `${baseURL}/vector_illustration_naivector.svg`, -'vector_illustration/roundish_flat': `${baseURL}/vector_illustration_roundish_flat.svg`, -'vector_illustration/segmented_colors': `${baseURL}/vector_illustration_segmented_colors.svg`, -'vector_illustration/sharp_contrast': `${baseURL}/vector_illustration_sharp_contrast.svg`, -'vector_illustration/thin': `${baseURL}/vector_illustration_thin.svg`, -'vector_illustration/vector_photo': `${baseURL}/vector_illustration_vector_photo.svg`, -'vector_illustration/vivid_shapes': `${baseURL}/vector_illustration_vivid_shapes.svg`, -'vector_illustration/engraving': `${baseURL}/vector_illustration_engraving.svg`, -'vector_illustration/line_art': `${baseURL}/vector_illustration_line_art.svg`, -'vector_illustration/line_circuit': `${baseURL}/vector_illustration_line_circuit.svg`, -'vector_illustration/linocut': `${baseURL}/vector_illustration_linocut.svg`, -'realistic_image/evening_light': `${baseURL}/realistic_image_evening_light.webp`, -'realistic_image/faded_nostalgia': `${baseURL}/realistic_image_faded_nostalgia.webp`, -'realistic_image/forest_life': `${baseURL}/realistic_image_forest_life.webp`, -'realistic_image/mystic_naturalism': `${baseURL}/realistic_image_mystic_naturalism.webp`, -'realistic_image/natural_tones': `${baseURL}/realistic_image_natural_tones.webp`, -'realistic_image/organic_calm': `${baseURL}/realistic_image_organic_calm.webp`, -'realistic_image/real_life_glow': `${baseURL}/realistic_image_real_life_glow.webp`, -'realistic_image/retro_realism': `${baseURL}/realistic_image_retro_realism.webp`, -'realistic_image/retro_snapshot': `${baseURL}/realistic_image_retro_snapshot.webp`, -'realistic_image/urban_drama': `${baseURL}/realistic_image_urban_drama.webp`, -'realistic_image/village_realism': `${baseURL}/realistic_image_village_realism.webp`, -'realistic_image/warm_folk': `${baseURL}/realistic_image_warm_folk.webp`, -'digital_illustration/antiquarian': `${baseURL}/digital_illustration_antiquarian.webp`, -'digital_illustration/bold_fantasy': `${baseURL}/digital_illustration_bold_fantasy.webp`, -'digital_illustration/child_book': `${baseURL}/digital_illustration_child_book.webp`, -'digital_illustration/child_books': `${baseURL}/digital_illustration_child_books.webp`, -'digital_illustration/cover': `${baseURL}/digital_illustration_cover.webp`, -'digital_illustration/crosshatch': `${baseURL}/digital_illustration_crosshatch.webp`, -'digital_illustration/digital_engraving': `${baseURL}/digital_illustration_digital_engraving.webp`, -'digital_illustration/expressionism': `${baseURL}/digital_illustration_expressionism.webp`, -'digital_illustration/freehand_details': `${baseURL}/digital_illustration_freehand_details.webp`, -'digital_illustration/grain_20': `${baseURL}/digital_illustration_grain_20.webp`, -'digital_illustration/graphic_intensity': `${baseURL}/digital_illustration_graphic_intensity.webp`, -'digital_illustration/hard_comics': `${baseURL}/digital_illustration_hard_comics.webp`, -'digital_illustration/long_shadow': `${baseURL}/digital_illustration_long_shadow.webp`, -'digital_illustration/modern_folk': `${baseURL}/digital_illustration_modern_folk.webp`, -'digital_illustration/multicolor': `${baseURL}/digital_illustration_multicolor.webp`, -'digital_illustration/neon_calm': `${baseURL}/digital_illustration_neon_calm.webp`, -'digital_illustration/noir': `${baseURL}/digital_illustration_noir.webp`, -'digital_illustration/nostalgic_pastel': `${baseURL}/digital_illustration_nostalgic_pastel.webp`, -'digital_illustration/outline_details': `${baseURL}/digital_illustration_outline_details.webp`, -'digital_illustration/pastel_gradient': `${baseURL}/digital_illustration_pastel_gradient.webp`, -'digital_illustration/pastel_sketch': `${baseURL}/digital_illustration_pastel_sketch.webp`, -'digital_illustration/pop_art': `${baseURL}/digital_illustration_pop_art.webp`, -'digital_illustration/pop_renaissance': `${baseURL}/digital_illustration_pop_renaissance.webp`, -'digital_illustration/street_art': `${baseURL}/digital_illustration_street_art.webp`, -'digital_illustration/tablet_sketch': `${baseURL}/digital_illustration_tablet_sketch.webp`, -'digital_illustration/urban_glow': `${baseURL}/digital_illustration_urban_glow.webp`, -'digital_illustration/urban_sketching': `${baseURL}/digital_illustration_urban_sketching.webp`, -'digital_illustration/vanilla_dreams': `${baseURL}/digital_illustration_vanilla_dreams.webp`, -'digital_illustration/young_adult_book': `${baseURL}/digital_illustration_young_adult_book.webp`, -'digital_illustration/young_adult_book_2': `${baseURL}/digital_illustration_young_adult_book_2.webp`, +'realistic_image': `${baseURL}realistic_image.webp`, +'digital_illustration': `${baseURL}digital_illustration.webp`, +'realistic_image/b_and_w': `${baseURL}realistic_image_black_&_white.webp`, +'realistic_image/hard_flash': `${baseURL}realistic_image_hard_flash.webp`, +'realistic_image/hdr': `${baseURL}realistic_image_hdr.webp`, +'realistic_image/natural_light': `${baseURL}realistic_image_natural_light.webp`, +'realistic_image/studio_portrait': `${baseURL}realistic_image_studio_portrait.webp`, +'realistic_image/enterprise': `${baseURL}realistic_image_enterprise.webp`, +'realistic_image/motion_blur': `${baseURL}realistic_image_motion_blur.webp`, +'digital_illustration/pixel_art': `${baseURL}digital_illustration_pixel_art.webp`, +'digital_illustration/hand_drawn': `${baseURL}digital_illustration_hand_drawn.webp`, +'digital_illustration/grain': `${baseURL}digital_illustration_grain.webp`, +'digital_illustration/infantile_sketch': `${baseURL}digital_illustration_infantile_sketch.webp`, +'digital_illustration/2d_art_poster': `${baseURL}digital_illustration_2d_art_poster.webp`, +'digital_illustration/handmade_3d': `${baseURL}digital_illustration_handmade_3d.webp`, +'digital_illustration/hand_drawn_outline': `${baseURL}digital_illustration_handdrawn_outline.webp`, +'digital_illustration/engraving_color': `${baseURL}digital_illustration_engraving_color.webp`, +'digital_illustration/2d_art_poster_2': `${baseURL}digital_illustration_2d_artposter_2.webp`, +'vector_illustration': `${baseURL}vector_illustration.svg`, +'vector_illustration/bold_stroke': `${baseURL}vector_illustration_bold_stroke.svg`, +'vector_illustration/chemistry': `${baseURL}vector_illustration_chemistry.svg`, +'vector_illustration/colored_stencil': `${baseURL}vector_illustration_colored_stencil.svg`, +'vector_illustration/contour_pop_art': `${baseURL}vector_illustration_contour_pop_art.svg`, +'vector_illustration/cosmics': `${baseURL}vector_illustration_cosmics.svg`, +'vector_illustration/cutout': `${baseURL}vector_illustration_cutout.svg`, +'vector_illustration/depressive': `${baseURL}vector_illustration_depressive.svg`, +'vector_illustration/editorial': `${baseURL}vector_illustration_editorial.svg`, +'vector_illustration/emotional_flat': `${baseURL}vector_illustration_emotional_flat.svg`, +'vector_illustration/infographical': `${baseURL}vector_illustration_infographical.svg`, +'vector_illustration/marker_outline': `${baseURL}vector_illustration_marker_outline.svg`, +'vector_illustration/mosaic': `${baseURL}vector_illustration_mosaic.svg`, +'vector_illustration/naivector': `${baseURL}vector_illustration_naivector.svg`, +'vector_illustration/roundish_flat': `${baseURL}vector_illustration_roundish_flat.svg`, +'vector_illustration/segmented_colors': `${baseURL}vector_illustration_segmented_colors.svg`, +'vector_illustration/sharp_contrast': `${baseURL}vector_illustration_sharp_contrast.svg`, +'vector_illustration/thin': `${baseURL}vector_illustration_thin.svg`, +'vector_illustration/vector_photo': `${baseURL}vector_illustration_vector_photo.svg`, +'vector_illustration/vivid_shapes': `${baseURL}vector_illustration_vivid_shapes.svg`, +'vector_illustration/engraving': `${baseURL}vector_illustration_engraving.svg`, +'vector_illustration/line_art': `${baseURL}vector_illustration_line_art.svg`, +'vector_illustration/line_circuit': `${baseURL}vector_illustration_line_circuit.svg`, +'vector_illustration/linocut': `${baseURL}vector_illustration_linocut.svg`, +'realistic_image/evening_light': `${baseURL}realistic_image_evening_light.webp`, +'realistic_image/faded_nostalgia': `${baseURL}realistic_image_faded_nostalgia.webp`, +'realistic_image/forest_life': `${baseURL}realistic_image_forest_life.webp`, +'realistic_image/mystic_naturalism': `${baseURL}realistic_image_mystic_naturalism.webp`, +'realistic_image/natural_tones': `${baseURL}realistic_image_natural_tones.webp`, +'realistic_image/organic_calm': `${baseURL}realistic_image_organic_calm.webp`, +'realistic_image/real_life_glow': `${baseURL}realistic_image_real_life_glow.webp`, +'realistic_image/retro_realism': `${baseURL}realistic_image_retro_realism.webp`, +'realistic_image/retro_snapshot': `${baseURL}realistic_image_retro_snapshot.webp`, +'realistic_image/urban_drama': `${baseURL}realistic_image_urban_drama.webp`, +'realistic_image/village_realism': `${baseURL}realistic_image_village_realism.webp`, +'realistic_image/warm_folk': `${baseURL}realistic_image_warm_folk.webp`, +'digital_illustration/antiquarian': `${baseURL}digital_illustration_antiquarian.webp`, +'digital_illustration/bold_fantasy': `${baseURL}digital_illustration_bold_fantasy.webp`, +'digital_illustration/child_book': `${baseURL}digital_illustration_child_book.webp`, +'digital_illustration/child_books': `${baseURL}digital_illustration_child_books.webp`, +'digital_illustration/cover': `${baseURL}digital_illustration_cover.webp`, +'digital_illustration/crosshatch': `${baseURL}digital_illustration_crosshatch.webp`, +'digital_illustration/digital_engraving': `${baseURL}digital_illustration_digital_engraving.webp`, +'digital_illustration/expressionism': `${baseURL}digital_illustration_expressionism.webp`, +'digital_illustration/freehand_details': `${baseURL}digital_illustration_freehand_details.webp`, +'digital_illustration/grain_20': `${baseURL}digital_illustration_grain_20.webp`, +'digital_illustration/graphic_intensity': `${baseURL}digital_illustration_graphic_intensity.webp`, +'digital_illustration/hard_comics': `${baseURL}digital_illustration_hard_comics.webp`, +'digital_illustration/long_shadow': `${baseURL}digital_illustration_long_shadow.webp`, +'digital_illustration/modern_folk': `${baseURL}digital_illustration_modern_folk.webp`, +'digital_illustration/multicolor': `${baseURL}digital_illustration_multicolor.webp`, +'digital_illustration/neon_calm': `${baseURL}digital_illustration_neon_calm.webp`, +'digital_illustration/noir': `${baseURL}digital_illustration_noir.webp`, +'digital_illustration/nostalgic_pastel': `${baseURL}digital_illustration_nostalgic_pastel.webp`, +'digital_illustration/outline_details': `${baseURL}digital_illustration_outline_details.webp`, +'digital_illustration/pastel_gradient': `${baseURL}digital_illustration_pastel_gradient.webp`, +'digital_illustration/pastel_sketch': `${baseURL}digital_illustration_pastel_sketch.webp`, +'digital_illustration/pop_art': `${baseURL}digital_illustration_pop_art.webp`, +'digital_illustration/pop_renaissance': `${baseURL}digital_illustration_pop_renaissance.webp`, +'digital_illustration/street_art': `${baseURL}digital_illustration_street_art.webp`, +'digital_illustration/tablet_sketch': `${baseURL}digital_illustration_tablet_sketch.webp`, +'digital_illustration/urban_glow': `${baseURL}digital_illustration_urban_glow.webp`, +'digital_illustration/urban_sketching': `${baseURL}digital_illustration_urban_sketching.webp`, +'digital_illustration/vanilla_dreams': `${baseURL}digital_illustration_vanilla_dreams.webp`, +'digital_illustration/young_adult_book': `${baseURL}digital_illustration_young_adult_book.webp`, +'digital_illustration/young_adult_book_2': `${baseURL}digital_illustration_young_adult_book_2.webp`, // Icon style thumbnails (using SVG format like vector styles) -'icon/broken_line': `${baseURL}/icon_broken_line.svg`, -'icon/colored_outline': `${baseURL}/icon_colored_outline.svg`, -'icon/colored_shapes': `${baseURL}/icon_colored_shapes.svg`, -'icon/colored_shapes_gradient': `${baseURL}/icon_colored_shapes_gradient.svg`, -'icon/doodle_fill': `${baseURL}/icon_doodle_fill.svg`, -'icon/doodle_offset_fill': `${baseURL}/icon_doodle_offset_fill.svg`, -'icon/offset_fill': `${baseURL}/icon_offset_fill.svg`, -'icon/outline': `${baseURL}/icon_outline.svg`, -'icon/outline_gradient': `${baseURL}/icon_outline_gradient.svg`, -'icon/uneven_fill': `${baseURL}/icon_uneven_fill.svg`, +'icon/broken_line': `${baseURL}icon_broken_line.svg`, +'icon/colored_outline': `${baseURL}icon_colored_outline.svg`, +'icon/colored_shapes': `${baseURL}icon_colored_shapes.svg`, +'icon/colored_shapes_gradient': `${baseURL}icon_colored_shapes_gradient.svg`, +'icon/doodle_fill': `${baseURL}icon_doodle_fill.svg`, +'icon/doodle_offset_fill': `${baseURL}icon_doodle_offset_fill.svg`, +'icon/offset_fill': `${baseURL}icon_offset_fill.svg`, +'icon/outline': `${baseURL}icon_outline.svg`, +'icon/outline_gradient': `${baseURL}icon_outline_gradient.svg`, +'icon/uneven_fill': `${baseURL}icon_uneven_fill.svg`, }) export function getStyleThumbnail( diff --git a/packages/plugin-ai-sticker-generation-web/src/fal-ai/Recraft20b.ts b/packages/plugin-ai-sticker-generation-web/src/fal-ai/Recraft20b.ts index ad30e02f..7a728c99 100644 --- a/packages/plugin-ai-sticker-generation-web/src/fal-ai/Recraft20b.ts +++ b/packages/plugin-ai-sticker-generation-web/src/fal-ai/Recraft20b.ts @@ -2,7 +2,8 @@ import { Icons, CustomAssetSource } from '@imgly/plugin-utils'; import { CommonProviderConfiguration, getPanelId, - createTranslationCallback + createTranslationCallback, + normalizeBaseURL } from '@imgly/plugin-ai-generation-web'; import Recraft20bSchema from './Recraft20b.json'; import CreativeEditorSDK, { AssetResult } from '@cesdk/cesdk-js'; @@ -61,9 +62,11 @@ function getProvider( const falKey = 'fal-ai/recraft/v2/text-to-image'; const modelKey = 'fal-ai/recraft/v2/text-to-sticker'; const styleIconAssetSourceId = `${modelKey}/styles/icon`; - const baseURL = + // Normalize baseURL to ensure exactly one trailing slash + const baseURL = normalizeBaseURL( config.baseURL ?? - 'https://cdn.img.ly/assets/plugins/plugin-ai-image-generation-web/v1/recraft-v3/'; + 'https://cdn.img.ly/assets/plugins/plugin-ai-image-generation-web/v1/recraft-v3/' + ); cesdk.ui.addIconSet('@imgly/plugin/formats', Icons.Formats);