@tokens-studio/tokenscript-interpreter 0.32.0 → 0.34.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.
Files changed (70) hide show
  1. package/dist/chunk-33CDF4L4.js +6444 -0
  2. package/dist/chunk-33CDF4L4.js.map +1 -0
  3. package/dist/chunk-AXH5N7KV.js +99 -0
  4. package/dist/chunk-AXH5N7KV.js.map +1 -0
  5. package/dist/chunk-QP7M6WUR.js +6227 -0
  6. package/dist/chunk-QP7M6WUR.js.map +1 -0
  7. package/dist/cli.js +242 -2
  8. package/dist/cli.js.map +1 -1
  9. package/dist/compliance-suite.js +2 -2
  10. package/dist/config-DtbN3iyg.d.ts +918 -0
  11. package/dist/lib/{chunk-QYRJ6NSL.cjs → chunk-LEYHQJTL.cjs} +3 -2
  12. package/dist/lib/chunk-LEYHQJTL.cjs.map +1 -0
  13. package/dist/lib/{chunk-GKSWF7FF.cjs → chunk-LMGHS2NP.cjs} +102 -100
  14. package/dist/lib/chunk-LMGHS2NP.cjs.map +1 -0
  15. package/dist/lib/{chunk-LI2D53SH.js → chunk-LSTH2XJ4.js} +5 -3
  16. package/dist/lib/chunk-LSTH2XJ4.js.map +1 -0
  17. package/dist/lib/{chunk-YD3MIYOO.js → chunk-ODVWXGOM.js} +3 -2
  18. package/dist/lib/chunk-ODVWXGOM.js.map +1 -0
  19. package/dist/lib/{chunk-UYVHWJIC.js → chunk-RWXDOZAS.js} +250 -5
  20. package/dist/lib/chunk-RWXDOZAS.js.map +1 -0
  21. package/dist/lib/{chunk-QGOGK2VP.cjs → chunk-YCIBJDRB.cjs} +790 -543
  22. package/dist/lib/chunk-YCIBJDRB.cjs.map +1 -0
  23. package/dist/lib/index.cjs +97 -89
  24. package/dist/lib/index.d.cts +5 -5
  25. package/dist/lib/index.d.ts +5 -5
  26. package/dist/lib/index.js +3 -3
  27. package/dist/lib/{interpreter-DNmBc--s.d.ts → interpreter-6QwMkUqD.d.cts} +30 -2
  28. package/dist/lib/{interpreter-CP7CNwDa.d.cts → interpreter-v7WiwSP9.d.ts} +30 -2
  29. package/dist/lib/interpreter.cjs +73 -73
  30. package/dist/lib/interpreter.d.cts +4 -4
  31. package/dist/lib/interpreter.d.ts +4 -4
  32. package/dist/lib/interpreter.js +3 -3
  33. package/dist/lib/processor-node.cjs +12 -12
  34. package/dist/lib/processor-node.d.cts +3 -3
  35. package/dist/lib/processor-node.d.ts +3 -3
  36. package/dist/lib/processor-node.js +3 -3
  37. package/dist/lib/processor.cjs +23 -15
  38. package/dist/lib/processor.d.cts +18 -5
  39. package/dist/lib/processor.d.ts +18 -5
  40. package/dist/lib/processor.js +3 -3
  41. package/dist/lib/schema.cjs +5 -5
  42. package/dist/lib/schema.d.cts +1 -1
  43. package/dist/lib/schema.d.ts +1 -1
  44. package/dist/lib/schema.js +3 -3
  45. package/dist/lib/syntax-highlighting.cjs +15 -15
  46. package/dist/lib/syntax-highlighting.d.cts +1 -1
  47. package/dist/lib/syntax-highlighting.d.ts +1 -1
  48. package/dist/lib/syntax-highlighting.js +2 -2
  49. package/dist/lib/{types-DHgmzR1Z.d.ts → types-BI0AZ4Ej.d.ts} +2 -2
  50. package/dist/lib/{types-BimJex2v.d.cts → types-EB8V9c46.d.cts} +1 -0
  51. package/dist/lib/{types-BimJex2v.d.ts → types-EB8V9c46.d.ts} +1 -0
  52. package/dist/lib/{types-DsJuwrq3.d.cts → types-cFwP43uv.d.cts} +2 -2
  53. package/dist/lib/types.cjs +6 -6
  54. package/dist/lib/types.d.cts +1 -1
  55. package/dist/lib/types.d.ts +1 -1
  56. package/dist/lib/types.js +1 -1
  57. package/dist/processor/index.d.ts +15 -2
  58. package/dist/processor/index.js +24 -3
  59. package/dist/processor/index.js.map +1 -1
  60. package/dist/repl.d.ts +1 -1
  61. package/dist/repl.js +2 -2
  62. package/dist/types.d.ts +1 -1
  63. package/dist/types.js +1 -1
  64. package/package.json +1 -1
  65. package/dist/lib/chunk-GKSWF7FF.cjs.map +0 -1
  66. package/dist/lib/chunk-LI2D53SH.js.map +0 -1
  67. package/dist/lib/chunk-QGOGK2VP.cjs.map +0 -1
  68. package/dist/lib/chunk-QYRJ6NSL.cjs.map +0 -1
  69. package/dist/lib/chunk-UYVHWJIC.js.map +0 -1
  70. package/dist/lib/chunk-YD3MIYOO.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { DictionarySymbol, serializeInterpreterResult, stringifyInterpreterResult, isSome, LexerError, isSpace, isNumber2, isAlpha, isAlphaNumeric, ParserError, isLanguageError, NullSymbol, isTokenscriptSymbol, StringSymbol, NumberWithUnitSymbol, NumberSymbol, InterpreterError, BooleanSymbol, isNull, jsValueToSymbolType, ListSymbol, parseHexWithAlpha, ColorSymbol, basicSymbolTypes, typeName, typeEquals, ProcessorError, isObject, TokenSymbol, isArray, isString, getKeyAlt, isNumber, isBoolean, safeParseInt, serializeError, ensureValidAlpha, formatHex8, isTransparent, getResultTypeName, LanguageError } from './chunk-LI2D53SH.js';
