@sendbird/actionbook-core 0.10.0 → 0.10.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/dist/index.d.ts CHANGED
@@ -222,6 +222,15 @@ declare function collectAllVariables(structures: JinjaIfStructure[]): Variable[]
222
222
  * @returns true/false if evaluation succeeded, null if parsing/evaluation failed
223
223
  */
224
224
  declare function evaluateCondition(condition: string, variables: Map<string, VariableValue>): boolean | null;
225
+ interface ConditionValidationResult {
226
+ readonly valid: boolean;
227
+ readonly error?: string;
228
+ }
229
+ /**
230
+ * Validate a Jinja conditional expression without evaluating it.
231
+ * Returns a structured result with an error message on failure.
232
+ */
233
+ declare function validateCondition(condition: string): ConditionValidationResult;
225
234
 
226
235
  type HighlightCategory = 'variable' | 'operator' | 'value' | 'punctuation';
227
236
  interface ConditionToken {
@@ -424,4 +433,4 @@ declare function actionbookToAST(manual: {
424
433
  logic: LogicV2;
425
434
  }): DocumentNode;
426
435
 
427
- export { ActionbookConversionError, type ActionbookJSON, AstNode, BlockNode, BlockquoteNode, BoldMark, type BranchDecision, BulletListNode, CodeMark, type ConditionToken, type DecisionTree, type DeleteOp, DeserializationError, DocumentNode, type DocumentTreeNode, type DocumentTreeNodeType, type EnumeratePathsIterOptions, type GotoEdge, type GotoEntryResolution, HardBreakNode, HeadingNode, type HighlightCategory, HorizontalRuleNode, InlineNode, type InsertOp, ItalicMark, type JinjaBlock, JinjaIfBlockNode, JinjaIfBranch, JinjaIfInlineNode, type JinjaIfStructure, type JinjaVisualBranch, type JinjaVisualStructure, JumpPointNode, LinkMark, type LintAsyncOptions, LintContext, LintResult, LintRule, LintSection, ListItemNode, LlmCompletionEndpoint, LlmLintRule, Mark, NodePath, NoteBlockNode, type Operation, OperationError, OrderedListNode, ParagraphNode, type ParseMarkdownOptions, type ReplaceOp, ResourceTagNode, ResourceTagType, StrikethroughMark, TableCellNode, TableNode, TableRowNode, TextNode, type Transaction, type TreeNode, type TreeNodeClassification, type TreeNodeLine, type TreeNodeType, type TreePath, type TreeSection, UnderlineMark, type ValidationError, type Variable, type VariableValue, type VisitOptions, actionbookToAST, analyzeJinjaBlocks, applyOperation, applyTransaction, blockquote, bold, buildDocumentTree, bulletList, chunkByHeading, code, collectAllVariables, comparePaths, defaultLlmRules, defaultRules, deserializeFromJSON, doc, enumeratePaths, enumeratePathsBySection, enumeratePathsIter, evaluateCondition, evaluateJinjaNodes, extractResourceTags, extractVariables, findAll, findDuplicateJumpPoints, fromMdast, generateDecisionTree, hardBreak, heading, horizontalRule, invertOperation, isBlock, isDocument, isInline, isTextNode, italic, jinjaBranch, jinjaIfBlock, jinjaIfInline, jumpPoint, link, lint, lintAsync, listItem, map, nodeAtPath, noteBlock, orderedList, paragraph, parentPath, parseFragment, parseMarkdown, pathFromString, pathToString, resolveGotoEntryPath, resourceTag, scanJinjaBlocks, serializeFragment, serializeToJSON, serializeToMarkdown, strikethrough, structureJinjaBlocks, table, tableCell, tableRow, text, textContent, toMdast, todoItem, tokenizeCondition, underline, validate, visit };
436
+ export { ActionbookConversionError, type ActionbookJSON, AstNode, BlockNode, BlockquoteNode, BoldMark, type BranchDecision, BulletListNode, CodeMark, type ConditionToken, type ConditionValidationResult, type DecisionTree, type DeleteOp, DeserializationError, DocumentNode, type DocumentTreeNode, type DocumentTreeNodeType, type EnumeratePathsIterOptions, type GotoEdge, type GotoEntryResolution, HardBreakNode, HeadingNode, type HighlightCategory, HorizontalRuleNode, InlineNode, type InsertOp, ItalicMark, type JinjaBlock, JinjaIfBlockNode, JinjaIfBranch, JinjaIfInlineNode, type JinjaIfStructure, type JinjaVisualBranch, type JinjaVisualStructure, JumpPointNode, LinkMark, type LintAsyncOptions, LintContext, LintResult, LintRule, LintSection, ListItemNode, LlmCompletionEndpoint, LlmLintRule, Mark, NodePath, NoteBlockNode, type Operation, OperationError, OrderedListNode, ParagraphNode, type ParseMarkdownOptions, type ReplaceOp, ResourceTagNode, ResourceTagType, StrikethroughMark, TableCellNode, TableNode, TableRowNode, TextNode, type Transaction, type TreeNode, type TreeNodeClassification, type TreeNodeLine, type TreeNodeType, type TreePath, type TreeSection, UnderlineMark, type ValidationError, type Variable, type VariableValue, type VisitOptions, actionbookToAST, analyzeJinjaBlocks, applyOperation, applyTransaction, blockquote, bold, buildDocumentTree, bulletList, chunkByHeading, code, collectAllVariables, comparePaths, defaultLlmRules, defaultRules, deserializeFromJSON, doc, enumeratePaths, enumeratePathsBySection, enumeratePathsIter, evaluateCondition, evaluateJinjaNodes, extractResourceTags, extractVariables, findAll, findDuplicateJumpPoints, fromMdast, generateDecisionTree, hardBreak, heading, horizontalRule, invertOperation, isBlock, isDocument, isInline, isTextNode, italic, jinjaBranch, jinjaIfBlock, jinjaIfInline, jumpPoint, link, lint, lintAsync, listItem, map, nodeAtPath, noteBlock, orderedList, paragraph, parentPath, parseFragment, parseMarkdown, pathFromString, pathToString, resolveGotoEntryPath, resourceTag, scanJinjaBlocks, serializeFragment, serializeToJSON, serializeToMarkdown, strikethrough, structureJinjaBlocks, table, tableCell, tableRow, text, textContent, toMdast, todoItem, tokenizeCondition, underline, validate, validateCondition, visit };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/ast/types.ts
2
2
  var RESOURCE_TAG_TYPES = ["tool", "manual", "agent_message_template", "handoff", "time_diff", "time_difference"];
3
- var JUMP_POINT_ID_PATTERN = /^[A-Za-z_]+$/;
3
+ var JUMP_POINT_ID_PATTERN = /^[\p{L}\p{N}_-]+$/u;
4
4
 
5
5
  // src/ast/builders.ts
6
6
  var bold = () => ({ type: "bold" });
@@ -18,7 +18,7 @@ var resourceTag = (tagType, resourceId, displayText) => ({
18
18
  });
19
19
  var jumpPoint = (id) => {
20
20
  if (!JUMP_POINT_ID_PATTERN.test(id)) {
21
- throw new Error(`Invalid jump point ID: "${id}". Must match /^[A-Za-z_]+$/.`);
21
+ throw new Error(`Invalid jump point ID: "${id}". Letters, numbers, underscore, and hyphen only.`);
22
22
  }
23
23
  return { type: "jumpPoint", id };
24
24
  };
@@ -2134,7 +2134,7 @@ function resourceTagToMarkdown() {
2134
2134
  }
2135
2135
 
2136
2136
  // src/markdown/plugins/jumpPoint.ts
2137
- var JUMP_POINT_RE = /\^([A-Za-z_]+)\^/g;
2137
+ var JUMP_POINT_RE = /\^([\p{L}\p{N}_-]+)\^/gu;
2138
2138
  function splitTextWithJumpPoints(text2) {
2139
2139
  const results = [];
2140
2140
  let lastIndex = 0;
@@ -3627,7 +3627,7 @@ function tokenize(input) {
3627
3627
  i++;
3628
3628
  }
3629
3629
  }
3630
- if (i >= input.length) return [];
3630
+ if (i >= input.length) return { tokens: [], error: "Unterminated string literal" };
3631
3631
  i++;
3632
3632
  tokens.push({ type: "STRING", value: str });
3633
3633
  continue;
@@ -3710,10 +3710,10 @@ function tokenize(input) {
3710
3710
  i++;
3711
3711
  continue;
3712
3712
  }
3713
- return [];
3713
+ return { tokens: [], error: `Unexpected character: ${input[i]}` };
3714
3714
  }
