@neosapience/n8n-nodes-typecast 1.0.2 → 1.0.4

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.
@@ -1,95 +1,196 @@
1
1
  import type { INodeProperties } from 'n8n-workflow';
2
2
 
3
3
  const showOnlyForVoice = {
4
- resource: ['voice'],
4
+ resource: ['voice'],
5
5
  };
6
6
 
7
7
  export const voiceDescription: INodeProperties[] = [
8
- {
9
- displayName: 'Operation',
10
- name: 'operation',
11
- type: 'options',
12
- noDataExpression: true,
13
- displayOptions: {
14
- show: showOnlyForVoice,
15
- },
16
- options: [
17
- {
18
- name: 'Get',
19
- value: 'get',
20
- description: 'Get details of a specific voice model',
21
- action: 'Get a voice',
22
- },
23
- {
24
- name: 'Get Many',
25
- value: 'getMany',
26
- description: 'Get all available voice models',
27
- action: 'Get all voices',
28
- },
29
- ],
30
- default: 'getMany',
31
- },
32
- // ----------------------------------
33
- // voice:get
34
- // ----------------------------------
35
- {
36
- displayName: 'Voice ID',
37
- name: 'voiceId',
38
- type: 'string',
39
- required: true,
40
- displayOptions: {
41
- show: {
42
- resource: ['voice'],
43
- operation: ['get'],
44
- },
45
- },
46
- default: 'tc_62a8975e695ad26f7fb514d1',
47
- description: 'The ID of the voice to retrieve',
48
- placeholder: 'tc_62a8975e695ad26f7fb514d1',
49
- },
50
- {
51
- displayName: 'Model',
52
- name: 'model',
53
- type: 'options',
54
- displayOptions: {
55
- show: {
56
- resource: ['voice'],
57
- operation: ['get'],
58
- },
59
- },
60
- options: [
61
- {
62
- name: 'SSFM-V21',
63
- value: 'ssfm-v21',
64
- },
65
- ],
66
- default: 'ssfm-v21',
67
- description: 'Voice model to use',
68
- },
69
- // ----------------------------------
70
- // voice:getMany
71
- // ----------------------------------
72
- {
73
- displayName: 'Model',
74
- name: 'model',
75
- type: 'options',
76
- displayOptions: {
77
- show: {
78
- resource: ['voice'],
79
- operation: ['getMany'],
80
- },
81
- },
82
- options: [
83
- {
84
- name: 'All',
85
- value: '',
86
- },
87
- {
88
- name: 'SSFM-V21',
89
- value: 'ssfm-v21',
90
- },
91
- ],
92
- default: '',
93
- description: 'Filter by voice model (optional)',
94
- },
8
+ {
9
+ displayName: 'Operation',
10
+ name: 'operation',
11
+ type: 'options',
12
+ noDataExpression: true,
13
+ displayOptions: {
14
+ show: showOnlyForVoice,
15
+ },
16
+ options: [
17
+ {
18
+ name: 'Get All Voices',
19
+ value: 'getMany',
20
+ description: 'Get all available voice models',
21
+ action: 'Get all voices',
22
+ },
23
+ ],
24
+ default: 'getMany',
25
+ },
26
+ // ----------------------------------
27
+ // voice:getMany
28
+ // ----------------------------------
29
+ {
30
+ displayName: 'Filters',
31
+ name: 'filters',
32
+ type: 'collection',
33
+ placeholder: 'Add Filter',
34
+ default: {},
35
+ displayOptions: {
36
+ show: {
37
+ resource: ['voice'],
38
+ operation: ['getMany'],
39
+ },
40
+ },
41
+ options: [
42
+ {
43
+ displayName: 'Model',
44
+ name: 'model',
45
+ type: 'options',
46
+ options: [
47
+ {
48
+ name: 'All',
49
+ value: '',
50
+ description: 'List all available voices for all models',
51
+ },
52
+ {
53
+ name: 'SSFM-V30 (Latest)',
54
+ value: 'ssfm-v30',
55
+ description: 'Latest model with improved prosody and additional emotion presets',
56
+ },
57
+ {
58
+ name: 'SSFM-V21',
59
+ value: 'ssfm-v21',
60
+ description: 'Stable production model with proven reliability',
61
+ },
62
+ ],
63
+ default: '',
64
+ description: 'Filter voices by TTS model version',
65
+ },
66
+ {
67
+ displayName: 'Gender',
68
+ name: 'gender',
69
+ type: 'options',
70
+ options: [
71
+ {
72
+ name: 'Female',
73
+ value: 'female',
74
+ description: 'Female voice',
75
+ },
76
+ {
77
+ name: 'Male',
78
+ value: 'male',
79
+ description: 'Male voice',
80
+ },
81
+ ],
82
+ default: 'female',
83
+ description: 'Filter voices by gender',
84
+ },
85
+ {
86
+ displayName: 'Age',
87
+ name: 'age',
88
+ type: 'options',
89
+ options: [
90
+ {
91
+ name: 'Child',
92
+ value: 'child',
93
+ description: 'Child voice (under 12 years old)',
94
+ },
95
+ {
96
+ name: 'Elder',
97
+ value: 'elder',
98
+ description: 'Elder voice (over 60 years old)',
99
+ },
100
+ {
101
+ name: 'Middle Age',
102
+ value: 'middle_age',
103
+ description: 'Middle-aged voice (36-60 years old)',
104
+ },
105
+ {
106
+ name: 'Teenager',
107
+ value: 'teenager',
108
+ description: 'Teenage voice (13-19 years old)',
109
+ },
110
+ {
111
+ name: 'Young Adult',
112
+ value: 'young_adult',
113
+ description: 'Young adult voice (20-35 years old)',
114
+ },
115
+ ],
116
+ default: 'child',
117
+ description: 'Filter voices by age group',
118
+ },
119
+ {
120
+ displayName: 'Use Cases',
121
+ name: 'use_cases',
122
+ type: 'options',
123
+ options: [
124
+ {
125
+ name: 'Ads',
126
+ value: 'Ads',
127
+ description: 'Advertising and promotional content',
128
+ },
129
+ {
130
+ name: 'Anime',
131
+ value: 'Anime',
132
+ description: 'Animation and character voices',
133
+ },
134
+ {
135
+ name: 'Announcer',
136
+ value: 'Announcer',
137
+ description: 'Public announcements and presentations',
138
+ },
139
+ {
140
+ name: 'Audiobook',
141
+ value: 'Audiobook',
142
+ description: 'Long-form narration and storytelling',
143
+ },
144
+ {
145
+ name: 'Conversational',
146
+ value: 'Conversational',
147
+ description: 'Chatbots and conversational AI',
148
+ },
149
+ {
150
+ name: 'Documentary',
151
+ value: 'Documentary',
152
+ description: 'Documentary narration and commentary',
153
+ },
154
+ {
155
+ name: 'E-Learning',
156
+ value: 'E-learning',
157
+ description: 'Educational content and tutorials',
158
+ },
159
+ {
160
+ name: 'Game',
161
+ value: 'Game',
162
+ description: 'Video game characters and narration',
163
+ },
164
+ {
165
+ name: 'News',
166
+ value: 'News',
167
+ description: 'News broadcasting',
168
+ },
169
+ {
170
+ name: 'Podcast',
171
+ value: 'Podcast',
172
+ description: 'Broadcasting and podcast production',
173
+ },
174
+ {
175
+ name: 'Rapper',
176
+ value: 'Rapper',
177
+ description: 'Rap and music performance',
178
+ },
179
+ {
180
+ name: 'TikTok/Reels',
181
+ value: 'Tiktok/Reels',
182
+ description: 'Short-form social media content',
183
+ },
184
+ {
185
+ name: 'Voicemail',
186
+ value: 'Voicemail',
187
+ description: 'IVR systems and voice assistants',
188
+ },
189
+ ],
190
+ default: 'Announcer',
191
+ description: 'Filter voices by use case category',
192
+ },
193
+ ],
194
+ description: 'Filter voices by model, gender, age, or use cases',
195
+ },
95
196
  ];
