@imgly/plugin-soundstripe-web 0.1.1 → 1.68.0-rc.2

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 CHANGED
@@ -1,210 +1,9 @@
1
- # IMG.LY CE.SDK Plugin Soundstripe
1
+ # @imgly/plugin-soundstripe-web
2
2
 
3
- This plugin provides integration with Soundstripe's audio library, allowing you to search and use Soundstripe audio tracks directly within CE.SDK.
3
+ Soundstripe asset source plugin for the CE.SDK editor
4
4
 
5
- ## Features
6
-
7
- - 🎵 Search and browse Soundstripe's audio library directly in CE.SDK
8
- - 🔄 Automatic refresh of expired audio URIs
9
- - 📦 Seamless integration with CE.SDK's asset management system
10
- - 🎨 Artist credits and metadata support
11
-
12
- ## Installation
13
-
14
- You can install the plugin via npm or a compatible package manager. Use the following commands to install the package:
15
-
16
- ```bash
17
- pnpm add @imgly/plugin-soundstripe-web
18
- # or
19
- yarn add @imgly/plugin-soundstripe-web
20
- # or
21
- npm install @imgly/plugin-soundstripe-web
22
- ```
23
-
24
- ## Prerequisites
25
-
26
- ### 1. Soundstripe API Key
27
- You'll need a valid Soundstripe API key. You can obtain one from [Soundstripe](https://soundstripe.com/).
28
-
29
- ### 2. Proxy Server Setup (Required)
30
- **⚠️ Important:** Soundstripe's API requires server-side proxy implementation for production use. Direct browser access to Soundstripe's API is intended for development only.
31
-
32
- You must set up a proxy server as described in [Soundstripe's integration guide](https://docs.soundstripe.com/docs/integrating-soundstripes-content-into-your-application). This proxy will:
33
- - Handle authentication securely
34
- - Prevent exposing your API key in client-side code
35
- - Ensure CORS compliance
36
- - Maintain stable API access
37
-
38
- ## Usage
39
-
40
- ### Basic Setup
41
-
42
- ```typescript
43
- import CreativeEditorSDK from '@cesdk/cesdk-js';
44
- import SoundstripePlugin from '@imgly/plugin-soundstripe-web';
45
-
46
- const config = {
47
- license: '<your-license-here>'
48
- };
49
-
50
- const cesdk = await CreativeEditorSDK.create(container, config);
51
- await cesdk.addDefaultAssetSources();
52
- await cesdk.addDemoAssetSources({ sceneMode: 'Design' });
53
-
54
- // Add the Soundstripe plugin
55
- await cesdk.addPlugin(
56
- SoundstripePlugin({
57
- apiKey: 'your-soundstripe-api-key'
58
- })
59
- );
60
-
61
- // Verify the asset source is available
62
- console.log(
63
- `Available asset sources: ${cesdk.engine.asset
64
- .findAllSources()
65
- .join(', ')}`
66
- );
67
-
68
- await cesdk.createDesignScene();
69
- ```
70
-
71
- ### Adding Soundstripe to Audio Asset Library
72
-
73
- To make Soundstripe appear in the Audio asset library panel, update the audio entry to include the Soundstripe source:
74
-
75
- ```typescript
76
- // After adding the Soundstripe plugin
77
- await cesdk.addPlugin(
78
- SoundstripePlugin({
79
- apiKey: 'your-soundstripe-api-key'
80
- })
81
- );
82
-
83
- // Get the existing audio entry
84
- const audioEntry = cesdk.ui.getAssetLibraryEntry('ly.img.audio');
85
-
86
- // Add Soundstripe to the audio sources
87
- cesdk.ui.updateAssetLibraryEntry('ly.img.audio', {
88
- sourceIds: [...audioEntry.sourceIds, 'ly.img.audio.soundstripe']
89
- });
90
-
91
- // Now Soundstripe will appear in the Audio asset panel
92
- ```
93
-
94
- ### Automatic URI Refresh
95
-
96
- Soundstripe MP3 file URIs expire after a certain time period. This plugin automatically handles URI refresh to ensure your audio tracks continue to play without interruption. The refresh happens:
97
- - When a scene is loaded
98
- - When the block selection changes
99
- - Before playback if URIs are expired
100
-
101
- You can also manually trigger a refresh using the exported utility function:
102
-
103
- ```typescript
104
- import { refreshSoundstripeAudioURIs } from '@imgly/plugin-soundstripe-web';
105
-
106
- // Manually refresh all Soundstripe audio URIs in the current scene
107
- await refreshSoundstripeAudioURIs(cesdk.engine, { apiKey });
108
-
109
- // Or when using a proxy server
110
- await refreshSoundstripeAudioURIs(cesdk.engine, { baseUrl: 'https://your-proxy.com' });
111
- ```
112
-
113
- ## Configuration
114
-
115
- ### Plugin Configuration
116
-
117
- The plugin can be configured in two ways depending on your setup:
118
-
119
- #### Option 1: Direct API Access (Development)
120
- ```typescript
121
- import SoundstripePlugin from '@imgly/plugin-soundstripe-web';
122
-
123
- await cesdk.addPlugin(SoundstripePlugin({
124
- apiKey: 'your-soundstripe-api-key' // Your Soundstripe API key
125
- }))
126
- ```
127
-
128
- #### Option 2: Proxy Server (Production - Recommended)
129
- ```typescript
130
- import SoundstripePlugin from '@imgly/plugin-soundstripe-web';
131
-
132
- await cesdk.addPlugin(SoundstripePlugin({
133
- baseUrl: 'https://your-proxy-server.com' // Your proxy server URL
134
- }))
135
- ```
136
-
137
- #### Configuration Parameters
138
-
139
- | Parameter | Type | Required | Description |
140
- |-----------|------|----------|-------------|
141
- | `apiKey` | `string` | Conditional | Your Soundstripe API key. Required when using direct API access (Option 1). |
142
- | `baseUrl` | `string` | Conditional | Your proxy server base URL. Required when using proxy server (Option 2). |
143
-
144
- **Note:** Either `apiKey` or `baseUrl` must be provided. You cannot omit both parameters.
145
-
146
- ### Proxy Configuration Example
147
-
148
- For production environments, configure your proxy server to handle Soundstripe API requests:
149
-
150
- ```javascript
151
- // Example Node.js proxy endpoint
152
- app.use('/api/soundstripe', async (req, res) => {
153
- const response = await fetch(`https://api.soundstripe.com/v1${req.path}`, {
154
- headers: {
155
- 'Authorization': `Bearer ${process.env.SOUNDSTRIPE_API_KEY}`,
156
- 'Accept': 'application/vnd.api+json',
157
- 'Content-Type': 'application/vnd.api+json'
158
- }
159
- });
160
-
161
- const data = await response.json();
162
- res.json(data);
163
- });
164
- ```
165
-
166
- Then modify the plugin to use your proxy endpoint instead of direct API calls.
167
-
168
- ## API Reference
169
-
170
- ### `SoundstripePlugin(configuration)`
171
-
172
- Creates a new Soundstripe plugin instance.
173
-
174
- #### Parameters
175
- - `configuration.apiKey` (string, optional): Your Soundstripe API key. Required when using direct API access.
176
- - `configuration.baseUrl` (string, optional): Your proxy server base URL. Required when using proxy server.
177
-
178
- **Note:** Either `apiKey` or `baseUrl` must be provided.
179
-
180
- #### Returns
181
- A plugin object compatible with CE.SDK's plugin system
182
-
183
- ### `refreshSoundstripeAudioURIs(engine, config)`
184
-
185
- Manually refreshes all Soundstripe audio URIs in the current scene.
186
-
187
- #### Parameters
188
- - `engine` (CreativeEngine, required): The CE.SDK engine instance
189
- - `config` (object, optional): Configuration object with the following properties:
190
- - `apiKey` (string, optional): Your Soundstripe API key. Optional when using proxy server.
191
- - `baseUrl` (string, optional): Your proxy server base URL
192
-
193
- #### Returns
194
- Promise<void>
195
-
196
- ## How It Works
197
-
198
- 1. **Asset Discovery**: The plugin registers as an asset source (`ly.img.audio.soundstripe`) in CE.SDK
199
- 2. **Search Integration**: Users can search Soundstripe's library through CE.SDK's asset panel
200
- 3. **Metadata Storage**: When an audio track is added, the plugin stores the Soundstripe song ID as metadata
201
- 4. **Automatic Refresh**: The plugin monitors for expired URIs and automatically fetches fresh ones using the stored song IDs
202
- 5. **Seamless Playback**: Users experience uninterrupted audio playback even when URIs expire
5
+ For documentation, visit: https://img.ly/docs/cesdk
203
6
 
204
7
  ## License
205
8
 
206
- See LICENSE.md file for licensing information.
207
-
208
- ## Support
209
-
210
- For support, please contact support@img.ly
9
+ This plugin is part of the IMG.LY plugin ecosystem for CreativeEditor SDK.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  import { type SoundstripePluginConfiguration } from './plugin';
2
2
  declare const Plugin: (pluginConfiguration: SoundstripePluginConfiguration) => {
3
- initialize: (context: import("@cesdk/cesdk-js").EnginePluginContext & {
4
- cesdk?: import("@cesdk/cesdk-js").default;
5
- }) => void;
3
+ initialize: (context: import("@cesdk/cesdk-js").EditorPluginContext) => void | Promise<void>;
6
4
  name: string;
7
5
  version: string;
8
6
  };
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- var A="@imgly/plugin-soundstripe-web";var P={assets:[],currentPage:1,nextPage:void 0,total:0};function b(r,c){let{apiKey:n,baseUrl:a}=c,l=async(e,t,i)=>{let d=a||"https://api.soundstripe.com",s=new URL(`${d}/v1/songs`);e&&s.searchParams.set("filter[q]",e),t&&s.searchParams.set("page[number]",t.toString()),i&&s.searchParams.set("page[size]",i.toString());let m={Accept:"application/vnd.api+json","Content-Type":"application/vnd.api+json"};n&&(console.warn("Using direct Soundstripe API access, this is not recommended for production use. Instead, consider using a proxy server."),m.Authorization=`Bearer ${n}`);let p=await fetch(s.toString(),{headers:m});if(!p.ok)throw new Error(`Soundstripe API error: ${p.status} ${p.statusText}`);return p.json()},o=(e,t)=>{let i=t.find(s=>s.type==="audio_files"&&s.id===e.relationships.audio_files.data[0]?.id);if(!i?.attributes.versions?.mp3)return;let d=t.find(s=>s.type==="artists"&&s.id===e.relationships.artists.data[0]?.id);return{id:e.id,label:e.attributes.title,meta:{mimeType:"audio/mp3",uri:i.attributes.versions.mp3,thumbUri:d?.attributes?.image,previewUri:i.attributes.versions.mp3,filename:e.attributes.title,blockType:"//ly.img.ubq/audio",duration:i.attributes.duration.toString()},credits:d?.attributes?.name?{name:d.attributes.name}:void 0}},f=(e,t,i)=>e<Math.ceil(i/t)?e+1:void 0;return{id:"ly.img.audio.soundstripe",credits:{name:"Soundstripe",url:"https://soundstripe.com/"},license:{name:"Soundstripe",url:"https://www.soundstripe.com/music-licensing"},applyAsset:async e=>{let t=await r.asset.defaultApplyAsset(e);if(t)return r.block.setMetadata(t,"ly.img.audio.soundstripe.songId",e.id),t},applyAssetToBlock:async(e,t)=>{await r.asset.defaultApplyAssetToBlock(e,t),r.block.setMetadata(t,"ly.img.audio.soundstripe.songId",e.id)},async findAssets(e){try{let t=await l(e.query,e.page,e.perPage);return{assets:t.data.map(s=>o(s,t.included)).filter(s=>s!==void 0),currentPage:e.page,nextPage:f(e.page,e.perPage,t.links.meta.total_count),total:t.links.meta.total_count}}catch{return P}}}}var y=b;async function g(r,c={}){let{apiKey:n,baseUrl:a}=c,l=async o=>{let f=a||"https://api.soundstripe.com",u=new URL(`${f}/v1/songs/${o}`),e={Accept:"application/vnd.api+json","Content-Type":"application/vnd.api+json"};n&&(console.warn("Using direct Soundstripe API access for refresh, this is not recommended for production use. Instead, consider using a proxy server."),e.Authorization=`Bearer ${n}`);let t=await fetch(u.toString(),{headers:e});if(!t.ok)throw new Error(`Soundstripe API error: ${t.status} ${t.statusText}`);return t.json()};try{if(r.scene.get()===null)return;let f=r.block.findByType("audio");await Promise.allSettled(f.map(async u=>{let e=r.block.getString(u,"audio/fileURI");if(e&&e.includes("soundstripe.com"))try{let i=r.block.getMetadata(u,"ly.img.audio.soundstripe.songId");if(!i){console.warn(`No metadata found for Soundstripe audio block ${u}`);return}let s=await l(i),p=s.included.find(S=>S.type==="audio_files"&&S.id===s.data.relationships.audio_files.data[0]?.id)?.attributes.versions?.mp3;p&&p!==e&&r.block.setString(u,"audio/fileURI",p)}catch(i){console.warn(`Failed to refresh URI for Soundstripe audio block ${u}:`,i)}}))}catch(o){console.warn("Failed to refresh Soundstripe audio URIs:",o)}}var h=r=>{let{apiKey:c,baseUrl:n}=r;if(!c&&!n)throw new Error("Soundstripe Plugin: Either apiKey or baseUrl must be provided");return{async initialize({engine:a,cesdk:l}){try{let o=y(a,{apiKey:c,baseUrl:n});a.asset.addSource(o),a.scene.onActiveChanged(()=>{g(a,{apiKey:c,baseUrl:n})}),l&&l.setTranslations({en:{[`libraries.${o.id}.label`]:"Soundstripe"}})}catch(o){throw console.error("\u{1F3B5} Soundstripe Plugin: Initialization failed:",o),o}}}};var U=r=>({name:A,version:"0.1.1",...h(r)}),$=U;export{$ as default,g as refreshSoundstripeAudioURIs};
1
+ var A="@imgly/plugin-soundstripe-web";var b={assets:[],currentPage:1,nextPage:void 0,total:0};function P(r,c){let{apiKey:o,baseUrl:a}=c,l=async(e,t,i)=>{let d=a||"https://api.soundstripe.com",s=new URL(`${d}/v1/songs`);e&&s.searchParams.set("filter[q]",e),t&&s.searchParams.set("page[number]",t.toString()),i&&s.searchParams.set("page[size]",i.toString());let g={Accept:"application/vnd.api+json","Content-Type":"application/vnd.api+json"};o&&(console.warn("Using direct Soundstripe API access, this is not recommended for production use. Instead, consider using a proxy server."),g.Authorization=`Bearer ${o}`);let p=await fetch(s.toString(),{headers:g});if(!p.ok)throw new Error(`Soundstripe API error: ${p.status} ${p.statusText}`);return p.json()},n=(e,t)=>{let i=t.find(s=>s.type==="audio_files"&&s.id===e.relationships.audio_files.data[0]?.id);if(!i?.attributes.versions?.mp3)return;let d=t.find(s=>s.type==="artists"&&s.id===e.relationships.artists.data[0]?.id);return{id:e.id,label:e.attributes.title,meta:{mimeType:"audio/mp3",uri:i.attributes.versions.mp3,thumbUri:d?.attributes?.image,previewUri:i.attributes.versions.mp3,filename:e.attributes.title,blockType:"//ly.img.ubq/audio",duration:i.attributes.duration.toString()},credits:d?.attributes?.name?{name:d.attributes.name}:void 0}},f=(e,t,i)=>e<Math.ceil(i/t)?e+1:void 0;return{id:"ly.img.audio.soundstripe",credits:{name:"Soundstripe",url:"https://soundstripe.com/"},license:{name:"Soundstripe",url:"https://www.soundstripe.com/music-licensing"},applyAsset:async e=>{let t=await r.asset.defaultApplyAsset(e);if(t)return r.block.setMetadata(t,"ly.img.audio.soundstripe.songId",e.id),t},applyAssetToBlock:async(e,t)=>{await r.asset.defaultApplyAssetToBlock(e,t),r.block.setMetadata(t,"ly.img.audio.soundstripe.songId",e.id)},async findAssets(e){try{let t=await l(e.query,e.page,e.perPage);return{assets:t.data.map(s=>n(s,t.included)).filter(s=>s!==void 0),currentPage:e.page,nextPage:f(e.page,e.perPage,t.links.meta.total_count),total:t.links.meta.total_count}}catch{return b}}}}var y=P;async function m(r,c={}){let{apiKey:o,baseUrl:a}=c,l=async n=>{let f=a||"https://api.soundstripe.com",u=new URL(`${f}/v1/songs/${n}`),e={Accept:"application/vnd.api+json","Content-Type":"application/vnd.api+json"};o&&(console.warn("Using direct Soundstripe API access for refresh, this is not recommended for production use. Instead, consider using a proxy server."),e.Authorization=`Bearer ${o}`);let t=await fetch(u.toString(),{headers:e});if(!t.ok)throw new Error(`Soundstripe API error: ${t.status} ${t.statusText}`);return t.json()};try{if(r.scene.get()===null)return;let f=r.block.findByType("audio");await Promise.allSettled(f.map(async u=>{let e=r.block.getString(u,"audio/fileURI");if(e&&e.includes("soundstripe.com"))try{let i=r.block.getMetadata(u,"ly.img.audio.soundstripe.songId");if(!i){console.warn(`No metadata found for Soundstripe audio block ${u}`);return}let s=await l(i),p=s.included.find(S=>S.type==="audio_files"&&S.id===s.data.relationships.audio_files.data[0]?.id)?.attributes.versions?.mp3;p&&p!==e&&r.block.setString(u,"audio/fileURI",p)}catch(i){console.warn(`Failed to refresh URI for Soundstripe audio block ${u}:`,i)}}))}catch(n){console.warn("Failed to refresh Soundstripe audio URIs:",n)}}var h=r=>{let{apiKey:c,baseUrl:o}=r;if(!c&&!o)throw new Error("Soundstripe Plugin: Either apiKey or baseUrl must be provided");return{async initialize({engine:a,cesdk:l}){let n=y(a,{apiKey:c,baseUrl:o});a.asset.addSource(n),a.scene.onActiveChanged(()=>{m(a,{apiKey:c,baseUrl:o})}),l&&l.setTranslations({en:{[`libraries.${n.id}.label`]:"Soundstripe"}})}}};var U=r=>({name:A,version:"1.68.0-rc.2",...h(r)}),$=U;export{$ as default,m as refreshSoundstripeAudioURIs};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/constants.ts", "../src/soundstripe-asset-source.ts", "../src/refresh-audio-uris.ts", "../src/plugin.ts", "../src/index.ts"],
4
- "sourcesContent": ["export const PLUGIN_ID = '@imgly/plugin-soundstripe-web';\n", "import {\n AssetQueryData,\n AssetResult,\n AssetsQueryResult,\n AssetSource,\n CreativeEngine\n} from '@cesdk/cesdk-js';\nimport {\n SoundstripeApiResponse,\n SoundstripeSong,\n SoundstripeArtist,\n SoundstripeAudioFile\n} from './types';\nimport { refreshSoundstripeAudioURIs } from './refresh-audio-uris';\n\nconst EMPTY_RESULT: AssetsQueryResult = {\n assets: [],\n currentPage: 1,\n nextPage: undefined,\n total: 0\n};\n\ninterface SoundstripeSourceConfig {\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction createSoundstripeSource(\n engine: CreativeEngine,\n config: SoundstripeSourceConfig\n): AssetSource {\n const { apiKey, baseUrl } = config;\n const fetchSoundstripeAssets = async (\n query?: string,\n page?: number,\n perPage?: number\n ): Promise<SoundstripeApiResponse> => {\n const apiBaseUrl = baseUrl || 'https://api.soundstripe.com';\n const url = new URL(`${apiBaseUrl}/v1/songs`);\n\n if (query) url.searchParams.set('filter[q]', query);\n if (page) url.searchParams.set('page[number]', page.toString());\n if (perPage) url.searchParams.set('page[size]', perPage.toString());\n\n const headers: Record<string, string> = {\n Accept: 'application/vnd.api+json',\n 'Content-Type': 'application/vnd.api+json'\n };\n\n // Only add Authorization header if apiKey is provided (not needed for proxy)\n if (apiKey) {\n console.warn(\n 'Using direct Soundstripe API access, this is not recommended for production use. Instead, consider using a proxy server.'\n );\n headers.Authorization = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(url.toString(), { headers });\n\n if (!response.ok) {\n throw new Error(\n `Soundstripe API error: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n };\n\n const formatAsset = (\n audio: SoundstripeSong,\n relationships: Array<SoundstripeArtist | SoundstripeAudioFile>\n ): AssetResult | undefined => {\n const audioFile = relationships.find(\n (item): item is SoundstripeAudioFile =>\n item.type === 'audio_files' &&\n item.id === audio.relationships.audio_files.data[0]?.id\n );\n\n if (!audioFile?.attributes.versions?.mp3) {\n return undefined;\n }\n\n const firstAuthor = relationships.find(\n (item): item is SoundstripeArtist =>\n item.type === 'artists' &&\n item.id === audio.relationships.artists.data[0]?.id\n );\n\n return {\n id: audio.id,\n label: audio.attributes.title,\n meta: {\n mimeType: 'audio/mp3',\n uri: audioFile.attributes.versions.mp3,\n thumbUri: firstAuthor?.attributes?.image,\n previewUri: audioFile.attributes.versions.mp3,\n filename: audio.attributes.title,\n blockType: '//ly.img.ubq/audio',\n duration: audioFile.attributes.duration.toString()\n },\n credits: firstAuthor?.attributes?.name\n ? {\n name: firstAuthor.attributes.name\n }\n : undefined\n };\n };\n\n const calculateNextPage = (\n page: number,\n pageSize: number,\n resultCount: number\n ) => {\n const hasNextPage = page < Math.ceil(resultCount / pageSize);\n return hasNextPage ? page + 1 : undefined;\n };\n\n const SoundstripeSource: AssetSource = {\n id: 'ly.img.audio.soundstripe',\n credits: {\n name: 'Soundstripe',\n url: 'https://soundstripe.com/'\n },\n license: {\n name: 'Soundstripe',\n url: 'https://www.soundstripe.com/music-licensing'\n },\n applyAsset: async (assetResult) => {\n const blockId = await engine.asset.defaultApplyAsset(assetResult);\n if (!blockId) return;\n engine.block.setMetadata(\n blockId,\n 'ly.img.audio.soundstripe.songId',\n assetResult.id\n );\n return blockId;\n },\n applyAssetToBlock: async (assetResult, blockId) => {\n await engine.asset.defaultApplyAssetToBlock(assetResult, blockId);\n engine.block.setMetadata(\n blockId,\n 'ly.img.audio.soundstripe.songId',\n assetResult.id\n );\n },\n async findAssets(queryData: AssetQueryData): Promise<AssetsQueryResult> {\n try {\n const response = await fetchSoundstripeAssets(\n queryData.query,\n queryData.page,\n queryData.perPage\n );\n\n const assets = response.data\n .map((song) => formatAsset(song, response.included))\n .filter((asset): asset is AssetResult => asset !== undefined);\n\n const result = {\n assets,\n currentPage: queryData.page,\n nextPage: calculateNextPage(\n queryData.page,\n queryData.perPage,\n response.links.meta.total_count\n ),\n total: response.links.meta.total_count\n };\n\n return result;\n } catch (error) {\n return EMPTY_RESULT;\n }\n }\n };\n\n return SoundstripeSource;\n}\n\nexport default createSoundstripeSource;\n", "import { CreativeEngine } from '@cesdk/cesdk-js';\nimport { SoundstripeSingleAssetResponse, SoundstripeAudioFile } from './types';\n\ninterface RefreshAudioConfig {\n apiKey?: string;\n baseUrl?: string;\n}\n\n/**\n * Refreshes expired Soundstripe audio URIs in the current scene\n * @param engine - The CESDK engine instance\n * @param config - Configuration object with apiKey and baseUrl\n */\nexport async function refreshSoundstripeAudioURIs(\n engine: CreativeEngine,\n config: RefreshAudioConfig = {}\n): Promise<void> {\n const { apiKey, baseUrl } = config;\n const fetchSoundstripeSong = async (\n songId: string\n ): Promise<SoundstripeSingleAssetResponse> => {\n const apiBaseUrl = baseUrl || 'https://api.soundstripe.com';\n const url = new URL(`${apiBaseUrl}/v1/songs/${songId}`);\n\n const headers: Record<string, string> = {\n Accept: 'application/vnd.api+json',\n 'Content-Type': 'application/vnd.api+json'\n };\n\n // Only add Authorization header if apiKey is provided (not needed for proxy)\n if (apiKey) {\n console.warn(\n 'Using direct Soundstripe API access for refresh, this is not recommended for production use. Instead, consider using a proxy server.'\n );\n headers.Authorization = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(url.toString(), { headers });\n\n if (!response.ok) {\n throw new Error(\n `Soundstripe API error: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n };\n\n try {\n const scene = engine.scene.get();\n if (scene === null) {\n return;\n }\n\n const audioBlocks = engine.block.findByType('audio');\n\n await Promise.allSettled(\n audioBlocks.map(async (blockId) => {\n const oldUri = engine.block.getString(blockId, 'audio/fileURI');\n const isSoundStripe = oldUri && oldUri.includes('soundstripe.com');\n if (!isSoundStripe) {\n return;\n }\n try {\n const metadata = engine.block.getMetadata(\n blockId,\n 'ly.img.audio.soundstripe.songId'\n );\n if (!metadata) {\n console.warn(\n `No metadata found for Soundstripe audio block ${blockId}`\n );\n return;\n }\n\n const songId = metadata;\n const response = await fetchSoundstripeSong(songId);\n\n const audioFile = response.included.find(\n (item): item is SoundstripeAudioFile =>\n item.type === 'audio_files' &&\n item.id === response.data.relationships.audio_files.data[0]?.id\n );\n const newUri = audioFile?.attributes.versions?.mp3;\n\n if (newUri && newUri !== oldUri) {\n engine.block.setString(blockId, 'audio/fileURI', newUri);\n }\n } catch (error) {\n console.warn(\n `Failed to refresh URI for Soundstripe audio block ${blockId}:`,\n error\n );\n }\n })\n );\n } catch (error) {\n console.warn('Failed to refresh Soundstripe audio URIs:', error);\n }\n}\n", "import { CreativeEngine, type EditorPlugin } from '@cesdk/cesdk-js';\nimport createSoundstripeSource from './soundstripe-asset-source';\nimport { refreshSoundstripeAudioURIs } from './refresh-audio-uris';\n\nexport const SoundstripePlugin = (\n pluginConfiguration: SoundstripePluginConfiguration\n): Omit<EditorPlugin, 'name' | 'version'> => {\n const { apiKey, baseUrl } = pluginConfiguration;\n\n // Validate configuration: either apiKey (for direct API) or baseUrl (for proxy) must be provided\n if (!apiKey && !baseUrl) {\n throw new Error('Soundstripe Plugin: Either apiKey or baseUrl must be provided');\n }\n\n return {\n async initialize({ engine, cesdk }) {\n try {\n const soundstripeSource = createSoundstripeSource(\n engine as CreativeEngine,\n { apiKey, baseUrl }\n );\n engine.asset.addSource(soundstripeSource);\n\n // Refresh all soundstripe urls when a scene is loaded\n engine.scene.onActiveChanged(() => {\n refreshSoundstripeAudioURIs(engine as CreativeEngine, { apiKey, baseUrl });\n });\n if (cesdk) {\n cesdk.setTranslations({\n en: {\n [`libraries.${soundstripeSource.id}.label`]: 'Soundstripe'\n }\n });\n }\n } catch (error) {\n console.error('\uD83C\uDFB5 Soundstripe Plugin: Initialization failed:', error);\n throw error;\n }\n }\n };\n};\n\nexport interface SoundstripePluginConfiguration {\n apiKey?: string; // Optional API key (required when using direct API access)\n baseUrl?: string; // Optional base URL for proxy server (required when using proxy)\n}\n", "import { PLUGIN_ID } from './constants';\nimport {\n SoundstripePlugin,\n type SoundstripePluginConfiguration\n} from './plugin';\n\nconst Plugin = (pluginConfiguration: SoundstripePluginConfiguration) => ({\n name: PLUGIN_ID,\n version: PLUGIN_VERSION,\n ...SoundstripePlugin(pluginConfiguration)\n});\n\nexport default Plugin;\nexport type { SoundstripePluginConfiguration };\nexport { refreshSoundstripeAudioURIs } from './refresh-audio-uris';\n"],
5
- "mappings": "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",
6
- "names": ["PLUGIN_ID", "EMPTY_RESULT", "createSoundstripeSource", "engine", "config", "apiKey", "baseUrl", "fetchSoundstripeAssets", "query", "page", "perPage", "apiBaseUrl", "url", "headers", "response", "formatAsset", "audio", "relationships", "audioFile", "item", "firstAuthor", "calculateNextPage", "pageSize", "resultCount", "assetResult", "blockId", "queryData", "song", "asset", "soundstripe_asset_source_default", "refreshSoundstripeAudioURIs", "engine", "config", "apiKey", "baseUrl", "fetchSoundstripeSong", "songId", "apiBaseUrl", "url", "headers", "response", "audioBlocks", "blockId", "oldUri", "metadata", "newUri", "item", "error", "SoundstripePlugin", "pluginConfiguration", "apiKey", "baseUrl", "engine", "cesdk", "soundstripeSource", "soundstripe_asset_source_default", "refreshSoundstripeAudioURIs", "error", "Plugin", "pluginConfiguration", "PLUGIN_ID", "SoundstripePlugin", "src_default"]
4
+ "sourcesContent": ["export const PLUGIN_ID = '@imgly/plugin-soundstripe-web';\n", "import {\n AssetQueryData,\n AssetResult,\n AssetsQueryResult,\n AssetSource,\n CreativeEngine\n} from '@cesdk/cesdk-js';\nimport {\n SoundstripeApiResponse,\n SoundstripeSong,\n SoundstripeArtist,\n SoundstripeAudioFile\n} from './types';\n\nconst EMPTY_RESULT: AssetsQueryResult = {\n assets: [],\n currentPage: 1,\n nextPage: undefined,\n total: 0\n};\n\ninterface SoundstripeSourceConfig {\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction createSoundstripeSource(\n engine: CreativeEngine,\n config: SoundstripeSourceConfig\n): AssetSource {\n const { apiKey, baseUrl } = config;\n const fetchSoundstripeAssets = async (\n query?: string,\n page?: number,\n perPage?: number\n ): Promise<SoundstripeApiResponse> => {\n const apiBaseUrl = baseUrl || 'https://api.soundstripe.com';\n const url = new URL(`${apiBaseUrl}/v1/songs`);\n\n if (query) url.searchParams.set('filter[q]', query);\n if (page) url.searchParams.set('page[number]', page.toString());\n if (perPage) url.searchParams.set('page[size]', perPage.toString());\n\n const headers: Record<string, string> = {\n Accept: 'application/vnd.api+json',\n 'Content-Type': 'application/vnd.api+json'\n };\n\n // Only add Authorization header if apiKey is provided (not needed for proxy)\n if (apiKey) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Using direct Soundstripe API access, this is not recommended for production use. Instead, consider using a proxy server.'\n );\n headers.Authorization = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(url.toString(), { headers });\n\n if (!response.ok) {\n throw new Error(\n `Soundstripe API error: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n };\n\n const formatAsset = (\n audio: SoundstripeSong,\n relationships: Array<SoundstripeArtist | SoundstripeAudioFile>\n ): AssetResult | undefined => {\n const audioFile = relationships.find(\n (item): item is SoundstripeAudioFile =>\n item.type === 'audio_files' &&\n item.id === audio.relationships.audio_files.data[0]?.id\n );\n\n if (!audioFile?.attributes.versions?.mp3) {\n return undefined;\n }\n\n const firstAuthor = relationships.find(\n (item): item is SoundstripeArtist =>\n item.type === 'artists' &&\n item.id === audio.relationships.artists.data[0]?.id\n );\n\n return {\n id: audio.id,\n label: audio.attributes.title,\n meta: {\n mimeType: 'audio/mp3',\n uri: audioFile.attributes.versions.mp3,\n thumbUri: firstAuthor?.attributes?.image,\n previewUri: audioFile.attributes.versions.mp3,\n filename: audio.attributes.title,\n blockType: '//ly.img.ubq/audio',\n duration: audioFile.attributes.duration.toString()\n },\n credits: firstAuthor?.attributes?.name\n ? {\n name: firstAuthor.attributes.name\n }\n : undefined\n };\n };\n\n const calculateNextPage = (\n page: number,\n pageSize: number,\n resultCount: number\n ) => {\n const hasNextPage = page < Math.ceil(resultCount / pageSize);\n return hasNextPage ? page + 1 : undefined;\n };\n\n const SoundstripeSource: AssetSource = {\n id: 'ly.img.audio.soundstripe',\n credits: {\n name: 'Soundstripe',\n url: 'https://soundstripe.com/'\n },\n license: {\n name: 'Soundstripe',\n url: 'https://www.soundstripe.com/music-licensing'\n },\n applyAsset: async (assetResult) => {\n const blockId = await engine.asset.defaultApplyAsset(assetResult);\n if (!blockId) return;\n engine.block.setMetadata(\n blockId,\n 'ly.img.audio.soundstripe.songId',\n assetResult.id\n );\n return blockId;\n },\n applyAssetToBlock: async (assetResult, blockId) => {\n await engine.asset.defaultApplyAssetToBlock(assetResult, blockId);\n engine.block.setMetadata(\n blockId,\n 'ly.img.audio.soundstripe.songId',\n assetResult.id\n );\n },\n async findAssets(queryData: AssetQueryData): Promise<AssetsQueryResult> {\n try {\n const response = await fetchSoundstripeAssets(\n queryData.query,\n queryData.page,\n queryData.perPage\n );\n\n const assets = response.data\n .map((song) => formatAsset(song, response.included))\n .filter((asset): asset is AssetResult => asset !== undefined);\n\n const result = {\n assets,\n currentPage: queryData.page,\n nextPage: calculateNextPage(\n queryData.page,\n queryData.perPage,\n response.links.meta.total_count\n ),\n total: response.links.meta.total_count\n };\n\n return result;\n } catch (error) {\n return EMPTY_RESULT;\n }\n }\n };\n\n return SoundstripeSource;\n}\n\nexport default createSoundstripeSource;\n", "import { CreativeEngine } from '@cesdk/cesdk-js';\nimport { SoundstripeSingleAssetResponse, SoundstripeAudioFile } from './types';\n\ninterface RefreshAudioConfig {\n apiKey?: string;\n baseUrl?: string;\n}\n\n/**\n * Refreshes expired Soundstripe audio URIs in the current scene\n * @param engine - The CESDK engine instance\n * @param config - Configuration object with apiKey and baseUrl\n */\nexport async function refreshSoundstripeAudioURIs(\n engine: CreativeEngine,\n config: RefreshAudioConfig = {}\n): Promise<void> {\n const { apiKey, baseUrl } = config;\n const fetchSoundstripeSong = async (\n songId: string\n ): Promise<SoundstripeSingleAssetResponse> => {\n const apiBaseUrl = baseUrl || 'https://api.soundstripe.com';\n const url = new URL(`${apiBaseUrl}/v1/songs/${songId}`);\n\n const headers: Record<string, string> = {\n Accept: 'application/vnd.api+json',\n 'Content-Type': 'application/vnd.api+json'\n };\n\n // Only add Authorization header if apiKey is provided (not needed for proxy)\n if (apiKey) {\n // eslint-disable-next-line no-console\n console.warn(\n 'Using direct Soundstripe API access for refresh, this is not recommended for production use. Instead, consider using a proxy server.'\n );\n headers.Authorization = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(url.toString(), { headers });\n\n if (!response.ok) {\n throw new Error(\n `Soundstripe API error: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n };\n\n try {\n const scene = engine.scene.get();\n if (scene === null) {\n return;\n }\n\n const audioBlocks = engine.block.findByType('audio');\n\n await Promise.allSettled(\n audioBlocks.map(async (blockId) => {\n const oldUri = engine.block.getString(blockId, 'audio/fileURI');\n const isSoundStripe = oldUri && oldUri.includes('soundstripe.com');\n if (!isSoundStripe) {\n return;\n }\n try {\n const metadata = engine.block.getMetadata(\n blockId,\n 'ly.img.audio.soundstripe.songId'\n );\n if (!metadata) {\n // eslint-disable-next-line no-console\n console.warn(\n `No metadata found for Soundstripe audio block ${blockId}`\n );\n return;\n }\n\n const songId = metadata;\n const response = await fetchSoundstripeSong(songId);\n\n const audioFile = response.included.find(\n (item): item is SoundstripeAudioFile =>\n item.type === 'audio_files' &&\n item.id === response.data.relationships.audio_files.data[0]?.id\n );\n const newUri = audioFile?.attributes.versions?.mp3;\n\n if (newUri && newUri !== oldUri) {\n engine.block.setString(blockId, 'audio/fileURI', newUri);\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn(\n `Failed to refresh URI for Soundstripe audio block ${blockId}:`,\n error\n );\n }\n })\n );\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn('Failed to refresh Soundstripe audio URIs:', error);\n }\n}\n", "import { CreativeEngine, type EditorPlugin } from '@cesdk/cesdk-js';\nimport createSoundstripeSource from './soundstripe-asset-source';\nimport { refreshSoundstripeAudioURIs } from './refresh-audio-uris';\n\nexport const SoundstripePlugin = (\n pluginConfiguration: SoundstripePluginConfiguration\n): Omit<EditorPlugin, 'name' | 'version'> => {\n const { apiKey, baseUrl } = pluginConfiguration;\n\n // Validate configuration: either apiKey (for direct API) or baseUrl (for proxy) must be provided\n if (!apiKey && !baseUrl) {\n throw new Error(\n 'Soundstripe Plugin: Either apiKey or baseUrl must be provided'\n );\n }\n\n return {\n async initialize({ engine, cesdk }) {\n const soundstripeSource = createSoundstripeSource(\n engine as CreativeEngine,\n { apiKey, baseUrl }\n );\n engine.asset.addSource(soundstripeSource);\n\n // Refresh all soundstripe urls when a scene is loaded\n engine.scene.onActiveChanged(() => {\n refreshSoundstripeAudioURIs(engine as CreativeEngine, {\n apiKey,\n baseUrl\n });\n });\n if (cesdk) {\n cesdk.setTranslations({\n en: {\n [`libraries.${soundstripeSource.id}.label`]: 'Soundstripe'\n }\n });\n }\n }\n };\n};\n\nexport interface SoundstripePluginConfiguration {\n apiKey?: string; // Optional API key (required when using direct API access)\n baseUrl?: string; // Optional base URL for proxy server (required when using proxy)\n}\n", "import { PLUGIN_ID } from './constants';\nimport {\n SoundstripePlugin,\n type SoundstripePluginConfiguration\n} from './plugin';\n\nconst Plugin = (pluginConfiguration: SoundstripePluginConfiguration) => ({\n name: PLUGIN_ID,\n version: PLUGIN_VERSION,\n ...SoundstripePlugin(pluginConfiguration)\n});\n\nexport default Plugin;\nexport type { SoundstripePluginConfiguration };\nexport { refreshSoundstripeAudioURIs } from './refresh-audio-uris';\n"],
5
+ "mappings": "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",
6
+ "names": ["PLUGIN_ID", "EMPTY_RESULT", "createSoundstripeSource", "engine", "config", "apiKey", "baseUrl", "fetchSoundstripeAssets", "query", "page", "perPage", "apiBaseUrl", "url", "headers", "response", "formatAsset", "audio", "relationships", "audioFile", "item", "firstAuthor", "calculateNextPage", "pageSize", "resultCount", "assetResult", "blockId", "queryData", "song", "asset", "soundstripe_asset_source_default", "refreshSoundstripeAudioURIs", "engine", "config", "apiKey", "baseUrl", "fetchSoundstripeSong", "songId", "apiBaseUrl", "url", "headers", "response", "audioBlocks", "blockId", "oldUri", "metadata", "newUri", "item", "error", "SoundstripePlugin", "pluginConfiguration", "apiKey", "baseUrl", "engine", "cesdk", "soundstripeSource", "soundstripe_asset_source_default", "refreshSoundstripeAudioURIs", "Plugin", "pluginConfiguration", "PLUGIN_ID", "SoundstripePlugin", "src_default"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imgly/plugin-soundstripe-web",
3
- "version": "0.1.1",
3
+ "version": "1.68.0-rc.2",
4
4
  "description": "Soundstripe asset source plugin for the CE.SDK editor",
5
5
  "keywords": [
6
6
  "CE.SDK",
@@ -9,10 +9,6 @@
9
9
  "soundstripe",
10
10
  "asset-source"
11
11
  ],
12
- "repository": {
13
- "type": "git",
14
- "url": "git+https://github.com/imgly/plugins.git"
15
- },
16
12
  "license": "SEE LICENSE IN LICENSE.md",
17
13
  "author": {
18
14
  "name": "IMG.LY GmbH",
@@ -31,7 +27,7 @@
31
27
  "types": "./dist/index.d.ts"
32
28
  }
33
29
  },
34
- "homepage": "https://img.ly/products/creative-sdk",
30
+ "homepage": "https://img.ly/docs/cesdk/",
35
31
  "files": [
36
32
  "LICENSE.md",
37
33
  "README.md",
@@ -49,7 +45,7 @@
49
45
  "typescript": "^5.7.3"
50
46
  },
51
47
  "peerDependencies": {
52
- "@cesdk/cesdk-js": "^1.32.0"
48
+ "@cesdk/cesdk-js": "1.68.0-rc.2"
53
49
  },
54
50
  "dependencies": {},
55
51
  "scripts": {
@@ -57,9 +53,6 @@
57
53
  "clean": "pnpm exec rimraf dist",
58
54
  "purge": "pnpm exec rimraf node_modules",
59
55
  "build": "pnpm run clean && pnpm exec node scripts/build.mjs",
60
- "test": "node test-simple.mjs",
61
- "test:engine": "node test-node.mjs",
62
- "test:with-key": "echo 'Set SOUNDSTRIPE_API_KEY and run: SOUNDSTRIPE_API_KEY=your_key node test-simple.mjs'",
63
56
  "dev": "pnpm run clean && pnpm --filter \"${npm_package_name}^...\" --parallel run dev:wait && pnpm exec node scripts/watch.mjs",
64
57
  "dev:wait": "pnpm exec wait-on ./dist/index.mjs ./dist/index.d.ts --window 250 --timeout 60000",
65
58
  "dev:types": "tsc --emitDeclarationOnly --watch --preserveWatchOutput",