3715
3715
  tokens.push({ type: "EOF", value: "" });
3716
- return tokens;
3716
+ return { tokens };
3717
3717
  }
3718
3718
  var Parser = class {
3719
3719
  pos = 0;
@@ -3892,8 +3892,8 @@ function toNumber(v) {
3892
3892
  }
3893
3893
  function evaluateCondition(condition, variables) {
3894
3894
  try {
3895
- const tokens = tokenize(condition.trim());
3896
- if (tokens.length === 0) return null;
3895
+ const { tokens, error } = tokenize(condition.trim());
3896
+ if (error || tokens.length === 0) return null;
3897
3897
  const parser = new Parser(tokens, variables);
3898
3898
  const result = parser.evaluate();
3899
3899
  return isTruthy(result);
@@ -3901,6 +3901,21 @@ function evaluateCondition(condition, variables) {
3901
3901
  return null;
3902
3902
  }
3903
3903
  }
3904
+ function validateCondition(condition) {
3905
+ const trimmed = condition.trim();
3906
+ if (trimmed === "") return { valid: true };
3907
+ const { tokens, error: tokenError } = tokenize(trimmed);
3908
+ if (tokenError) return { valid: false, error: tokenError };
3909
+ if (tokens.length === 0) return { valid: false, error: "Empty expression" };
3910
+ try {
3911
+ const parser = new Parser(tokens, /* @__PURE__ */ new Map());
3912
+ parser.evaluate();
3913
+ return { valid: true };
3914
+ } catch (e) {
3915
+ const msg = e instanceof Error ? e.message : "Invalid expression";
3916
+ return { valid: false, error: msg };
3917
+ }
3918
+ }
3904
3919
 
3905
3920
  // src/jinja/conditionHighlighter.ts
3906
3921
  var KEYWORDS3 = {
@@ -4325,7 +4340,7 @@ var duplicateJumpPoints = {
4325
4340
  };
4326
4341
 
4327
4342
  // src/lint/rules/jumpPointRefValidity.ts
4328
- var JUMP_REF_PATTERN = /#([A-Za-z_]+)/g;
4343
+ var JUMP_REF_PATTERN = /#([\p{L}\p{N}_-]+)/gu;
4329
4344
  var jumpPointRefValidity = {
4330
4345
  id: "jump-point-ref-validity",
4331
4346
  description: "Detects references to non-existent jump point IDs",
@@ -4349,7 +4364,7 @@ var jumpPointRefValidity = {
4349
4364
  const t = node;
4350
4365
  const linkMark = t.marks?.find((m2) => m2.type === "link");
4351
4366
  if (linkMark && linkMark.type === "link") {
4352
- const match = /^#([A-Za-z_]+)$/.exec(linkMark.href);
4367
+ const match = /^#([\p{L}\p{N}_-]+)$/u.exec(linkMark.href);
4353
4368
  if (match) {
4354
4369
  refs.push({ id: match[1] });
4355
4370
  }
@@ -4848,7 +4863,7 @@ function classifyNode(node) {
4848
4863
  }
4849
4864
  function hasSpeechContent(node) {
4850
4865
  for (const line of node.lines) {
4851
- const stripped = line.content.replace(/\{\{[^}]+\}\}/g, "").replace(/\^[A-Za-z_]+\^/g, "").replace(/\[[^\]]*\]\(#[^)]+\)/g, "").trim();
4866
+ const stripped = line.content.replace(/\{\{[^}]+\}\}/g, "").replace(/\^[\p{L}\p{N}_-]+\^/gu, "").replace(/\[[^\]]*\]\(#[^)]+\)/g, "").trim();
4852
4867
  if (stripped.length > 0) return true;
4853
4868
  }
4854
4869
  return false;
@@ -5795,6 +5810,7 @@ export {
5795
5810
  tokenizeCondition,
5796
5811
  underline,
5797
5812
  validate,
5813
+ validateCondition,
5798
5814
  visit
5799
5815
  };
5800
5816
  //# sourceMappingURL=index.js.map