Sign In

@templatical/types

Package Overview
Dependencies
Maintainers
1
Versions
76
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@templatical/types - npm Package Compare versions

Comparing version
0.26.0
to
0.26.1
+43
-1
dist/index.d.ts

@@ -1044,2 +1044,44 @@ //#region src/blocks.d.ts

//#endregion
//#region src/html-scan.d.ts
/**
* Minimal, allocation-free primitives for reading an HTML open tag out of a
* markup string. They exist because merge-tag markup is rewritten from a raw
* string in two packages — `@templatical/types` (label / sample resolution for
* the previews) and `@templatical/renderer` (converting spans back to tokens on
* export) — and both need the same two answers: where does this open tag end,
* and what is the value of one of its attributes.
*
* Both are hand-written character scans rather than regexes. A regex over an
* attribute string with no closing quote backtracks across the whole input,
* which is the ReDoS class the span scanners were rewritten to avoid; a scan
* that only moves forward cannot.
*/
/**
* Index of the `>` that closes the open tag whose name ends at `from`, or `-1`
* when the tag never closes.
*
* Quote-aware: a `>` inside a quoted attribute value does not end the tag.
* That matters because a consumer may configure a merge-tag syntax whose tag
* values contain `<` / `>` — Smarty-style `<% $email %>` — and HTML attribute
* serialization escapes only `&`, `"` and U+00A0, so those characters reach the
* markup literally. A plain `indexOf(">")` stops mid-attribute there and every
* caller downstream sees a truncated attribute string.
*
* An unterminated quote yields `-1` rather than a guessed tag end: callers
* treat that as "not markup I can rewrite" and emit the input untouched, which
* is the safe answer for malformed HTML.
*/
declare function findOpenTagEnd(html: string, from: number): number;
/**
* The value of the `name` attribute within an open tag's attribute string (the
* text between the tag name and its closing `>`), or `null` when the attribute
* is absent or its quoted value is never closed.
*
* Handles double-quoted, single-quoted and unquoted values, and matches the
* attribute name case-insensitively, as HTML does. Attribute values are not
* entity-decoded — callers compare them against configured merge-tag tokens,
* which are stored the same way.
*/
declare function getTagAttrValue(attrs: string, name: string): string | null;
//#endregion
//#region src/preview-resolution.d.ts