@@ -1,54 +1,82 @@
1
1
  import type {
2
- IExecuteFunctions,
3
- ILoadOptionsFunctions,
4
- IHookFunctions,
5
- IHttpRequestMethods,
6
- IDataObject,
7
- IHttpRequestOptions,
2
+ IExecuteFunctions,
3
+ ILoadOptionsFunctions,
4
+ IHookFunctions,
5
+ IHttpRequestMethods,
6
+ IDataObject,
7
+ IHttpRequestOptions,
8
8
  } from 'n8n-workflow';
9
9
 
10
10
  export async function typecastApiRequest(
11
- this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions,
12
- method: IHttpRequestMethods,
13
- endpoint: string,
14
- body: IDataObject = {},
15
- qs: IDataObject = {},
11
+ this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions,
12
+ method: IHttpRequestMethods,
13
+ endpoint: string,
14
+ body: IDataObject = {},
15
+ qs: IDataObject = {},
16
+ version: string = 'v2',
16
17
  ) {
17
- const options: IHttpRequestOptions = {
18
- method,
19
- body,
20
- qs,
21
- url: `https://api.typecast.ai/v1${endpoint}`,
22
- json: true,
23
- };
24
-
25
- try {
26
- return await this.helpers.httpRequestWithAuthentication.call(this, 'typecastApi', options);
27
- } catch (error) {
28
- throw new Error(`Typecast API request failed: ${(error as Error).message}`);
29
- }
18
+ const options: IHttpRequestOptions = {
19
+ method,
20
+ body,
21
+ qs,
22
+ url: `https://api.typecast.ai/${version}${endpoint}`,
23
+ json: true,
24
+ };
25
+
26
+ try {
27
+ return await this.helpers.httpRequestWithAuthentication.call(this, 'typecastApi', options);
28
+ } catch (error) {
29
+ const errorData = error as {
30
+ message?: string;
31
+ httpCode?: number;
32
+ errorResponse?: { error_code?: string };
33
+ error_code?: string;
34
+ };
35
+ const errorMessage = errorData.message || 'Unknown error';
36
+ const statusCode = errorData.httpCode;
37
+ const errorCode = errorData.errorResponse?.error_code || errorData.error_code;
38
+
39
+ const statusDetails = statusCode ? `[${statusCode}] ` : '';
40
+ const errorCodeDetails = errorCode ? `(Error Code: ${errorCode}) ` : '';
41
+
42
+ throw new Error(`Typecast API request failed: ${statusDetails}${errorCodeDetails}${errorMessage}`);
43
+ }
30
44
  }