2
- import { __name, SupportedFormats, ReservedKeyword, __export, UNINTERPRETED_KEYWORDS } from './chunk-YD3MIYOO.js';
1
+ import { DictionarySymbol, serializeInterpreterResult, stringifyInterpreterResult, isSome, LexerError, isSpace, isNumber2, isAlpha, isAlphaNumeric, ParserError, isLanguageError, NullSymbol, isTokenscriptSymbol, StringSymbol, NumberWithUnitSymbol, NumberSymbol, InterpreterError, BooleanSymbol, isNull, jsValueToSymbolType, ListSymbol, ColorSymbol, parseHexWithAlpha, basicSymbolTypes, typeName, typeEquals, ProcessorError, isObject, TokenSymbol, isArray, isString, getKeyAlt, isNumber, isBoolean, safeParseInt, serializeError, ensureValidAlpha, formatHex8, isTransparent, getResultTypeName, LanguageError } from './chunk-LSTH2XJ4.js';
2
+ import { __name, SupportedFormats, ReservedKeyword, __export, UNINTERPRETED_KEYWORDS } from './chunk-ODVWXGOM.js';
3
3
  import { z, Color, Fn, Token, Unit, Constants, ZodError } from '@tokens-studio/schema-validation';
4
4
 
5
5
  // src/interpreter/tolerant/partial-nodes.ts
@@ -105,6 +105,15 @@ var _StringNode = class _StringNode {
105
105
  };
106
106
  __name(_StringNode, "StringNode");
107
107
  var StringNode = _StringNode;