@@ -1355,3 +1397,3 @@ /**

//#endregion
export { type AiChatMessage, type AiConfig, type AiGenerateOptions, type AiScoreOptions, type AiStreamEvent, type ApiError, type ApiResponse, type AuthConfig, type AuthRequestOptions, BUTTON_BLOCK_DEFAULTS, type BaseBlock, type Block, type BlockDefaults, type BlockStyles, type BlockType, type BlockVisibility, type ButtonBlock, COUNTDOWN_BLOCK_DEFAULTS, type CategoryScore, type CollaborationConfig, type Collaborator, type ColorsConfig, type ColumnLayout, type Comment, type CommentEvent, type CommentEventType, type CommentThread, type CountdownBlock, type CreateCommentData, type CustomBlock, type CustomBlockBooleanField, type CustomBlockColorField, type CustomBlockDefinition, type CustomBlockField, type CustomBlockFieldBase, type CustomBlockFieldType, type CustomBlockImageField, type CustomBlockNumberField, type CustomBlockRepeatableField, type CustomBlockSelectField, type CustomBlockTextField, type CustomBlockTextareaField, type CustomFont, DEFAULT_BLOCK_DEFAULTS, DEFAULT_TEMPLATE_DEFAULTS, DIVIDER_BLOCK_DEFAULTS, type DataSourceConfig, type DataSourceFetchContext, type DirectAuthConfig, type DisplayCondition, type DisplayConditionsConfig, type DividerBlock, type EditorState, EventEmitter, type ExportResult, type FindingSeverity, type FontsConfig, HEADING_LEVEL_FONT_SIZE, HTML_BLOCK_DEFAULTS, type HeadingLevel, type HealthCheckResult, type HtmlBlock, IMAGE_BLOCK_DEFAULTS, type ImageBlock, type LogicPair, type LogicTag, type LogicTagsConfig, MENU_BLOCK_DEFAULTS, type McpConfig, type McpOperation, type McpOperationPayload, type MediaResult, type MenuBlock, type MenuItemData, type MergeTag, type MergeTagsConfig, PARAGRAPH_BLOCK_DEFAULTS, type ParagraphBlock, type PlanConfig, type PlanFeatures, type PlanLimits, type PreviewResolveContext, type ProxyAuthConfig, type ResolvePreview, type RewriteData, SECTION_BLOCK_DEFAULTS, SOCIAL_ICONS_BLOCK_DEFAULTS, SOCIAL_ICON_GLYPHS, SPACER_BLOCK_DEFAULTS, SYNTAX_PRESETS, type SaveResult, type SavedBlock, type SavedBlockInput, type SavedBlockPatch, type SavedBlocksListParams, type SavedBlocksProvider, type ScoringCategory, type ScoringFinding, type ScoringResult, type SdkAuthConfig, SdkError, type SectionBlock, type SectionWrapper, type SelectOption, type SocialIcon, type SocialIconGlyph, type SocialIconSize, type SocialIconStyle, type SocialIconsBlock, type SocialPlatform, type SpacerBlock, type SpacingValue, type SyntaxPreset, type SyntaxPresetName, TABLE_BLOCK_DEFAULTS, TITLE_BLOCK_DEFAULTS, type TableBlock, type TableCellData, type TableRowData, type Template, type TemplateContent, type TemplateDefaults, type TemplateSettings, type TemplateSnapshot, type TestEmailConfig, type TestEmailPayload, type TestEmailProvider, type ThemeOverrides, type TitleBlock, type TokenData, type UiTheme, type UpdateCommentData, type UserConfig, VIDEO_BLOCK_DEFAULTS, type VideoBlock, type ViewportSize, type WebSocketServerConfig, cloneBlock, containsMergeTag, createBlock, createButtonBlock, createCountdownBlock, createCustomBlock, createDefaultTemplateContent, createDividerBlock, createHtmlBlock, createImageBlock, createMenuBlock, createParagraphBlock, createSectionBlock, createSocialIconsBlock, createSpacerBlock, createTableBlock, createTitleBlock, createVideoBlock, deepMergeDefaults, generateId, getLogicMergeTagKeyword, getMergeTagLabel, getMergeTagSample, getSyntaxClosingChar, getSyntaxTriggerChar, hasMergeTagSamples, isButton, isCountdown, isCustomBlock, isDivider, isHtml, isImage, isLogicMergeTagValue, isMenu, isMergeTagValue, isParagraph, isRenderableTemplateContent, isSection, isSocialIcons, isSpacer, isTable, isTitle, isVideo, resolveHtmlLogicMergeTagLabels, resolveHtmlMergeTagLabels, resolveSyntax, restoreMergeTagMarkup, safeClone, substituteHtmlMergeTagSamples, substituteTextMergeTagSamples };
export { type AiChatMessage, type AiConfig, type AiGenerateOptions, type AiScoreOptions, type AiStreamEvent, type ApiError, type ApiResponse, type AuthConfig, type AuthRequestOptions, BUTTON_BLOCK_DEFAULTS, type BaseBlock, type Block, type BlockDefaults, type BlockStyles, type BlockType, type BlockVisibility, type ButtonBlock, COUNTDOWN_BLOCK_DEFAULTS, type CategoryScore, type CollaborationConfig, type Collaborator, type ColorsConfig, type ColumnLayout, type Comment, type CommentEvent, type CommentEventType, type CommentThread, type CountdownBlock, type CreateCommentData, type CustomBlock, type CustomBlockBooleanField, type CustomBlockColorField, type CustomBlockDefinition, type CustomBlockField, type CustomBlockFieldBase, type CustomBlockFieldType, type CustomBlockImageField, type CustomBlockNumberField, type CustomBlockRepeatableField, type CustomBlockSelectField, type CustomBlockTextField, type CustomBlockTextareaField, type CustomFont, DEFAULT_BLOCK_DEFAULTS, DEFAULT_TEMPLATE_DEFAULTS, DIVIDER_BLOCK_DEFAULTS, type DataSourceConfig, type DataSourceFetchContext, type DirectAuthConfig, type DisplayCondition, type DisplayConditionsConfig, type DividerBlock, type EditorState, EventEmitter, type ExportResult, type FindingSeverity, type FontsConfig, HEADING_LEVEL_FONT_SIZE, HTML_BLOCK_DEFAULTS, type HeadingLevel, type HealthCheckResult, type HtmlBlock, IMAGE_BLOCK_DEFAULTS, type ImageBlock, type LogicPair, type LogicTag, type LogicTagsConfig, MENU_BLOCK_DEFAULTS, type McpConfig, type McpOperation, type McpOperationPayload, type MediaResult, type MenuBlock, type MenuItemData, type MergeTag, type MergeTagsConfig, PARAGRAPH_BLOCK_DEFAULTS, type ParagraphBlock, type PlanConfig, type PlanFeatures, type PlanLimits, type PreviewResolveContext, type ProxyAuthConfig, type ResolvePreview, type RewriteData, SECTION_BLOCK_DEFAULTS, SOCIAL_ICONS_BLOCK_DEFAULTS, SOCIAL_ICON_GLYPHS, SPACER_BLOCK_DEFAULTS, SYNTAX_PRESETS, type SaveResult, type SavedBlock, type SavedBlockInput, type SavedBlockPatch, type SavedBlocksListParams, type SavedBlocksProvider, type ScoringCategory, type ScoringFinding, type ScoringResult, type SdkAuthConfig, SdkError, type SectionBlock, type SectionWrapper, type SelectOption, type SocialIcon, type SocialIconGlyph, type SocialIconSize, type SocialIconStyle, type SocialIconsBlock, type SocialPlatform, type SpacerBlock, type SpacingValue, type SyntaxPreset, type SyntaxPresetName, TABLE_BLOCK_DEFAULTS, TITLE_BLOCK_DEFAULTS, type TableBlock, type TableCellData, type TableRowData, type Template, type TemplateContent, type TemplateDefaults, type TemplateSettings, type TemplateSnapshot, type TestEmailConfig, type TestEmailPayload, type TestEmailProvider, type ThemeOverrides, type TitleBlock, type TokenData, type UiTheme, type UpdateCommentData, type UserConfig, VIDEO_BLOCK_DEFAULTS, type VideoBlock, type ViewportSize, type WebSocketServerConfig, cloneBlock, containsMergeTag, createBlock, createButtonBlock, createCountdownBlock, createCustomBlock, createDefaultTemplateContent, createDividerBlock, createHtmlBlock, createImageBlock, createMenuBlock, createParagraphBlock, createSectionBlock, createSocialIconsBlock, createSpacerBlock, createTableBlock, createTitleBlock, createVideoBlock, deepMergeDefaults, findOpenTagEnd, generateId, getLogicMergeTagKeyword, getMergeTagLabel, getMergeTagSample, getSyntaxClosingChar, getSyntaxTriggerChar, getTagAttrValue, hasMergeTagSamples, isButton, isCountdown, isCustomBlock, isDivider, isHtml, isImage, isLogicMergeTagValue, isMenu, isMergeTagValue, isParagraph, isRenderableTemplateContent, isSection, isSocialIcons, isSpacer, isTable, isTitle, isVideo, resolveHtmlLogicMergeTagLabels, resolveHtmlMergeTagLabels, resolveSyntax, restoreMergeTagMarkup, safeClone, substituteHtmlMergeTagSamples, substituteTextMergeTagSamples };
//# sourceMappingURL=index.d.ts.map

@@ -502,2 +502,97 @@ //#region src/blocks.ts

//#endregion
//#region src/html-scan.ts
/**
* Minimal, allocation-free primitives for reading an HTML open tag out of a
* markup string. They exist because merge-tag markup is rewritten from a raw
* string in two packages — `@templatical/types` (label / sample resolution for
* the previews) and `@templatical/renderer` (converting spans back to tokens on
* export) — and both need the same two answers: where does this open tag end,
* and what is the value of one of its attributes.
*
* Both are hand-written character scans rather than regexes. A regex over an
* attribute string with no closing quote backtracks across the whole input,
* which is the ReDoS class the span scanners were rewritten to avoid; a scan
* that only moves forward cannot.
*/
const QUOTES = /* @__PURE__ */ new Set(["\"", "'"]);
/**
* Index of the `>` that closes the open tag whose name ends at `from`, or `-1`
* when the tag never closes.
*
* Quote-aware: a `>` inside a quoted attribute value does not end the tag.
* That matters because a consumer may configure a merge-tag syntax whose tag
* values contain `<` / `>` — Smarty-style `<% $email %>` — and HTML attribute
* serialization escapes only `&`, `"` and U+00A0, so those characters reach the
* markup literally. A plain `indexOf(">")` stops mid-attribute there and every
* caller downstream sees a truncated attribute string.
*
* An unterminated quote yields `-1` rather than a guessed tag end: callers
* treat that as "not markup I can rewrite" and emit the input untouched, which
* is the safe answer for malformed HTML.
*/
function findOpenTagEnd(html, from) {
let quote = null;
for (let i = from; i < html.length; i++) {
const char = html[i];
if (quote !== null) {
if (char === quote) quote = null;
continue;
}
if (QUOTES.has(char)) {
quote = char;
continue;
}
if (char === ">") return i;
}
return -1;
}
function isAttrNameChar(char) {
return char !== " " && char !== " " && char !== "\n" && char !== "\r" && char !== "\f" && char !== "=" && char !== ">" && char !== "/";
}
function isWhitespace(char) {
return char === " " || char === " " || char === "\n" || char === "\r" || char === "\f";
}
/**
* The value of the `name` attribute within an open tag's attribute string (the
* text between the tag name and its closing `>`), or `null` when the attribute
* is absent or its quoted value is never closed.
*
* Handles double-quoted, single-quoted and unquoted values, and matches the
* attribute name case-insensitively, as HTML does. Attribute values are not
* entity-decoded — callers compare them against configured merge-tag tokens,
* which are stored the same way.
*/
function getTagAttrValue(attrs, name) {
const target = name.toLowerCase();
let i = 0;
while (i < attrs.length) {
while (i < attrs.length && (isWhitespace(attrs[i]) || attrs[i] === "/")) i++;
if (i >= attrs.length) break;
const nameStart = i;
while (i < attrs.length && isAttrNameChar(attrs[i])) i++;
const attrName = attrs.substring(nameStart, i).toLowerCase();
if (attrName === "") {
i++;
continue;
}
while (i < attrs.length && isWhitespace(attrs[i])) i++;
if (attrs[i] !== "=") continue;
i++;
while (i < attrs.length && isWhitespace(attrs[i])) i++;
const quote = attrs[i];
if (QUOTES.has(quote)) {
const valueStart = i + 1;
const valueEnd = attrs.indexOf(quote, valueStart);
if (valueEnd === -1) return null;
if (attrName === target) return attrs.substring(valueStart, valueEnd);
i = valueEnd + 1;
continue;
}
const valueStart = i;
while (i < attrs.length && !isWhitespace(attrs[i]) && attrs[i] !== ">") i++;
if (attrName === target) return attrs.substring(valueStart, i);
}
return null;
}
//#endregion
//#region src/merge-tags.ts

