Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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`;
Expand Down
3 changes: 2 additions & 1 deletion packages/plugin-ai-generation-web/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ export {
getThumbnailForVideo,
getLabelFromId,
isAsyncGenerator,
addIconSetOnce
addIconSetOnce,
normalizeBaseURL
} from './utils/utils';

export { checkAiPluginVersion } from './utils/checkAiPluginVersion';
Expand Down
15 changes: 15 additions & 0 deletions packages/plugin-ai-generation-web/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(/\/+$/, '')}/`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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(
Expand Down
Loading