108
+ var _TemplateStringNode = class _TemplateStringNode {
109
+ constructor(parts, token) {
110
+ this.parts = parts;
111
+ this.token = token;
112
+ this.nodeType = "TemplateStringNode";
113
+ }
114
+ };
115
+ __name(_TemplateStringNode, "TemplateStringNode");
116
+ var TemplateStringNode = _TemplateStringNode;
108
117
  var _UnaryOpNode = class _UnaryOpNode {
109
118
  constructor(opToken, expr, token) {
110
119
  this.opToken = opToken;
@@ -402,6 +411,10 @@ function walkAST(node, onVisit) {
402
411
  for (const statement of node.statements) {
403
412
  walkAST(statement, onVisit);
404
413
  }
414
+ } else if (node instanceof TemplateStringNode) {
415
+ for (const part of node.parts) {
416
+ walkAST(part, onVisit);
417
+ }
405
418
  } else if (node instanceof AttributeAccessNode) {
406
419
  walkAST(node.left, onVisit);
407
420
  if (node.right instanceof FunctionCallNode || node.right instanceof PartialFunctionCallNode) {
@@ -711,6 +724,51 @@ var _Lexer = class _Lexer {
711
724
  endPos: this.pos
712
725
  };
713
726
  }
727
+ /**
728
+ * Read a backtick-delimited template string.
729
+ * Supports escape sequences: \{ \$ \` \\
730
+ * The raw content (with escapes preserved) is stored as the token value.
731
+ * The parser handles splitting into segments.
732
+ */
733
+ templateString() {
734
+ const startPos = this.pos;
735
+ this.eat("`");
736
+ let result = "";
737
+ while (this.currentChar !== null && this.currentChar !== "`") {
738
+ if (this.currentChar === "\\") {
739
+ const next = this.peek();
740
+ if (next === "{" || next === "$" || next === "`" || next === "\\") {
741
+ result += "\\";
742
+ result += next;
743
+ this.advance();
744
+ this.advance();
745
+ continue;
746
+ }
747
+ }
748
+ result += this.currentChar;
749
+ this.advance();
750
+ }
751
+ if (this.currentChar === null) {
752
+ if (this.tolerant) {
753
+ return {
754
+ type: "TEMPLATE_STRING" /* TEMPLATE_STRING */,
755
+ value: result,
756
+ line: this.line,
757
+ pos: startPos,
758
+ endPos: this.pos
759
+ };
760
+ }
761
+ this.error("LEXER_UNTERMINATED_TEMPLATE_STRING" /* UNTERMINATED_TEMPLATE_STRING */, {});
762
+ }
763
+ this.eat("`");
764
+ return {
765
+ type: "TEMPLATE_STRING" /* TEMPLATE_STRING */,
766
+ value: result,
767
+ line: this.line,
768
+ pos: startPos,
769
+ endPos: this.pos
770
+ };
771
+ }
714
772
  hexColor() {
715
773
  const startPos = this.pos;
716
774
  let result = "";
@@ -761,6 +819,9 @@ var _Lexer = class _Lexer {
761
819
  if (this.currentChar === "'" || this.currentChar === '"') {
762
820
  return this.collectToken(this.explicitString(this.currentChar));
763
821
  }
822
+ if (this.currentChar === "`") {
823
+ return this.collectToken(this.templateString());
824
+ }
764
825
  if (this.isValidIdentifierStart(this.currentChar)) {
765
826
  return this.collectToken(this.stringElement());
766
827
  }
@@ -1687,6 +1748,9 @@ ${contextText}`;
1687
1748
  node = this.attributeAccess(node);
1688
1749
  return node;
1689
1750
  }
1751
+ if (token.type === "TEMPLATE_STRING" /* TEMPLATE_STRING */) {
1752
+ return this.templateString();
1753
+ }
1690
1754
  if (token.type === "EXPLICIT_STRING" /* EXPLICIT_STRING */) {
1691
1755
  this.eat("EXPLICIT_STRING" /* EXPLICIT_STRING */);
1692
1756
  let node = new StringNode(token);
@@ -1746,6 +1810,122 @@ ${contextText}`;
1746
1810
  this.eat("RPAREN" /* RPAREN */);
1747
1811
  return new FunctionCallNode(functionName.value, args, functionName);
1748
1812
  }
1813
+ /**
1814
+ * Parse a TEMPLATE_STRING token into a TemplateStringNode.
1815
+ * Scans the raw content for:
1816
+ * - {ref.path} → ReferenceNode
1817
+ * - ${expression} → parsed sub-expression
1818
+ * - \{ \${ \` \\ → escaped literals (backslash removed)
1819
+ * - everything else → literal StringNode segments
1820
+ */
1821
+ templateString() {
1822
+ const token = this.currentToken;
1823
+ const raw = token.value;
1824
+ this.eat("TEMPLATE_STRING" /* TEMPLATE_STRING */);
1825
+ const parts = [];
1826
+ let literal = "";
1827
+ let i = 0;
1828
+ const flushLiteral = /* @__PURE__ */ __name(() => {
1829
+ if (literal.length > 0) {
1830
+ parts.push(new StringNode({ ...token, value: literal }));
1831
+ literal = "";
1832
+ }
1833
+ }, "flushLiteral");
1834
+ while (i < raw.length) {
1835
+ const ch = raw[i];
1836
+ if (ch === "\\" && i + 1 < raw.length) {
1837
+ const next = raw[i + 1];
1838
+ if (next === "{" || next === "`" || next === "\\") {
1839
+ literal += next;
1840
+ i += 2;
1841
+ continue;
1842
+ }
1843
+ if (next === "$") {
1844
+ if (i + 2 < raw.length && raw[i + 2] === "{") {
1845
+ literal += "${";
1846
+ i += 3;
1847
+ } else {
1848
+ literal += "$";
1849
+ i += 2;
1850
+ }
1851
+ continue;
1852
+ }
1853
+ }
1854
+ if (ch === "$" && i + 1 < raw.length && raw[i + 1] === "{") {
1855
+ flushLiteral();
1856
+ const start = i + 2;
1857
+ let depth = 1;
1858
+ let j = start;
1859
+ while (j < raw.length && depth > 0) {
1860
+ if (raw[j] === "`") {
1861
+ this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
1862
+ message: "Nested template strings are not allowed inside ${...}"
1863
+ });
1864
+ }
1865
+ if (raw[j] === "{") depth++;
1866
+ else if (raw[j] === "}") depth--;
1867
+ if (depth > 0) j++;
1868
+ }
1869
+ if (depth !== 0) {
1870
+ this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
1871
+ message: "Unterminated ${...} in template string"
1872
+ });
1873
+ }
1874
+ const exprStr = raw.slice(start, j);
1875
+ const subLexer = new Lexer(exprStr);
1876
+ const subParser = new _Parser(subLexer);
1877
+ const exprNode = subParser.expr();
1878
+ for (const ref of subParser.requiredReferences) {
1879
+ this.requiredReferences.add(ref);
1880
+ }
1881
+ parts.push(exprNode);
1882
+ i = j + 1;
1883
+ continue;
1884
+ }
1885
+ if (ch === "{") {
1886
+ flushLiteral();
1887
+ const start = i + 1;
1888
+ let j = start;
1889
+ while (j < raw.length && raw[j] !== "}") {
1890
+ if (raw[j] === "{") {
1891
+ this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
1892
+ message: "Nested braces in template reference"
1893
+ });
1894
+ }
1895
+ j++;
1896
+ }
1897
+ if (j >= raw.length) {
1898
+ this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
1899
+ message: "Unterminated {ref} in template string"
1900
+ });
1901
+ }
1902
+ let refPath = raw.slice(start, j);
1903
+ refPath = refPath.replace(/[ \t]/g, "");
1904
+ if (refPath.length === 0) {
1905
+ this.error("PARSER_INVALID_SYNTAX" /* INVALID_SYNTAX */, {
1906
+ message: "Empty reference in template string"
1907
+ });
1908
+ }
1909
+ this.requiredReferences.add(refPath);
1910
+ parts.push(
1911
+ new ReferenceNode({
1912
+ ...token,
1913
+ type: "REFERENCE" /* REFERENCE */,
1914
+ value: refPath
1915
+ })
1916
+ );
1917
+ i = j + 1;
1918
+ continue;
1919
+ }
1920
+ literal += ch;
1921
+ i++;
1922
+ }
1923
+ flushLiteral();
1924
+ if (parts.length === 1 && parts[0] instanceof StringNode) {
1925
+ return parts[0];
1926
+ }
1927
+ return new TemplateStringNode(parts, token);
1928
+ }
1749
1929
  parse(inlineMode = false) {
1750
1930
  if (this.tolerant && !inlineMode) {
1751
1931
  this.error("PARSER_TOLERANT_REQUIRES_INLINE" /* TOLERANT_REQUIRES_INLINE */);
@@ -2492,6 +2672,47 @@ var _Interpreter = class _Interpreter {
2492
2672
  visitStringNode(node) {
2493
2673
  return new StringSymbol(node.value, this.config);
2494
2674
  }
2675
+ visitTemplateStringNode(node) {
2676
+ if (node.parts.length === 0) {
2677
+ return new StringSymbol("", this.config);
2678
+ }
2679
+ if (node.parts.length === 1) {
2680
+ const val = this.visit(node.parts[0]);
2681
+ this.validateTemplateValue(val, node);
2682
+ return val;
2683
+ }
2684
+ let result = "";
2685
+ for (const part of node.parts) {
2686
+ const val = this.visit(part);
2687
+ this.validateTemplateValue(val, node);
2688
+ result += val.toString();
2689
+ }
2690
+ return new StringSymbol(result, this.config);
2691
+ }
2692
+ /**
2693
+ * Validate that a value is a primitive type allowed in template string interpolation.
2694
+ * Lists, Dictionaries, and non-hex Colors are rejected.
2695
+ */
2696
+ validateTemplateValue(val, node) {
2697
+ if (val instanceof ListSymbol) {
2698
+ throw new InterpreterError("INT_TEMPLATE_INVALID_TYPE" /* TEMPLATE_INVALID_TYPE */, {
2699
+ token: node.token,
2700
+ data: { valueType: "List" }
2701
+ });
2702
+ }
2703
+ if (val instanceof DictionarySymbol) {
2704
+ throw new InterpreterError("INT_TEMPLATE_INVALID_TYPE" /* TEMPLATE_INVALID_TYPE */, {
2705
+ token: node.token,
2706
+ data: { valueType: "Dictionary" }
2707
+ });
2708
+ }
2709
+ if (val instanceof ColorSymbol && !val.isHex()) {
2710
+ throw new InterpreterError("INT_TEMPLATE_INVALID_TYPE" /* TEMPLATE_INVALID_TYPE */, {
2711
+ token: node.token,
2712
+ data: { valueType: `Color.${val.subType}` }
2713
+ });
2714
+ }
2715
+ }
2495
2716
  /**
2496
2717
  * Bare identifiers are treated as string literals if not found as variables
2497
2718
  * Check symbol table first (variables override references), then references
@@ -3211,6 +3432,21 @@ var _DependencyGraph = class _DependencyGraph {
3211
3432
  __name(_DependencyGraph, "DependencyGraph");
3212
3433
  var DependencyGraph = _DependencyGraph;
3213
3434
 
3435
+ // src/processor/utils/name-validation.ts
3436
+ var INVALID_TOKEN_NAME_CHARS = /[ \t\n\r\f{}[\]]/;
3437
+ function validateTokenName(name) {
3438
+ return name.length > 0 && !INVALID_TOKEN_NAME_CHARS.test(name);
3439
+ }
3440
+ __name(validateTokenName, "validateTokenName");
3441
+ function splitTokenPath(path) {
3442
+ return path.split(".");
3443
+ }
3444
+ __name(splitTokenPath, "splitTokenPath");
3445
+ function validateTokenPath(path) {
3446
+ return splitTokenPath(path).every(validateTokenName);
3447
+ }
3448
+ __name(validateTokenPath, "validateTokenPath");
3449
+
3214
3450
  // src/processor/utils/structured-tokens.ts
3215
3451
  function matchesObjectParser(value, parsers) {
3216
3452
  if (!isObject(value)) return false;
@@ -3648,6 +3884,15 @@ var _PrefixResolver = class _PrefixResolver {
3648
3884
  parseAndBuildGraph() {
3649
3885
  this.earlyResolved = [];
3650
3886
  for (const [tokenName, tokenData] of this.tokens.entries()) {
3887
+ if (!validateTokenPath(tokenName)) {
3888
+ this.addIssue(tokenName, {
3889
+ code: "INVALID_TOKEN_NAME",
3890
+ severity: "error" /* ERROR */,
3891
+ message: `token "${tokenName}" contains invalid characters in name (spaces, braces, or brackets are not allowed)`,
3892
+ tokenName,
3893
+ data: { path: tokenName }
3894
+ });
3895
+ }
3651
3896
  const tokenValue = getTokenValue(tokenData);
