ssml-builder-js 2.10.0 → 2.11.0
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 +66 -4
- package/bin/sync-voices.js +62 -0
- package/dist/{chunk-BYIZQL2W.mjs → chunk-FWWMWI2C.mjs} +69 -12
- package/dist/chunk-FWWMWI2C.mjs.map +1 -0
- package/dist/{chunk-GW6CKHXF.mjs → chunk-SNRI43QJ.mjs} +55 -3
- package/dist/chunk-SNRI43QJ.mjs.map +1 -0
- package/dist/core.d.mts +10 -2
- package/dist/core.d.ts +10 -2
- package/dist/core.js +54 -2
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +1 -1
- package/dist/elements.js +68 -11
- package/dist/elements.js.map +1 -1
- package/dist/elements.mjs +1 -1
- package/dist/index.d.mts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +134 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +80 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react.js +173 -12
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +106 -2
- package/dist/react.mjs.map +1 -1
- package/package.json +5 -1
- package/dist/chunk-BYIZQL2W.mjs.map +0 -1
- package/dist/chunk-GW6CKHXF.mjs.map +0 -1
package/dist/elements.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -44,4 +44,29 @@ declare class AzureTtsClient {
|
|
|
44
44
|
|
|
45
45
|
declare function synthesizeSpeech(ssml: string, config: TtsConfig): Promise<ArrayBuffer>;
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
interface FetchAzureVoiceCatalogOptions {
|
|
48
|
+
apiKey: string;
|
|
49
|
+
region: string | string[];
|
|
50
|
+
}
|
|
51
|
+
interface AzureVoiceCatalogVoice {
|
|
52
|
+
name: string;
|
|
53
|
+
locale: string;
|
|
54
|
+
secondaryLocales?: readonly string[];
|
|
55
|
+
styles?: readonly string[];
|
|
56
|
+
regions: readonly string[];
|
|
57
|
+
status?: "ga" | "preview" | "deprecated";
|
|
58
|
+
}
|
|
59
|
+
interface FetchedAzureVoiceCatalogMetadata {
|
|
60
|
+
voiceCount: number;
|
|
61
|
+
generatedAt: string;
|
|
62
|
+
apiVersion: string;
|
|
63
|
+
regions: readonly string[];
|
|
64
|
+
}
|
|
65
|
+
interface AzureVoiceCatalog {
|
|
66
|
+
voices: readonly AzureVoiceCatalogVoice[];
|
|
67
|
+
metadata: FetchedAzureVoiceCatalogMetadata;
|
|
68
|
+
}
|
|
69
|
+
/** Fetches and deduplicates the current Azure Speech voice catalog for one or more regions. */
|
|
70
|
+
declare function fetchAzureVoiceCatalog(options: FetchAzureVoiceCatalogOptions): Promise<AzureVoiceCatalog>;
|
|
71
|
+
|
|
72
|
+
export { AzureTtsClient, type AzureTtsClientOptions, AzureTtsError, type AzureTtsLogger, AzureTtsSdkError, type AzureVoiceCatalog, type AzureVoiceCatalogVoice, type FetchAzureVoiceCatalogOptions, type FetchedAzureVoiceCatalogMetadata, type TtsConfig, fetchAzureVoiceCatalog, synthesizeSpeech };
|
package/dist/index.d.ts
CHANGED
|
@@ -44,4 +44,29 @@ declare class AzureTtsClient {
|
|
|
44
44
|
|
|
45
45
|
declare function synthesizeSpeech(ssml: string, config: TtsConfig): Promise<ArrayBuffer>;
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
interface FetchAzureVoiceCatalogOptions {
|
|
48
|
+
apiKey: string;
|
|
49
|
+
region: string | string[];
|
|
50
|
+
}
|
|
51
|
+
interface AzureVoiceCatalogVoice {
|
|
52
|
+
name: string;
|
|
53
|
+
locale: string;
|
|
54
|
+
secondaryLocales?: readonly string[];
|
|
55
|
+
styles?: readonly string[];
|
|
56
|
+
regions: readonly string[];
|
|
57
|
+
status?: "ga" | "preview" | "deprecated";
|
|
58
|
+
}
|
|
59
|
+
interface FetchedAzureVoiceCatalogMetadata {
|
|
60
|
+
voiceCount: number;
|
|
61
|
+
generatedAt: string;
|
|
62
|
+
apiVersion: string;
|
|
63
|
+
regions: readonly string[];
|
|
64
|
+
}
|
|
65
|
+
interface AzureVoiceCatalog {
|
|
66
|
+
voices: readonly AzureVoiceCatalogVoice[];
|
|
67
|
+
metadata: FetchedAzureVoiceCatalogMetadata;
|
|
68
|
+
}
|
|
69
|
+
/** Fetches and deduplicates the current Azure Speech voice catalog for one or more regions. */
|
|
70
|
+
declare function fetchAzureVoiceCatalog(options: FetchAzureVoiceCatalogOptions): Promise<AzureVoiceCatalog>;
|
|
71
|
+
|
|
72
|
+
export { AzureTtsClient, type AzureTtsClientOptions, AzureTtsError, type AzureTtsLogger, AzureTtsSdkError, type AzureVoiceCatalog, type AzureVoiceCatalogVoice, type FetchAzureVoiceCatalogOptions, type FetchedAzureVoiceCatalogMetadata, type TtsConfig, fetchAzureVoiceCatalog, synthesizeSpeech };
|
package/dist/index.js
CHANGED
|
@@ -45,6 +45,7 @@ __export(src_exports, {
|
|
|
45
45
|
buildSsml: () => buildSsml,
|
|
46
46
|
extractSsmlText: () => extractSsmlText,
|
|
47
47
|
extractSsmlTranslatableText: () => extractSsmlTranslatableText,
|
|
48
|
+
fetchAzureVoiceCatalog: () => fetchAzureVoiceCatalog,
|
|
48
49
|
fromPlainTextToSsml: () => fromPlainTextToSsml,
|
|
49
50
|
getAzureVoiceCatalogMetadata: () => getAzureVoiceCatalogMetadata,
|
|
50
51
|
getBuiltInVoiceCatalogMetadata: () => getBuiltInVoiceCatalogMetadata,
|
|
@@ -1501,6 +1502,9 @@ var AZURE_VOICE_DEFINITIONS = [
|
|
|
1501
1502
|
},
|
|
1502
1503
|
{ name: "es-ES-ElviraNeural", locale: "es-ES" },
|
|
1503
1504
|
{ name: "fil-PH-AngeloNeural", locale: "fil-PH" },
|
|
1505
|
+
{ name: "fil-PH-Angelo:DragonHDLatestNeural", locale: "fil-PH" },
|
|
1506
|
+
{ name: "fil-PH-BlessicaNeural", locale: "fil-PH" },
|
|
1507
|
+
{ name: "fil-PH-Blessica:DragonHDLatestNeural", locale: "fil-PH" },
|
|
1504
1508
|
{ name: "fr-FR-DeniseNeural", locale: "fr-FR", styles: ["cheerful", "sad"] },
|
|
1505
1509
|
{ name: "fr-FR-HenriNeural", locale: "fr-FR", styles: ["cheerful", "sad"] },
|
|
1506
1510
|
{ name: "id-ID-GadisNeural", locale: "id-ID" },
|
|
@@ -1597,6 +1601,18 @@ var ALLOWED_SILENCE_TYPES = /* @__PURE__ */ new Set([
|
|
|
1597
1601
|
"Enumerationcomma"
|
|
1598
1602
|
]);
|
|
1599
1603
|
var ALLOWED_VISEME_TYPES = /* @__PURE__ */ new Set(["redlips_front", "FacialExpression"]);
|
|
1604
|
+
var DEFAULT_PREVIEW_TAGS = /* @__PURE__ */ new Set(["mstts:voiceconversion"]);
|
|
1605
|
+
function featureStatusForTag(name, options) {
|
|
1606
|
+
const tagName = canonicalTagName(name);
|
|
1607
|
+
const configured = Object.entries(options.tagStatuses ?? {}).find(
|
|
1608
|
+
([candidate]) => canonicalTagName(candidate) === tagName
|
|
1609
|
+
)?.[1];
|
|
1610
|
+
if (configured) return configured;
|
|
1611
|
+
if ((options.previewTags ?? [...DEFAULT_PREVIEW_TAGS]).some((candidate) => canonicalTagName(candidate) === tagName))
|
|
1612
|
+
return "preview";
|
|
1613
|
+
if ((options.deprecatedTags ?? []).some((candidate) => canonicalTagName(candidate) === tagName)) return "deprecated";
|
|
1614
|
+
return void 0;
|
|
1615
|
+
}
|
|
1600
1616
|
function decodeAttribute(value) {
|
|
1601
1617
|
return value.replace(
|
|
1602
1618
|
/&(?:amp|apos|gt|lt|quot);/gi,
|
|
@@ -1713,9 +1729,9 @@ function isValidAzureAudioDuration(value) {
|
|
|
1713
1729
|
return Number(clock[1]) > 0 || Number(clock[2]) > 0 || Number(clock[3]) > 0 || Number(clock[4] ?? 0) > 0;
|
|
1714
1730
|
}
|
|
1715
1731
|
function isValidAzureBackgroundAudioDuration(value) {
|
|
1716
|
-
const match = /^(\d+
|
|
1732
|
+
const match = /^(\d+)$/.exec(value.trim());
|
|
1717
1733
|
if (!match) return false;
|
|
1718
|
-
const milliseconds = Number(match[1])
|
|
1734
|
+
const milliseconds = Number(match[1]);
|
|
1719
1735
|
return Number.isFinite(milliseconds) && milliseconds >= 0 && milliseconds <= 1e4;
|
|
1720
1736
|
}
|
|
1721
1737
|
function attr(token, name) {
|
|
@@ -1876,6 +1892,25 @@ function validateAudioSource(token, source, diagnostics, options, elementName2)
|
|
|
1876
1892
|
}
|
|
1877
1893
|
function validateElement(token, source, diagnostics, voiceName, options, voiceCatalog) {
|
|
1878
1894
|
const name = token.name.toLowerCase();
|
|
1895
|
+
const tagStatus = featureStatusForTag(token.name, options);
|
|
1896
|
+
if (tagStatus === "preview")
|
|
1897
|
+
addDiagnostic(
|
|
1898
|
+
diagnostics,
|
|
1899
|
+
source,
|
|
1900
|
+
token.start,
|
|
1901
|
+
`<${token.name}> is an Azure Speech preview feature and may change or require preview access.`,
|
|
1902
|
+
"warning",
|
|
1903
|
+
"azure-preview-tag"
|
|
1904
|
+
);
|
|
1905
|
+
if (tagStatus === "deprecated")
|
|
1906
|
+
addDiagnostic(
|
|
1907
|
+
diagnostics,
|
|
1908
|
+
source,
|
|
1909
|
+
token.start,
|
|
1910
|
+
`<${token.name}> is deprecated by Azure Speech; migrate to a supported alternative.`,
|
|
1911
|
+
"info",
|
|
1912
|
+
"azure-deprecated-tag"
|
|
1913
|
+
);
|
|
1879
1914
|
if (name === "voice" && !attr(token, "name")?.trim())
|
|
1880
1915
|
addDiagnostic(diagnostics, source, token.start, '<voice> requires a non-empty "name" attribute.');
|
|
1881
1916
|
if (name === "break") {
|
|
@@ -2087,6 +2122,24 @@ function validateAzureSsml(ssml, options = {}) {
|
|
|
2087
2122
|
const name = attr(token, "name")?.trim();
|
|
2088
2123
|
const language = attr(token, "xml:lang")?.trim() || (speak ? attr(speak, "xml:lang")?.trim() : void 0);
|
|
2089
2124
|
const definition = name ? voiceCatalog.get(name.toLowerCase()) : void 0;
|
|
2125
|
+
if (name && definition?.status === "preview")
|
|
2126
|
+
addDiagnostic(
|
|
2127
|
+
diagnostics,
|
|
2128
|
+
ssml,
|
|
2129
|
+
token.start,
|
|
2130
|
+
`Voice "${name}" is an Azure Speech preview voice and may change or require preview access.`,
|
|
2131
|
+
"warning",
|
|
2132
|
+
"azure-preview-voice"
|
|
2133
|
+
);
|
|
2134
|
+
if (name && definition?.status === "deprecated")
|
|
2135
|
+
addDiagnostic(
|
|
2136
|
+
diagnostics,
|
|
2137
|
+
ssml,
|
|
2138
|
+
token.start,
|
|
2139
|
+
`Voice "${name}" is deprecated by Azure Speech; migrate to a supported voice.`,
|
|
2140
|
+
"info",
|
|
2141
|
+
"azure-deprecated-voice"
|
|
2142
|
+
);
|
|
2090
2143
|
if (name && !definition && policySeverity)
|
|
2091
2144
|
addDiagnostic(
|
|
2092
2145
|
diagnostics,
|
|
@@ -2324,6 +2377,84 @@ var AzureTtsClient = class {
|
|
|
2324
2377
|
}
|
|
2325
2378
|
};
|
|
2326
2379
|
_options = new WeakMap();
|
|
2380
|
+
|
|
2381
|
+
// packages/azure-tts-client/src/voiceCatalog.ts
|
|
2382
|
+
var AZURE_VOICE_API_VERSION = "2025-10-01";
|
|
2383
|
+
function stringValue(value) {
|
|
2384
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
2385
|
+
}
|
|
2386
|
+
function stringList(value) {
|
|
2387
|
+
if (!Array.isArray(value)) return [];
|
|
2388
|
+
return [...new Set(value.map(stringValue).filter((item) => item !== void 0))];
|
|
2389
|
+
}
|
|
2390
|
+
function normalizeStatus(value) {
|
|
2391
|
+
const status = stringValue(value)?.toLowerCase();
|
|
2392
|
+
if (status === "preview" || status === "deprecated" || status === "ga") return status;
|
|
2393
|
+
return void 0;
|
|
2394
|
+
}
|
|
2395
|
+
function normalizeRegions(region) {
|
|
2396
|
+
const regions = Array.isArray(region) ? region : [region];
|
|
2397
|
+
const result = [...new Set(regions.map((item) => item.trim()).filter(Boolean))];
|
|
2398
|
+
if (result.length === 0) throw new TypeError("At least one Azure Speech region is required.");
|
|
2399
|
+
return result;
|
|
2400
|
+
}
|
|
2401
|
+
async function fetchRegionVoices(region, apiKey) {
|
|
2402
|
+
const endpoint = `https://${encodeURIComponent(region)}.tts.speech.microsoft.com/cognitiveservices/voices/list`;
|
|
2403
|
+
const response = await fetch(endpoint, {
|
|
2404
|
+
headers: {
|
|
2405
|
+
Accept: "application/json",
|
|
2406
|
+
"Ocp-Apim-Subscription-Key": apiKey
|
|
2407
|
+
}
|
|
2408
|
+
});
|
|
2409
|
+
if (!response.ok) {
|
|
2410
|
+
throw new Error(`Azure List Voices API request failed for region "${region}" with HTTP ${response.status}.`);
|
|
2411
|
+
}
|
|
2412
|
+
const payload = await response.json();
|
|
2413
|
+
if (!Array.isArray(payload)) throw new Error(`Azure List Voices API returned an invalid response for "${region}".`);
|
|
2414
|
+
return payload.filter((item) => Boolean(item && typeof item === "object"));
|
|
2415
|
+
}
|
|
2416
|
+
async function fetchAzureVoiceCatalog(options) {
|
|
2417
|
+
if (!options || typeof options.apiKey !== "string" || !options.apiKey.trim())
|
|
2418
|
+
throw new TypeError("An Azure Speech API key is required.");
|
|
2419
|
+
const regions = normalizeRegions(options.region);
|
|
2420
|
+
const payloads = await Promise.all(regions.map((region) => fetchRegionVoices(region, options.apiKey)));
|
|
2421
|
+
const voices = /* @__PURE__ */ new Map();
|
|
2422
|
+
for (let regionIndex = 0; regionIndex < payloads.length; regionIndex += 1) {
|
|
2423
|
+
const region = regions[regionIndex];
|
|
2424
|
+
for (const record of payloads[regionIndex]) {
|
|
2425
|
+
const name = stringValue(record.ShortName) ?? stringValue(record.Name);
|
|
2426
|
+
const locale = stringValue(record.Locale);
|
|
2427
|
+
if (!name || !locale) continue;
|
|
2428
|
+
const key = name.toLowerCase();
|
|
2429
|
+
const existing = voices.get(key);
|
|
2430
|
+
const secondaryLocales = stringList(record.SecondaryLocaleList);
|
|
2431
|
+
const styles = stringList(record.StyleList);
|
|
2432
|
+
const status = normalizeStatus(record.Status);
|
|
2433
|
+
const merged = {
|
|
2434
|
+
name: existing?.name ?? name,
|
|
2435
|
+
locale: existing?.locale ?? locale,
|
|
2436
|
+
regions: [.../* @__PURE__ */ new Set([...existing?.regions ?? [], region])]
|
|
2437
|
+
};
|
|
2438
|
+
const mergedSecondaryLocales = [.../* @__PURE__ */ new Set([...existing?.secondaryLocales ?? [], ...secondaryLocales])];
|
|
2439
|
+
if (mergedSecondaryLocales.length > 0) merged.secondaryLocales = mergedSecondaryLocales;
|
|
2440
|
+
const mergedStyles = [.../* @__PURE__ */ new Set([...existing?.styles ?? [], ...styles])];
|
|
2441
|
+
if (mergedStyles.length > 0) merged.styles = mergedStyles;
|
|
2442
|
+
if (status) merged.status = status;
|
|
2443
|
+
else if (existing?.status) merged.status = existing.status;
|
|
2444
|
+
voices.set(key, merged);
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
const sortedVoices = [...voices.values()].sort((first, second) => first.name.localeCompare(second.name));
|
|
2448
|
+
return {
|
|
2449
|
+
voices: sortedVoices,
|
|
2450
|
+
metadata: {
|
|
2451
|
+
voiceCount: sortedVoices.length,
|
|
2452
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2453
|
+
apiVersion: AZURE_VOICE_API_VERSION,
|
|
2454
|
+
regions
|
|
2455
|
+
}
|
|
2456
|
+
};
|
|
2457
|
+
}
|
|
2327
2458
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2328
2459
|
0 && (module.exports = {
|
|
2329
2460
|
AzureTtsClient,
|
|
@@ -2334,6 +2465,7 @@ _options = new WeakMap();
|
|
|
2334
2465
|
buildSsml,
|
|
2335
2466
|
extractSsmlText,
|
|
2336
2467
|
extractSsmlTranslatableText,
|
|
2468
|
+
fetchAzureVoiceCatalog,
|
|
2337
2469
|
fromPlainTextToSsml,
|
|
2338
2470
|
getAzureVoiceCatalogMetadata,
|
|
2339
2471
|
getBuiltInVoiceCatalogMetadata,
|