31
45
 
32
46
  export async function typecastApiRequestBinary(
33
- this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions,
34
- method: IHttpRequestMethods,
35
- endpoint: string,
36
- body: IDataObject = {},
37
- qs: IDataObject = {},
38
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
+ this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions,
48
+ method: IHttpRequestMethods,
49
+ endpoint: string,
50
+ body: IDataObject = {},
51
+ qs: IDataObject = {},
52
+ version: string = 'v1',
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
54
  ): Promise<any> {
40
- const options: IHttpRequestOptions = {
41
- method,
42
- body,
43
- qs,
44
- url: `https://api.typecast.ai/v1${endpoint}`,
45
- json: true,
46
- encoding: 'arraybuffer',
47
- };
48
-
49
- try {
50
- return await this.helpers.httpRequestWithAuthentication.call(this, 'typecastApi', options);
51
- } catch (error) {
52
- throw new Error(`Typecast API binary request failed: ${(error as Error).message}`);
53
- }
55
+ const options: IHttpRequestOptions = {
56
+ method,
57
+ body,
58
+ qs,
59
+ url: `https://api.typecast.ai/${version}${endpoint}`,
60
+ json: true,
61
+ encoding: 'arraybuffer',
62
+ };
63
+
64
+ try {
65
+ return await this.helpers.httpRequestWithAuthentication.call(this, 'typecastApi', options);
66
+ } catch (error) {
67
+ const errorData = error as {
68
+ message?: string;
69
+ httpCode?: number;
70
+ errorResponse?: { error_code?: string };
71
+ error_code?: string;
72
+ };
73
+ const errorMessage = errorData.message || 'Unknown error';
74
+ const statusCode = errorData.httpCode;
75
+ const errorCode = errorData.errorResponse?.error_code || errorData.error_code;
76
+
77
+ const statusDetails = statusCode ? `[${statusCode}] ` : '';
78
+ const errorCodeDetails = errorCode ? `(Error Code: ${errorCode}) ` : '';
79
+
80
+ throw new Error(`Typecast API binary request failed: ${statusDetails}${errorCodeDetails}${errorMessage}`);
81
+ }
54
82
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neosapience/n8n-nodes-typecast",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "n8n node for Typecast TTS API integration",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",