3652
3897
  if (isString(tokenValue) && UNINTERPRETED_KEYWORDS.includes(tokenValue)) {
3653
3898
  const symbol = new StringSymbol(tokenValue, this.config);
@@ -6999,6 +7244,6 @@ var ASTNodes = {
6999
7244
  UnaryOpNode
7000
7245
  };
7001
7246
 
7002
- export { ASTNodes, ColorManager, ColorSpecificationSchema, Config, ConstantsSpecificationSchema, DEFAULT_LANGUAGE_OPTIONS, FunctionSpecificationSchema, FunctionsManager, IncompleteType, Interpreter, Lexer, ParseState, Parser, PartialBinOpNode, PartialFunctionCallNode, PartialParenNode, PartialReferenceNode, PartialStringNode, PartialUnaryOpNode, TokenResolver, UnitManager, UnitSpecificationSchema, ValidationSeverity, buildTokens, builders_exports, collectAllReferences, collectReferenceNodes, errorClasses, errorHelpers, evaluateExpression, fetchAndRegisterSchemas, fetchTokenScriptSchema, filterAST, flattenChildrenMap, flattenChildrenObject, getAffectedTokens, getBrokenReferences, getModifiedDependants, getRenamedReferences, hasPartialNodes, parseExpression, parseTolerantly, processTokenSets, processTokens, renameReferences, tokenizeTolerantly, walkAST };
7003
- //# sourceMappingURL=chunk-UYVHWJIC.js.map
7004
- //# sourceMappingURL=chunk-UYVHWJIC.js.map
7247
+ export { ASTNodes, ColorManager, ColorSpecificationSchema, Config, ConstantsSpecificationSchema, DEFAULT_LANGUAGE_OPTIONS, FunctionSpecificationSchema, FunctionsManager, IncompleteType, Interpreter, Lexer, ParseState, Parser, PartialBinOpNode, PartialFunctionCallNode, PartialParenNode, PartialReferenceNode, PartialStringNode, PartialUnaryOpNode, TokenResolver, UnitManager, UnitSpecificationSchema, ValidationSeverity, buildTokens, builders_exports, collectAllReferences, collectReferenceNodes, errorClasses, errorHelpers, evaluateExpression, fetchAndRegisterSchemas, fetchTokenScriptSchema, filterAST, flattenChildrenMap, flattenChildrenObject, getAffectedTokens, getBrokenReferences, getModifiedDependants, getRenamedReferences, hasPartialNodes, parseExpression, parseTolerantly, processTokenSets, processTokens, renameReferences, tokenizeTolerantly, validateTokenName, validateTokenPath, walkAST };
7248
+ //# sourceMappingURL=chunk-RWXDOZAS.js.map
7249
+ //# sourceMappingURL=chunk-RWXDOZAS.js.map