ssml-builder-js 2.11.0 → 2.12.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 +36 -3
- package/dist/{chunk-SNRI43QJ.mjs → chunk-4BVNAUVR.mjs} +123 -3
- package/dist/chunk-4BVNAUVR.mjs.map +1 -0
- package/dist/{chunk-FWWMWI2C.mjs → chunk-FHDFRM2F.mjs} +24 -3
- package/dist/chunk-FHDFRM2F.mjs.map +1 -0
- package/dist/core.d.mts +11 -1
- package/dist/core.d.ts +11 -1
- package/dist/core.js +123 -2
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +3 -1
- package/dist/elements.js +23 -2
- package/dist/elements.js.map +1 -1
- package/dist/elements.mjs +1 -1
- package/dist/index.d.mts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +166 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +45 -3
- package/dist/index.mjs.map +1 -1
- package/dist/react.js +163 -4
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +141 -3
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-FWWMWI2C.mjs.map +0 -1
- package/dist/chunk-SNRI43QJ.mjs.map +0 -1
package/dist/core.d.mts
CHANGED
|
@@ -188,6 +188,14 @@ interface BuildPartialSsmlOptions extends SsmlPartialContext {
|
|
|
188
188
|
declare function buildPartialSsml(text: string, context?: SsmlPartialContext): string;
|
|
189
189
|
declare function buildPartialSsml(options: BuildPartialSsmlOptions): string;
|
|
190
190
|
|
|
191
|
+
/**
|
|
192
|
+
* Splits SSML into independently synthesizable documents without breaking XML
|
|
193
|
+
* elements. Parent elements such as `<voice>` and `<prosody>` are copied into
|
|
194
|
+
* every block. Paragraph and sentence elements therefore remain the natural
|
|
195
|
+
* split points, while oversized text is split at word/character boundaries.
|
|
196
|
+
*/
|
|
197
|
+
declare function splitSsmlDocument(ssml: string, maxLength?: number): string[];
|
|
198
|
+
|
|
191
199
|
declare function parseSsml(xmlString: string): SsmlDocument;
|
|
192
200
|
|
|
193
201
|
interface SsmlValidationError {
|
|
@@ -286,6 +294,8 @@ interface AzureValidationOptions {
|
|
|
286
294
|
customVoiceDefinitions?: readonly AzureVoiceDefinition[];
|
|
287
295
|
languageAliases?: Record<string, string | readonly string[]>;
|
|
288
296
|
maxLength?: number;
|
|
297
|
+
/** Maximum XML element nesting depth, counting `<speak>` as depth 1. */
|
|
298
|
+
maxXmlDepth?: number;
|
|
289
299
|
/** Optional model identifier used to validate a voice's model compatibility. */
|
|
290
300
|
model?: string;
|
|
291
301
|
normalizeLanguage?: (lang: string) => string;
|
|
@@ -324,4 +334,4 @@ declare function getAzureVoiceCatalogMetadata(): AzureVoiceCatalogMetadata;
|
|
|
324
334
|
/** Alias for consumers that refer to the bundled catalog as the built-in catalog. */
|
|
325
335
|
declare const getBuiltInVoiceCatalogMetadata: typeof getAzureVoiceCatalogMetadata;
|
|
326
336
|
|
|
327
|
-
export { type AudioElement, type AzureDiagnosticCode, type AzureLanguageNormalizationOptions, type AzureSsmlValidationOptions, type AzureValidationOptions, type AzureVoiceCatalogMetadata, type AzureVoiceDefinition, type AzureVoiceMetadata, type BookmarkElement, type BreakElement, type BuildPartialSsmlOptions, type CustomElement, type EmphasisElement, type ExpressAsElement, type ExtractSsmlTranslatableTextOptions, type FromPlainTextToSsmlOptions, type LangElement, type LexiconElement, type MapSsmlTextNodesOptions, type MarkElement, type MsttsAudioDurationElement, type MsttsEmbeddingElement, type MsttsSilenceElement, type MsttsTtsEmbeddingElement, type MsttsVisemeElement, type MsttsVoiceConversionElement, type NamedElement, type ParagraphElement, type PhonemeElement, type ProsodyElement, type SayAsElement, type SentenceElement, type SsmlAttributeValue, type SsmlAttributes, type SsmlBackgroundAudioNode, type SsmlBreakElement, type SsmlDiagnostic, type SsmlDiagnosticSeverity, type SsmlDiagnosticSource, type SsmlDialogNode, type SsmlDocument, type SsmlElement, type SsmlElementBase, type SsmlEmbeddingNode, type SsmlExpressAsElement, type SsmlNode, type SsmlPartialContext, type SsmlPartialProsody, type SsmlPartialVoice, type SsmlPhonemeElement, type SsmlProsodyElement, type SsmlSayAsElement, type SsmlStructureIntegrityResult, type SsmlStructureMismatch, type SsmlText, type SsmlTextNodeContext, type SsmlTtsEmbeddingNode, type SsmlTurnNode, type SsmlValidationError, type SsmlVoiceConversionNode, type SsmlVoiceElement, type SubElement, type VoiceElement, type WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, extractSsmlTranslatableText, fromPlainTextToSsml, getAzureVoiceCatalogMetadata, getBuiltInVoiceCatalogMetadata, isValidAzureAudioDuration, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, validateAzureSsml, validateSsml, validateSsmlStructureIntegrity };
|
|
337
|
+
export { type AudioElement, type AzureDiagnosticCode, type AzureLanguageNormalizationOptions, type AzureSsmlValidationOptions, type AzureValidationOptions, type AzureVoiceCatalogMetadata, type AzureVoiceDefinition, type AzureVoiceMetadata, type BookmarkElement, type BreakElement, type BuildPartialSsmlOptions, type CustomElement, type EmphasisElement, type ExpressAsElement, type ExtractSsmlTranslatableTextOptions, type FromPlainTextToSsmlOptions, type LangElement, type LexiconElement, type MapSsmlTextNodesOptions, type MarkElement, type MsttsAudioDurationElement, type MsttsEmbeddingElement, type MsttsSilenceElement, type MsttsTtsEmbeddingElement, type MsttsVisemeElement, type MsttsVoiceConversionElement, type NamedElement, type ParagraphElement, type PhonemeElement, type ProsodyElement, type SayAsElement, type SentenceElement, type SsmlAttributeValue, type SsmlAttributes, type SsmlBackgroundAudioNode, type SsmlBreakElement, type SsmlDiagnostic, type SsmlDiagnosticSeverity, type SsmlDiagnosticSource, type SsmlDialogNode, type SsmlDocument, type SsmlElement, type SsmlElementBase, type SsmlEmbeddingNode, type SsmlExpressAsElement, type SsmlNode, type SsmlPartialContext, type SsmlPartialProsody, type SsmlPartialVoice, type SsmlPhonemeElement, type SsmlProsodyElement, type SsmlSayAsElement, type SsmlStructureIntegrityResult, type SsmlStructureMismatch, type SsmlText, type SsmlTextNodeContext, type SsmlTtsEmbeddingNode, type SsmlTurnNode, type SsmlValidationError, type SsmlVoiceConversionNode, type SsmlVoiceElement, type SubElement, type VoiceElement, type WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, extractSsmlTranslatableText, fromPlainTextToSsml, getAzureVoiceCatalogMetadata, getBuiltInVoiceCatalogMetadata, isValidAzureAudioDuration, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, splitSsmlDocument, validateAzureSsml, validateSsml, validateSsmlStructureIntegrity };
|
package/dist/core.d.ts
CHANGED
|
@@ -188,6 +188,14 @@ interface BuildPartialSsmlOptions extends SsmlPartialContext {
|
|
|
188
188
|
declare function buildPartialSsml(text: string, context?: SsmlPartialContext): string;
|
|
189
189
|
declare function buildPartialSsml(options: BuildPartialSsmlOptions): string;
|
|
190
190
|
|
|
191
|
+
/**
|
|
192
|
+
* Splits SSML into independently synthesizable documents without breaking XML
|
|
193
|
+
* elements. Parent elements such as `<voice>` and `<prosody>` are copied into
|
|
194
|
+
* every block. Paragraph and sentence elements therefore remain the natural
|
|
195
|
+
* split points, while oversized text is split at word/character boundaries.
|
|
196
|
+
*/
|
|
197
|
+
declare function splitSsmlDocument(ssml: string, maxLength?: number): string[];
|
|
198
|
+
|
|
191
199
|
declare function parseSsml(xmlString: string): SsmlDocument;
|
|
192
200
|
|
|
193
201
|
interface SsmlValidationError {
|
|
@@ -286,6 +294,8 @@ interface AzureValidationOptions {
|
|
|
286
294
|
customVoiceDefinitions?: readonly AzureVoiceDefinition[];
|
|
287
295
|
languageAliases?: Record<string, string | readonly string[]>;
|
|
288
296
|
maxLength?: number;
|
|
297
|
+
/** Maximum XML element nesting depth, counting `<speak>` as depth 1. */
|
|
298
|
+
maxXmlDepth?: number;
|
|
289
299
|
/** Optional model identifier used to validate a voice's model compatibility. */
|
|
290
300
|
model?: string;
|
|
291
301
|
normalizeLanguage?: (lang: string) => string;
|
|
@@ -324,4 +334,4 @@ declare function getAzureVoiceCatalogMetadata(): AzureVoiceCatalogMetadata;
|
|
|
324
334
|
/** Alias for consumers that refer to the bundled catalog as the built-in catalog. */
|
|
325
335
|
declare const getBuiltInVoiceCatalogMetadata: typeof getAzureVoiceCatalogMetadata;
|
|
326
336
|
|
|
327
|
-
export { type AudioElement, type AzureDiagnosticCode, type AzureLanguageNormalizationOptions, type AzureSsmlValidationOptions, type AzureValidationOptions, type AzureVoiceCatalogMetadata, type AzureVoiceDefinition, type AzureVoiceMetadata, type BookmarkElement, type BreakElement, type BuildPartialSsmlOptions, type CustomElement, type EmphasisElement, type ExpressAsElement, type ExtractSsmlTranslatableTextOptions, type FromPlainTextToSsmlOptions, type LangElement, type LexiconElement, type MapSsmlTextNodesOptions, type MarkElement, type MsttsAudioDurationElement, type MsttsEmbeddingElement, type MsttsSilenceElement, type MsttsTtsEmbeddingElement, type MsttsVisemeElement, type MsttsVoiceConversionElement, type NamedElement, type ParagraphElement, type PhonemeElement, type ProsodyElement, type SayAsElement, type SentenceElement, type SsmlAttributeValue, type SsmlAttributes, type SsmlBackgroundAudioNode, type SsmlBreakElement, type SsmlDiagnostic, type SsmlDiagnosticSeverity, type SsmlDiagnosticSource, type SsmlDialogNode, type SsmlDocument, type SsmlElement, type SsmlElementBase, type SsmlEmbeddingNode, type SsmlExpressAsElement, type SsmlNode, type SsmlPartialContext, type SsmlPartialProsody, type SsmlPartialVoice, type SsmlPhonemeElement, type SsmlProsodyElement, type SsmlSayAsElement, type SsmlStructureIntegrityResult, type SsmlStructureMismatch, type SsmlText, type SsmlTextNodeContext, type SsmlTtsEmbeddingNode, type SsmlTurnNode, type SsmlValidationError, type SsmlVoiceConversionNode, type SsmlVoiceElement, type SubElement, type VoiceElement, type WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, extractSsmlTranslatableText, fromPlainTextToSsml, getAzureVoiceCatalogMetadata, getBuiltInVoiceCatalogMetadata, isValidAzureAudioDuration, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, validateAzureSsml, validateSsml, validateSsmlStructureIntegrity };
|
|
337
|
+
export { type AudioElement, type AzureDiagnosticCode, type AzureLanguageNormalizationOptions, type AzureSsmlValidationOptions, type AzureValidationOptions, type AzureVoiceCatalogMetadata, type AzureVoiceDefinition, type AzureVoiceMetadata, type BookmarkElement, type BreakElement, type BuildPartialSsmlOptions, type CustomElement, type EmphasisElement, type ExpressAsElement, type ExtractSsmlTranslatableTextOptions, type FromPlainTextToSsmlOptions, type LangElement, type LexiconElement, type MapSsmlTextNodesOptions, type MarkElement, type MsttsAudioDurationElement, type MsttsEmbeddingElement, type MsttsSilenceElement, type MsttsTtsEmbeddingElement, type MsttsVisemeElement, type MsttsVoiceConversionElement, type NamedElement, type ParagraphElement, type PhonemeElement, type ProsodyElement, type SayAsElement, type SentenceElement, type SsmlAttributeValue, type SsmlAttributes, type SsmlBackgroundAudioNode, type SsmlBreakElement, type SsmlDiagnostic, type SsmlDiagnosticSeverity, type SsmlDiagnosticSource, type SsmlDialogNode, type SsmlDocument, type SsmlElement, type SsmlElementBase, type SsmlEmbeddingNode, type SsmlExpressAsElement, type SsmlNode, type SsmlPartialContext, type SsmlPartialProsody, type SsmlPartialVoice, type SsmlPhonemeElement, type SsmlProsodyElement, type SsmlSayAsElement, type SsmlStructureIntegrityResult, type SsmlStructureMismatch, type SsmlText, type SsmlTextNodeContext, type SsmlTtsEmbeddingNode, type SsmlTurnNode, type SsmlValidationError, type SsmlVoiceConversionNode, type SsmlVoiceElement, type SubElement, type VoiceElement, type WordElement, areAzureLanguagesEquivalent, buildPartialSsml, buildSsml, extractSsmlText, extractSsmlTranslatableText, fromPlainTextToSsml, getAzureVoiceCatalogMetadata, getBuiltInVoiceCatalogMetadata, isValidAzureAudioDuration, mapSsmlTextNodes, normalizeAzureLanguage, parseSsml, splitSsmlDocument, validateAzureSsml, validateSsml, validateSsmlStructureIntegrity };
|
package/dist/core.js
CHANGED
|
@@ -39,6 +39,7 @@ __export(core_exports, {
|
|
|
39
39
|
mapSsmlTextNodes: () => mapSsmlTextNodes,
|
|
40
40
|
normalizeAzureLanguage: () => normalizeAzureLanguage,
|
|
41
41
|
parseSsml: () => parseSsml,
|
|
42
|
+
splitSsmlDocument: () => splitSsmlDocument,
|
|
42
43
|
validateAzureSsml: () => validateAzureSsml,
|
|
43
44
|
validateSsml: () => validateSsml,
|
|
44
45
|
validateSsmlStructureIntegrity: () => validateSsmlStructureIntegrity
|
|
@@ -972,6 +973,104 @@ function buildPartialSsml(textOrOptions, context) {
|
|
|
972
973
|
return serializePartialSsml(textOrOptions.text, textOrOptions);
|
|
973
974
|
}
|
|
974
975
|
|
|
976
|
+
// packages/ssml-core/src/split.ts
|
|
977
|
+
var DEFAULT_MAX_LENGTH = 1e4;
|
|
978
|
+
function cloneElement(element, children) {
|
|
979
|
+
return { ...element, children };
|
|
980
|
+
}
|
|
981
|
+
function documentWithChildren(document, children) {
|
|
982
|
+
return buildSsml({ ...document, children });
|
|
983
|
+
}
|
|
984
|
+
function wrapWithContext(node, context) {
|
|
985
|
+
return context.reduceRight((current, parent) => cloneElement(parent, [current]), node);
|
|
986
|
+
}
|
|
987
|
+
function documentWithNode(document, node, context) {
|
|
988
|
+
return documentWithChildren(document, [wrapWithContext(node, context)]);
|
|
989
|
+
}
|
|
990
|
+
function splitTextNode(text, document, context, maxLength) {
|
|
991
|
+
if (!text) return [text];
|
|
992
|
+
const parts = [];
|
|
993
|
+
let start = 0;
|
|
994
|
+
while (start < text.length) {
|
|
995
|
+
let end = start + 1;
|
|
996
|
+
let bestEnd = end;
|
|
997
|
+
while (end <= text.length) {
|
|
998
|
+
if (documentWithNode(document, text.slice(start, end), context).length > maxLength) break;
|
|
999
|
+
bestEnd = end;
|
|
1000
|
+
end += 1;
|
|
1001
|
+
}
|
|
1002
|
+
if (bestEnd === start) {
|
|
1003
|
+
throw new RangeError("maxLength is too small to contain the SSML document wrapper");
|
|
1004
|
+
}
|
|
1005
|
+
const segment = text.slice(start, bestEnd);
|
|
1006
|
+
const boundary = Math.max(segment.lastIndexOf(" "), segment.lastIndexOf("\n"), segment.lastIndexOf(" "));
|
|
1007
|
+
const splitEnd = boundary > 0 ? start + boundary + 1 : bestEnd;
|
|
1008
|
+
parts.push(text.slice(start, splitEnd));
|
|
1009
|
+
start = splitEnd;
|
|
1010
|
+
}
|
|
1011
|
+
return parts;
|
|
1012
|
+
}
|
|
1013
|
+
function splitNode(document, node, maxLength, context = []) {
|
|
1014
|
+
if (typeof node === "string" || node.type === "text") {
|
|
1015
|
+
const value = typeof node === "string" ? node : node.value;
|
|
1016
|
+
if (documentWithNode(document, node, context).length <= maxLength) return [node];
|
|
1017
|
+
return splitTextNode(value, document, context, maxLength);
|
|
1018
|
+
}
|
|
1019
|
+
if (documentWithNode(document, node, context).length <= maxLength) return [node];
|
|
1020
|
+
const children = node.children ?? [];
|
|
1021
|
+
if (children.length === 0) {
|
|
1022
|
+
throw new RangeError(`maxLength is too small to contain <${node.type}>`);
|
|
1023
|
+
}
|
|
1024
|
+
const splitChildren = children.flatMap((child) => splitNode(document, child, maxLength, [...context, node]));
|
|
1025
|
+
const parts = [];
|
|
1026
|
+
let group = [];
|
|
1027
|
+
const flush = () => {
|
|
1028
|
+
if (group.length > 0) {
|
|
1029
|
+
parts.push(cloneElement(node, group));
|
|
1030
|
+
group = [];
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
for (const child of splitChildren) {
|
|
1034
|
+
const candidate = cloneElement(node, [...group, child]);
|
|
1035
|
+
if (documentWithNode(document, candidate, context).length <= maxLength) {
|
|
1036
|
+
group.push(child);
|
|
1037
|
+
continue;
|
|
1038
|
+
}
|
|
1039
|
+
flush();
|
|
1040
|
+
if (documentWithNode(document, cloneElement(node, [child]), context).length > maxLength) {
|
|
1041
|
+
throw new RangeError(`maxLength is too small to contain <${node.type}>`);
|
|
1042
|
+
}
|
|
1043
|
+
group.push(child);
|
|
1044
|
+
}
|
|
1045
|
+
flush();
|
|
1046
|
+
return parts;
|
|
1047
|
+
}
|
|
1048
|
+
function splitSsmlDocument(ssml, maxLength = DEFAULT_MAX_LENGTH) {
|
|
1049
|
+
if (!Number.isInteger(maxLength) || maxLength <= 0) {
|
|
1050
|
+
throw new RangeError("maxLength must be a positive integer");
|
|
1051
|
+
}
|
|
1052
|
+
const document = parseSsml(ssml);
|
|
1053
|
+
if (ssml.length <= maxLength) return [ssml];
|
|
1054
|
+
const children = document.children ?? [];
|
|
1055
|
+
const splitChildren = children.flatMap((child) => splitNode(document, child, maxLength));
|
|
1056
|
+
const chunks = [];
|
|
1057
|
+
let group = [];
|
|
1058
|
+
for (const child of splitChildren) {
|
|
1059
|
+
const candidate = [...group, child];
|
|
1060
|
+
if (documentWithChildren(document, candidate).length <= maxLength) {
|
|
1061
|
+
group = candidate;
|
|
1062
|
+
continue;
|
|
1063
|
+
}
|
|
1064
|
+
if (group.length > 0) chunks.push(group);
|
|
1065
|
+
group = [child];
|
|
1066
|
+
if (documentWithChildren(document, group).length > maxLength) {
|
|
1067
|
+
throw new RangeError("maxLength is too small to contain the SSML document wrapper");
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
if (group.length > 0) chunks.push(group);
|
|
1071
|
+
return chunks.map((chunk) => documentWithChildren(document, chunk));
|
|
1072
|
+
}
|
|
1073
|
+
|
|
975
1074
|
// packages/ssml-core/src/validation.ts
|
|
976
1075
|
var PARSER_POSITION_SUFFIX = / at position (\d+)$/;
|
|
977
1076
|
function validateSsml(xmlString) {
|
|
@@ -1666,6 +1765,7 @@ function tokenizeElements(source) {
|
|
|
1666
1765
|
attributes,
|
|
1667
1766
|
childElementIndex,
|
|
1668
1767
|
end,
|
|
1768
|
+
depth: openElements.length + 1,
|
|
1669
1769
|
name: tokenName,
|
|
1670
1770
|
parentName: parent?.name,
|
|
1671
1771
|
parentVoiceName,
|
|
@@ -1856,13 +1956,18 @@ function validateAudioSource(token, source, diagnostics, options, elementName2)
|
|
|
1856
1956
|
addDiagnostic(diagnostics, source, token.start, `<${elementName2} src> must be an absolute HTTP(S) URL.`);
|
|
1857
1957
|
return;
|
|
1858
1958
|
}
|
|
1959
|
+
if (parsed.username || parsed.password)
|
|
1960
|
+
addDiagnostic(diagnostics, source, token.start, `<${elementName2} src> must not contain URL credentials.`);
|
|
1859
1961
|
if (parsed.protocol !== "https:" && !(options.allowHttpAudio && parsed.protocol === "http:"))
|
|
1860
1962
|
addDiagnostic(diagnostics, source, token.start, `<${elementName2} src> must use HTTPS.`);
|
|
1861
1963
|
const isAllowedOrigin = options.allowedAudioOrigins?.some((allowedOrigin) => {
|
|
1862
1964
|
try {
|
|
1863
|
-
|
|
1965
|
+
const configured = new URL(allowedOrigin);
|
|
1966
|
+
if (configured.protocol !== "https:" && configured.protocol !== "http:" || configured.username || configured.password || configured.pathname !== "/" || configured.search || configured.hash)
|
|
1967
|
+
return false;
|
|
1968
|
+
return configured.origin === parsed.origin;
|
|
1864
1969
|
} catch {
|
|
1865
|
-
return
|
|
1970
|
+
return false;
|
|
1866
1971
|
}
|
|
1867
1972
|
}) ?? false;
|
|
1868
1973
|
if (options.allowedAudioOrigins && !isAllowedOrigin)
|
|
@@ -2070,6 +2175,9 @@ function validateAzureSsml(ssml, options = {}) {
|
|
|
2070
2175
|
const maxLength = options.maxLength ?? 1e4;
|
|
2071
2176
|
if (ssml.length > maxLength)
|
|
2072
2177
|
addDiagnostic(diagnostics, ssml, maxLength, `SSML exceeds the maximum length of ${maxLength} characters.`);
|
|
2178
|
+
if (options.maxXmlDepth !== void 0 && (!Number.isInteger(options.maxXmlDepth) || options.maxXmlDepth <= 0)) {
|
|
2179
|
+
addDiagnostic(diagnostics, ssml, 0, "maxXmlDepth must be a positive integer.");
|
|
2180
|
+
}
|
|
2073
2181
|
try {
|
|
2074
2182
|
parseSsml(ssml);
|
|
2075
2183
|
} catch (error) {
|
|
@@ -2079,6 +2187,18 @@ function validateAzureSsml(ssml, options = {}) {
|
|
|
2079
2187
|
return diagnostics;
|
|
2080
2188
|
}
|
|
2081
2189
|
const tokens = tokenizeElements(ssml);
|
|
2190
|
+
if (options.maxXmlDepth !== void 0) {
|
|
2191
|
+
for (const token of tokens) {
|
|
2192
|
+
if (token.depth > options.maxXmlDepth) {
|
|
2193
|
+
addDiagnostic(
|
|
2194
|
+
diagnostics,
|
|
2195
|
+
ssml,
|
|
2196
|
+
token.start,
|
|
2197
|
+
`XML nesting depth ${token.depth} exceeds the configured maximum of ${options.maxXmlDepth}.`
|
|
2198
|
+
);
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2082
2202
|
const speak = tokens.find((token) => token.name.toLowerCase() === "speak");
|
|
2083
2203
|
const voices = tokens.filter((token) => token.name.toLowerCase() === "voice");
|
|
2084
2204
|
const backgroundAudioTokens = tokens.filter((token) => token.name.toLowerCase() === "mstts:backgroundaudio");
|
|
@@ -2194,6 +2314,7 @@ var getBuiltInVoiceCatalogMetadata = getAzureVoiceCatalogMetadata;
|
|
|
2194
2314
|
mapSsmlTextNodes,
|
|
2195
2315
|
normalizeAzureLanguage,
|
|
2196
2316
|
parseSsml,
|
|
2317
|
+
splitSsmlDocument,
|
|
2197
2318
|
validateAzureSsml,
|
|
2198
2319
|
validateSsml,
|
|
2199
2320
|
validateSsmlStructureIntegrity
|