@@ -682,5 +777,11 @@ const SYNTAX_PRESETS = {

* no closing `>`.
*
* Tag boundaries and attribute values are resolved by `findOpenTagEnd` /
* `getTagAttrValue`, which are quote-aware. A merge-tag value may itself
* contain `<` / `>` when the consumer configures a custom syntax — Smarty-style
* `<% $email %>` — and those characters survive attribute serialization
* verbatim, so anything that treats the first `>` as the tag end reads a
* truncated attribute and resolves nothing.
*/
function rewriteSpanByAttr(html, attrName, relabel, options) {
const attrPattern = new RegExp(`(?:^|\\s)${attrName}="([^"<>]*)"`);
let out = "";

@@ -700,3 +801,3 @@ let i = 0;

}
const openEnd = html.indexOf(">", open + 5);
const openEnd = findOpenTagEnd(html, open + 5);
if (openEnd === -1) {

@@ -711,5 +812,4 @@ out += html.substring(i);

}
const attrs = html.substring(open + 5, openEnd);
const attrMatch = attrPattern.exec(attrs);
if (!attrMatch) {
const value = getTagAttrValue(html.substring(open + 5, openEnd), attrName);
if (value === null) {
out += html.substring(i, open + 5);

@@ -719,3 +819,2 @@ i = open + 5;

}
const value = attrMatch[1];
const newLabel = relabel(value);

@@ -769,4 +868,4 @@ if (options?.unwrap?.(value)) {

//#endregion
export { BUTTON_BLOCK_DEFAULTS, COUNTDOWN_BLOCK_DEFAULTS, DEFAULT_BLOCK_DEFAULTS, DEFAULT_TEMPLATE_DEFAULTS, DIVIDER_BLOCK_DEFAULTS, EventEmitter, HEADING_LEVEL_FONT_SIZE, HTML_BLOCK_DEFAULTS, IMAGE_BLOCK_DEFAULTS, MENU_BLOCK_DEFAULTS, PARAGRAPH_BLOCK_DEFAULTS, SECTION_BLOCK_DEFAULTS, SOCIAL_ICONS_BLOCK_DEFAULTS, SOCIAL_ICON_GLYPHS, SPACER_BLOCK_DEFAULTS, SYNTAX_PRESETS, SdkError, TABLE_BLOCK_DEFAULTS, TITLE_BLOCK_DEFAULTS, VIDEO_BLOCK_DEFAULTS, cloneBlock, containsMergeTag, createBlock, createButtonBlock, createCountdownBlock, createCustomBlock, createDefaultTemplateContent, createDividerBlock, createHtmlBlock, createImageBlock, createMenuBlock, createParagraphBlock, createSectionBlock, createSocialIconsBlock, createSpacerBlock, createTableBlock, createTitleBlock, createVideoBlock, deepMergeDefaults, generateId, getLogicMergeTagKeyword, getMergeTagLabel, getMergeTagSample, getSyntaxClosingChar, getSyntaxTriggerChar, hasMergeTagSamples, isButton, isCountdown, isCustomBlock, isDivider, isHtml, isImage, isLogicMergeTagValue, isMenu, isMergeTagValue, isParagraph, isRenderableTemplateContent, isSection, isSocialIcons, isSpacer, isTable, isTitle, isVideo, resolveHtmlLogicMergeTagLabels, resolveHtmlMergeTagLabels, resolveSyntax, restoreMergeTagMarkup, safeClone, substituteHtmlMergeTagSamples, substituteTextMergeTagSamples };
export { BUTTON_BLOCK_DEFAULTS, COUNTDOWN_BLOCK_DEFAULTS, DEFAULT_BLOCK_DEFAULTS, DEFAULT_TEMPLATE_DEFAULTS, DIVIDER_BLOCK_DEFAULTS, EventEmitter, HEADING_LEVEL_FONT_SIZE, HTML_BLOCK_DEFAULTS, IMAGE_BLOCK_DEFAULTS, MENU_BLOCK_DEFAULTS, PARAGRAPH_BLOCK_DEFAULTS, SECTION_BLOCK_DEFAULTS, SOCIAL_ICONS_BLOCK_DEFAULTS, SOCIAL_ICON_GLYPHS, SPACER_BLOCK_DEFAULTS, SYNTAX_PRESETS, SdkError, TABLE_BLOCK_DEFAULTS, TITLE_BLOCK_DEFAULTS, VIDEO_BLOCK_DEFAULTS, cloneBlock, containsMergeTag, createBlock, createButtonBlock, createCountdownBlock, createCustomBlock, createDefaultTemplateContent, createDividerBlock, createHtmlBlock, createImageBlock, createMenuBlock, createParagraphBlock, createSectionBlock, createSocialIconsBlock, createSpacerBlock, createTableBlock, createTitleBlock, createVideoBlock, deepMergeDefaults, findOpenTagEnd, generateId, getLogicMergeTagKeyword, getMergeTagLabel, getMergeTagSample, getSyntaxClosingChar, getSyntaxTriggerChar, getTagAttrValue, hasMergeTagSamples, isButton, isCountdown, isCustomBlock, isDivider, isHtml, isImage, isLogicMergeTagValue, isMenu, isMergeTagValue, isParagraph, isRenderableTemplateContent, isSection, isSocialIcons, isSpacer, isTable, isTitle, isVideo, resolveHtmlLogicMergeTagLabels, resolveHtmlMergeTagLabels, resolveSyntax, restoreMergeTagMarkup, safeClone, substituteHtmlMergeTagSamples, substituteTextMergeTagSamples };
//# sourceMappingURL=index.js.map
+2
-2
{
"name": "@templatical/types",
"description": "Shared TypeScript types, block factory functions, and event emitter for Templatical email editor",
"version": "0.26.0",
"version": "0.26.1",
"bugs": "https://github.com/templatical/sdk/issues",

@@ -9,3 +9,3 @@ "devDependencies": {

"vitest": "^4.1.10",
"@templatical/media-library": "0.26.0"
"@templatical/media-library": "0.26.1"
},

@@ -12,0 +12,0 @@ "exports": {

Sorry, the diff of this file is too big to display