@aperturesyndicate/synx-format 3.6.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/LICENSE +21 -0
- package/README.md +144 -0
- package/SPECIFICATION.md +6 -0
- package/bin/synx.js +146 -0
- package/dist/browser.d.ts +17 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +72 -0
- package/dist/browser.js.map +1 -0
- package/dist/calc.d.ts +16 -0
- package/dist/calc.d.ts.map +1 -0
- package/dist/calc.js +140 -0
- package/dist/calc.js.map +1 -0
- package/dist/demo-browser.html +153 -0
- package/dist/engine.d.ts +9 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +970 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.d.ts +193 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +810 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +12 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +442 -0
- package/dist/parser.js.map +1 -0
- package/dist/synx.browser.js +29 -0
- package/dist/synx.browser.js.map +7 -0
- package/dist/synx.browser.mjs +28 -0
- package/dist/synx.browser.mjs.map +7 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/parser.ts", "../src/calc.ts", "../src/engine.ts", "../src/types.ts", "../src/browser.ts"],
|
|
4
|
+
"sourcesContent": ["/**\r\n * SYNX Parser \u2014 @aperturesyndicate/synx\r\n *\r\n * Converts raw .synx text into a structured object tree\r\n * with hidden metadata (__synx) for the Engine to resolve.\r\n *\r\n * Performance-optimized: charCode-based parsing, fast path\r\n * for simple key-value lines, no regex on hot paths.\r\n */\r\n\r\nimport type {\r\n SynxObject,\r\n SynxArray,\r\n SynxValue,\r\n SynxMode,\r\n SynxParseResult,\r\n SynxInclude,\r\n SynxMeta,\r\n SynxMetaMap,\r\n SynxConstraints,\r\n} from './types';\r\n\r\n// \u2500\u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Cast a raw string value to a JS primitive */\r\nfunction castType(val: string): SynxValue {\r\n if (val === 'true') return true;\r\n if (val === 'false') return false;\r\n if (val === 'null') return null;\r\n\r\n const len = val.length;\r\n if (len === 0) return val;\r\n\r\n const c0 = val.charCodeAt(0);\r\n\r\n // Explicit cast: (int)007, (string)90210, (float)3.0, (bool)true, (random), (random:bool)\r\n if (c0 === 40 && len > 2) { // '('\r\n const closeIdx = val.indexOf(')');\r\n if (closeIdx > 1) {\r\n const hint = val.substring(1, closeIdx);\r\n const raw = val.substring(closeIdx + 1);\r\n switch (hint) {\r\n case 'int': { const n = parseInt(raw, 10); return isNaN(n) ? 0 : n; }\r\n case 'float': { const n = parseFloat(raw); return isNaN(n) ? 0 : n; }\r\n case 'bool': return raw.trim() === 'true';\r\n case 'string': return raw;\r\n case 'random': return Math.floor(Math.random() * 2147483647);\r\n case 'random:int': return Math.floor(Math.random() * 2147483647);\r\n case 'random:float': return Math.random();\r\n case 'random:bool': return Math.random() < 0.5;\r\n }\r\n }\r\n }\r\n\r\n // Auto number detection via charCode (no regex)\r\n let firstDigit = 0;\r\n let fc = c0;\r\n if (fc === 45) { // '-'\r\n if (len === 1) return val;\r\n firstDigit = 1;\r\n fc = val.charCodeAt(1);\r\n }\r\n if (fc >= 48 && fc <= 57) { // '0'-'9'\r\n let allNumeric = true;\r\n let dotPos = -1;\r\n for (let i = firstDigit + 1; i < len; i++) {\r\n const ch = val.charCodeAt(i);\r\n if (ch === 46) { // '.'\r\n if (dotPos !== -1) { allNumeric = false; break; }\r\n dotPos = i;\r\n } else if (ch < 48 || ch > 57) {\r\n allNumeric = false;\r\n break;\r\n }\r\n }\r\n if (allNumeric) {\r\n if (dotPos === -1) return parseInt(val, 10);\r\n if (dotPos > firstDigit && dotPos < len - 1) return parseFloat(val);\r\n }\r\n }\r\n\r\n return val;\r\n}\r\n\r\n/** Strip inline comment from a value string */\r\nfunction stripInlineComment(val: string): string {\r\n // Fast path: no space means no inline comment possible\r\n if (val.indexOf(' ') === -1) return val;\r\n\r\n let result = val;\r\n const slashIdx = result.indexOf(' //');\r\n if (slashIdx !== -1) result = result.substring(0, slashIdx);\r\n const hashIdx = result.indexOf(' #');\r\n if (hashIdx !== -1) result = result.substring(0, hashIdx);\r\n return result.trimEnd();\r\n}\r\n\r\n/** Parse constraint string like \"min:3, max:30, required, type:int\" */\r\nfunction parseConstraints(raw: string): SynxConstraints {\r\n const constraints: SynxConstraints = {};\r\n let start = 0;\r\n while (start < raw.length) {\r\n let end = raw.indexOf(',', start);\r\n if (end === -1) end = raw.length;\r\n const part = raw.substring(start, end).trim();\r\n start = end + 1;\r\n if (!part) continue;\r\n\r\n if (part === 'required') {\r\n constraints.required = true;\r\n } else if (part === 'readonly') {\r\n constraints.readonly = true;\r\n } else {\r\n const colonIdx = part.indexOf(':');\r\n if (colonIdx !== -1) {\r\n const key = part.substring(0, colonIdx).trim();\r\n const value = part.substring(colonIdx + 1).trim();\r\n switch (key) {\r\n case 'min': constraints.min = Number(value); break;\r\n case 'max': constraints.max = Number(value); break;\r\n case 'type': constraints.type = value; break;\r\n case 'pattern': constraints.pattern = value; break;\r\n case 'enum': constraints.enum = value.split('|'); break;\r\n }\r\n }\r\n }\r\n }\r\n return constraints;\r\n}\r\n\r\n/** Attach hidden __synx metadata to an object */\r\nfunction saveMeta(\r\n obj: SynxObject,\r\n key: string,\r\n markers: string[],\r\n args: string[],\r\n constraints: SynxConstraints | undefined,\r\n mode: SynxMode,\r\n typeHint?: string,\r\n): void {\r\n if (mode !== 'active') return;\r\n if (markers.length === 0 && !constraints && !typeHint) return;\r\n\r\n let metaMap: SynxMetaMap;\r\n if ((obj as any).__synx) {\r\n metaMap = (obj as any).__synx;\r\n } else {\r\n metaMap = {};\r\n Object.defineProperty(obj, '__synx', {\r\n value: metaMap,\r\n enumerable: false,\r\n writable: true,\r\n configurable: true,\r\n });\r\n }\r\n\r\n const meta: SynxMeta = { markers };\r\n if (args.length > 0) meta.args = args;\r\n if (constraints) meta.constraints = constraints;\r\n if (typeHint) meta.typeHint = typeHint;\r\n metaMap[key] = meta;\r\n}\r\n\r\n// \u2500\u2500\u2500 Fallback regex for complex lines (type hints, constraints, markers) \u2500\u2500\r\nconst LINE_REGEX = /^([^\\s\\[:\\-#/(][^\\s\\[:(]*)(?:\\(([\\w:]+)\\))?(?:\\[([^\\]]*)\\])?(?::([^\\s]+))?\\s*(.*)$/;\r\n\r\n// \u2500\u2500\u2500 Parser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function parseData(text: string): SynxParseResult {\r\n const lines = text.split('\\n');\r\n const root: SynxObject = {};\r\n const stack: Array<{ indent: number; obj: SynxObject | SynxArray }> = [\r\n { indent: -1, obj: root },\r\n ];\r\n\r\n let mode: SynxMode = 'static';\r\n let locked = false;\r\n const includes: SynxInclude[] = [];\r\n let currentBlock: { indent: number; obj: SynxObject; key: string } | null = null;\r\n let currentList: { indent: number; arr: SynxArray } | null = null;\r\n let inBlockComment = false;\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const rawLine = lines[i];\r\n const rawLen = rawLine.length;\r\n\r\n // \u2500\u2500 Manual indent computation (no regex) \u2500\u2500\r\n let indent = 0;\r\n while (indent < rawLen) {\r\n const ch = rawLine.charCodeAt(indent);\r\n if (ch !== 32 && ch !== 9 && ch !== 13) break; // space, tab, \\r\r\n indent++;\r\n }\r\n\r\n // \u2500\u2500 Empty line \u2500\u2500\r\n if (indent === rawLen) continue;\r\n\r\n const fc = rawLine.charCodeAt(indent); // first non-whitespace char\r\n\r\n // \u2500\u2500 Block comment toggle: ### \u2500\u2500\r\n if (fc === 35) {\r\n const rest = rawLine.substring(indent).trimEnd();\r\n if (rest === '###') {\r\n inBlockComment = !inBlockComment;\r\n continue;\r\n }\r\n }\r\n if (inBlockComment) continue;\r\n\r\n // \u2500\u2500 Comments: # or // \u2500\u2500\r\n if (fc === 35) { // #\r\n // Legacy: #!mode:active / #!mode:static\r\n if (rawLen - indent > 7 && rawLine.charCodeAt(indent + 1) === 33) { // !\r\n if (rawLine.substring(indent, indent + 7) === '#!mode:') {\r\n const declared = rawLine.substring(indent + 7, rawLen).trim();\r\n mode = declared === 'active' ? 'active' : 'static';\r\n }\r\n }\r\n continue;\r\n }\r\n if (fc === 47 && indent + 1 < rawLen && rawLine.charCodeAt(indent + 1) === 47) continue; // //\r\n\r\n // \u2500\u2500 Compute trimmed string (manual trim, no regex) \u2500\u2500\r\n let trimEndPos = rawLen;\r\n while (trimEndPos > indent) {\r\n const ch = rawLine.charCodeAt(trimEndPos - 1);\r\n if (ch !== 32 && ch !== 9 && ch !== 13 && ch !== 10) break;\r\n trimEndPos--;\r\n }\r\n const trimmed = rawLine.substring(indent, trimEndPos);\r\n const trimmedLen = trimmed.length;\r\n\r\n // \u2500\u2500 Mode declaration: !active / !lock / !include \u2500\u2500\r\n if (fc === 33) {\r\n if (trimmed === '!active') { mode = 'active'; continue; }\r\n if (trimmed === '!lock') { locked = true; continue; }\r\n if (trimmed.startsWith('!include ')) {\r\n const parts = trimmed.substring(9).trim().split(/\\s+/);\r\n const inclPath = parts[0];\r\n const alias = parts[1] || inclPath.replace(/^.*[\\/\\\\]/, '').replace(/\\.synx$/i, '');\r\n includes.push({ path: inclPath, alias });\r\n continue;\r\n }\r\n }\r\n\r\n // \u2500\u2500 Continue multiline block \u2500\u2500\r\n if (currentBlock && indent > currentBlock.indent) {\r\n const line = trimmed;\r\n currentBlock.obj[currentBlock.key] +=\r\n (currentBlock.obj[currentBlock.key] ? '\\n' : '') + line;\r\n continue;\r\n } else {\r\n currentBlock = null;\r\n }\r\n\r\n // \u2500\u2500 List items: '- ' \u2500\u2500\r\n if (fc === 45 && trimmedLen > 1 && trimmed.charCodeAt(1) === 32) {\r\n if (currentList && indent > currentList.indent) {\r\n const val = stripInlineComment(trimmed.substring(2).trim());\r\n\r\n // Check if this list item has sub-keys (peek next line)\r\n let nextNonEmpty = i + 1;\r\n while (nextNonEmpty < lines.length) {\r\n const nl = lines[nextNonEmpty];\r\n let ni = 0;\r\n while (ni < nl.length && (nl.charCodeAt(ni) === 32 || nl.charCodeAt(ni) === 9 || nl.charCodeAt(ni) === 13)) ni++;\r\n if (ni < nl.length) break;\r\n nextNonEmpty++;\r\n }\r\n\r\n if (nextNonEmpty < lines.length) {\r\n const nextLine = lines[nextNonEmpty];\r\n let nextIndent = 0;\r\n while (nextIndent < nextLine.length && (nextLine.charCodeAt(nextIndent) === 32 || nextLine.charCodeAt(nextIndent) === 9 || nextLine.charCodeAt(nextIndent) === 13)) nextIndent++;\r\n const nfc = nextLine.charCodeAt(nextIndent);\r\n if (nextIndent > indent && nextIndent < nextLine.length &&\r\n nfc !== 45 && nfc !== 35 &&\r\n !(nfc === 47 && nextIndent + 1 < nextLine.length && nextLine.charCodeAt(nextIndent + 1) === 47)) {\r\n const itemObj: SynxObject = {};\r\n const itemMatch = val.match(LINE_REGEX);\r\n if (itemMatch) {\r\n const [, iKey, iTypeHint, , , iVal] = itemMatch;\r\n let iValue = iVal || '';\r\n if (iTypeHint) iValue = `(${iTypeHint})${iValue}`;\r\n itemObj[iKey] = iValue ? castType(stripInlineComment(iValue)) : {};\r\n } else {\r\n itemObj['_value'] = castType(val);\r\n }\r\n currentList.arr.push(itemObj);\r\n stack.push({ indent, obj: itemObj });\r\n continue;\r\n }\r\n }\r\n\r\n currentList.arr.push(castType(val));\r\n continue;\r\n }\r\n // Not in list context \u2014 skip (LINE_REGEX wouldn't match '- ' anyway)\r\n continue;\r\n }\r\n\r\n // Close list if needed (non-list-item line at <= list indent)\r\n if (currentList && indent <= currentList.indent) {\r\n currentList = null;\r\n }\r\n\r\n // \u2500\u2500 Validate first char can start a key \u2500\u2500\r\n // LINE_REGEX first char: [^\\s\\[:\\-#/(] \u2014 we already filtered #, //, -\r\n if (fc === 91 || fc === 40 || fc === 58 || fc === 47) continue; // [ ( : /\r\n\r\n // \u2500\u2500 Parse key line \u2500\u2500\r\n // FAST PATH: scan key for special chars ( [ :\r\n // If none found, skip LINE_REGEX entirely\r\n let key: string;\r\n let typeHint: string | undefined;\r\n let constraintStr: string | undefined;\r\n let markerChain: string | undefined;\r\n let rawValue: string;\r\n\r\n let hasSpecial = false;\r\n let spaceIdx = -1;\r\n for (let j = 0; j < trimmedLen; j++) {\r\n const ch = trimmed.charCodeAt(j);\r\n if (ch === 32 || ch === 9) { // space or tab\r\n spaceIdx = j;\r\n break;\r\n }\r\n if (ch === 40 || ch === 91 || ch === 58) { // ( [ :\r\n hasSpecial = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!hasSpecial) {\r\n // \u2500\u2500 Fast path: simple key-value or section header \u2500\u2500\r\n if (spaceIdx === -1) {\r\n key = trimmed;\r\n rawValue = '';\r\n } else {\r\n key = trimmed.substring(0, spaceIdx);\r\n // Skip whitespace between key and value\r\n let valStart = spaceIdx;\r\n while (valStart < trimmedLen && (trimmed.charCodeAt(valStart) === 32 || trimmed.charCodeAt(valStart) === 9)) valStart++;\r\n rawValue = valStart < trimmedLen ? stripInlineComment(trimmed.substring(valStart)) : '';\r\n }\r\n typeHint = undefined;\r\n constraintStr = undefined;\r\n markerChain = undefined;\r\n } else {\r\n // \u2500\u2500 Slow path: regex for lines with ( [ : \u2500\u2500\r\n const match = trimmed.match(LINE_REGEX);\r\n if (!match) continue;\r\n [, key, typeHint, constraintStr, markerChain, rawValue] = match;\r\n rawValue = rawValue ? stripInlineComment(rawValue.trim()) : '';\r\n }\r\n\r\n // Apply explicit type cast\r\n if (typeHint) rawValue = `(${typeHint})${rawValue}`;\r\n\r\n // Parse markers chain\r\n let markers: string[] = [];\r\n let markerArgs: string[] = [];\r\n if (markerChain) {\r\n markers = markerChain.split(':');\r\n }\r\n\r\n // For :random \u2014 the rawValue may contain weight percentages\r\n if (markers.length > 0 && markers.includes('random') && rawValue) {\r\n const nums = rawValue.split(/\\s+/).filter(s => /^\\d+(\\.\\d+)?$/.test(s));\r\n if (nums.length > 0) {\r\n markerArgs = nums;\r\n rawValue = '';\r\n }\r\n }\r\n\r\n const constraints = constraintStr ? parseConstraints(constraintStr) : undefined;\r\n\r\n // \u2500\u2500 Pop stack to correct parent \u2500\u2500\r\n while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {\r\n stack.pop();\r\n }\r\n const parent = stack[stack.length - 1].obj as SynxObject;\r\n\r\n // \u2500\u2500 Reject prototype-polluting keys \u2500\u2500\r\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue;\r\n\r\n // \u2500\u2500 Determine what this line creates \u2500\u2500\r\n if (rawValue === '|') {\r\n // Multiline block\r\n parent[key] = '';\r\n currentBlock = { indent, obj: parent, key };\r\n saveMeta(parent, key, markers, markerArgs, constraints, mode, typeHint);\r\n } else if (!rawValue && markers.length > 0 &&\r\n (markers.includes('random') || markers.includes('unique') ||\r\n markers.includes('geo') || markers.includes('join'))) {\r\n // List with markers (items follow with -)\r\n parent[key] = [];\r\n currentList = { indent, arr: parent[key] as SynxArray };\r\n saveMeta(parent, key, markers, markerArgs, constraints, mode, typeHint);\r\n } else if (!rawValue) {\r\n // No value \u2192 nested object (group) OR plain list\r\n parent[key] = {};\r\n stack.push({ indent, obj: parent[key] as SynxObject });\r\n // Peek ahead: if next meaningful line starts with -, it's a list\r\n let peekIdx = i + 1;\r\n while (peekIdx < lines.length) {\r\n const pl = lines[peekIdx];\r\n let pi = 0;\r\n while (pi < pl.length && (pl.charCodeAt(pi) === 32 || pl.charCodeAt(pi) === 9 || pl.charCodeAt(pi) === 13)) pi++;\r\n if (pi < pl.length) break;\r\n peekIdx++;\r\n }\r\n if (peekIdx < lines.length) {\r\n const pl = lines[peekIdx];\r\n let pi = 0;\r\n while (pi < pl.length && (pl.charCodeAt(pi) === 32 || pl.charCodeAt(pi) === 9 || pl.charCodeAt(pi) === 13)) pi++;\r\n if (pi + 1 < pl.length && pl.charCodeAt(pi) === 45 && pl.charCodeAt(pi + 1) === 32) {\r\n parent[key] = [];\r\n stack[stack.length - 1] = { indent, obj: parent[key] as unknown as SynxObject };\r\n currentList = { indent, arr: parent[key] as SynxArray };\r\n }\r\n }\r\n saveMeta(parent, key, markers, markerArgs, constraints, mode, typeHint);\r\n } else {\r\n // Simple key-value\r\n parent[key] = castType(rawValue);\r\n saveMeta(parent, key, markers, markerArgs, constraints, mode, typeHint);\r\n }\r\n }\r\n\r\n return { root, mode, locked, includes: includes.length > 0 ? includes : undefined };\r\n}\r\n", "/**\r\n * SYNX Safe Calculator \u2014 @aperturesyndicate/synx\r\n *\r\n * Evaluates arithmetic expressions WITHOUT eval() or new Function().\r\n * Supports: +, -, *, /, %, parentheses, and numeric literals.\r\n * Variable references are resolved before this stage.\r\n */\r\n\r\ntype Token =\r\n | { type: 'number'; value: number }\r\n | { type: 'op'; value: string }\r\n | { type: 'paren'; value: '(' | ')' };\r\n\r\n/**\r\n * Tokenize an arithmetic expression string.\r\n */\r\nfunction tokenize(expr: string): Token[] {\r\n const tokens: Token[] = [];\r\n let i = 0;\r\n\r\n while (i < expr.length) {\r\n const ch = expr[i];\r\n\r\n // Skip whitespace\r\n if (ch === ' ' || ch === '\\t') {\r\n i++;\r\n continue;\r\n }\r\n\r\n // Number (integer or float, including negative after operator/start)\r\n if (\r\n (ch >= '0' && ch <= '9') ||\r\n (ch === '.' && i + 1 < expr.length && expr[i + 1] >= '0' && expr[i + 1] <= '9') ||\r\n (ch === '-' && (tokens.length === 0 || tokens[tokens.length - 1].type === 'op' || (tokens[tokens.length - 1].type === 'paren' && tokens[tokens.length - 1].value === '(')))\r\n ) {\r\n let num = '';\r\n if (ch === '-') {\r\n num += '-';\r\n i++;\r\n }\r\n while (i < expr.length && ((expr[i] >= '0' && expr[i] <= '9') || expr[i] === '.')) {\r\n num += expr[i];\r\n i++;\r\n }\r\n tokens.push({ type: 'number', value: parseFloat(num) });\r\n continue;\r\n }\r\n\r\n // Operators\r\n if ('+-*/%'.includes(ch)) {\r\n tokens.push({ type: 'op', value: ch });\r\n i++;\r\n continue;\r\n }\r\n\r\n // Parentheses\r\n if (ch === '(' || ch === ')') {\r\n tokens.push({ type: 'paren', value: ch });\r\n i++;\r\n continue;\r\n }\r\n\r\n throw new Error(`SYNX :calc \u2014 unexpected character: '${ch}' in expression \"${expr}\"`);\r\n }\r\n\r\n return tokens;\r\n}\r\n\r\n/**\r\n * Recursive descent parser for arithmetic.\r\n * Grammar:\r\n * expr \u2192 term (('+' | '-') term)*\r\n * term \u2192 factor (('*' | '/' | '%') factor)*\r\n * factor \u2192 NUMBER | '(' expr ')'\r\n */\r\nclass ExprParser {\r\n private tokens: Token[];\r\n private pos: number;\r\n\r\n constructor(tokens: Token[]) {\r\n this.tokens = tokens;\r\n this.pos = 0;\r\n }\r\n\r\n parse(): number {\r\n const result = this.expr();\r\n if (this.pos < this.tokens.length) {\r\n throw new Error(`SYNX :calc \u2014 unexpected token at position ${this.pos}`);\r\n }\r\n return result;\r\n }\r\n\r\n private expr(): number {\r\n let left = this.term();\r\n while (this.pos < this.tokens.length && this.tokens[this.pos].type === 'op' && (this.tokens[this.pos].value === '+' || this.tokens[this.pos].value === '-')) {\r\n const op = this.tokens[this.pos].value;\r\n this.pos++;\r\n const right = this.term();\r\n left = op === '+' ? left + right : left - right;\r\n }\r\n return left;\r\n }\r\n\r\n private term(): number {\r\n let left = this.factor();\r\n while (this.pos < this.tokens.length && this.tokens[this.pos].type === 'op' && ('*/%'.includes(this.tokens[this.pos].value as string))) {\r\n const op = this.tokens[this.pos].value;\r\n this.pos++;\r\n const right = this.factor();\r\n if (op === '*') left = left * right;\r\n else if (op === '/') {\r\n if (right === 0) throw new Error('SYNX :calc \u2014 division by zero');\r\n left = left / right;\r\n }\r\n else {\r\n if (right === 0) throw new Error('SYNX :calc \u2014 division by zero');\r\n left = left % right;\r\n }\r\n }\r\n return left;\r\n }\r\n\r\n private factor(): number {\r\n const tok = this.tokens[this.pos];\r\n\r\n if (!tok) {\r\n throw new Error('SYNX :calc \u2014 unexpected end of expression');\r\n }\r\n\r\n if (tok.type === 'number') {\r\n this.pos++;\r\n return tok.value;\r\n }\r\n\r\n if (tok.type === 'paren' && tok.value === '(') {\r\n this.pos++; // skip '('\r\n const val = this.expr();\r\n if (!this.tokens[this.pos] || this.tokens[this.pos].type !== 'paren' || this.tokens[this.pos].value !== ')') {\r\n throw new Error('SYNX :calc \u2014 missing closing parenthesis');\r\n }\r\n this.pos++; // skip ')'\r\n return val;\r\n }\r\n\r\n throw new Error(`SYNX :calc \u2014 unexpected token: ${JSON.stringify(tok)}`);\r\n }\r\n}\r\n\r\n/**\r\n * Safely evaluate an arithmetic expression.\r\n * All variable names must be substituted with numbers before calling this.\r\n *\r\n * @param expr - e.g. \"100 * 5 + (20 / 4)\"\r\n * @returns The computed number\r\n */\r\nexport function safeCalc(expr: string): number {\r\n const tokens = tokenize(expr.trim());\r\n if (tokens.length === 0) return 0;\r\n return new ExprParser(tokens).parse();\r\n}\r\n", "/**\r\n * SYNX Engine \u2014 @aperturesyndicate/synx\r\n *\r\n * Resolves active markers (:random, :calc, :env, :alias, :secret, etc.)\r\n * in a parsed SYNX object tree. Only runs in !active mode.\r\n */\r\n\r\nimport type { SynxObject, SynxValue, SynxMetaMap, SynxOptions, SynxInclude } from './types';\r\nimport { safeCalc } from './calc';\r\nimport { parseData } from './parser';\r\n\r\n// Lazy-loaded Node.js modules (not available in browser)\r\nlet fs: typeof import('fs') | undefined;\r\nlet pathModule: typeof import('path') | undefined;\r\ntry {\r\n fs = require('fs');\r\n pathModule = require('path');\r\n} catch {\r\n // Browser environment \u2014 :include will not work\r\n}\r\n\r\n// \u2500\u2500\u2500 Security constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nconst MAX_CALC_EXPR_LEN = 4096;\r\nconst MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB\r\nconst DEFAULT_MAX_INCLUDE_DEPTH = 16;\r\n\r\n/** Maximum object nesting depth for active-mode resolution (prevents stack overflow). */\r\nconst MAX_RESOLVE_DEPTH = 512;\r\n\r\n/** Ensure a file path stays inside the base directory (path jail). */\r\nfunction jailPath(base: string, filePath: string): string {\r\n if (!pathModule) throw new Error('path module not available');\r\n // Block absolute paths\r\n if (pathModule.isAbsolute(filePath)) {\r\n throw new Error(`absolute path not allowed: ${filePath}`);\r\n }\r\n const resolved = pathModule.resolve(base, filePath);\r\n const normalizedBase = pathModule.resolve(base);\r\n // Ensure resolved path starts with the base directory\r\n if (!resolved.startsWith(normalizedBase + pathModule.sep) && resolved !== normalizedBase) {\r\n throw new Error(`path escapes base directory: ${filePath}`);\r\n }\r\n return resolved;\r\n}\r\n\r\n/** Check that a file does not exceed MAX_FILE_SIZE. */\r\nfunction checkFileSize(filePath: string): void {\r\n if (!fs) return;\r\n const stat = fs.statSync(filePath);\r\n if (stat.size > MAX_FILE_SIZE) {\r\n throw new Error(`file too large (${stat.size} bytes, max ${MAX_FILE_SIZE})`);\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Secret wrapper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nclass SynxSecret {\r\n private _value: string;\r\n\r\n constructor(value: string) {\r\n this._value = value;\r\n }\r\n\r\n toString(): string {\r\n return '[SECRET]';\r\n }\r\n\r\n toJSON(): string {\r\n return '[SECRET]';\r\n }\r\n\r\n /** Call this explicitly to get the real value */\r\n reveal(): string {\r\n return this._value;\r\n }\r\n\r\n [Symbol.toPrimitive](hint: string): string | number {\r\n if (hint === 'number') return NaN;\r\n return '[SECRET]';\r\n }\r\n}\r\n\r\nconst SPAM_BUCKETS = new Map<string, number[]>();\r\n\r\n// \u2500\u2500\u2500 Engine \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nexport function resolve(\r\n obj: SynxObject,\r\n options: SynxOptions = {},\r\n root?: SynxObject,\r\n includesMap?: Map<string, SynxObject>,\r\n _resolveDepth = 0,\r\n _currentPath = '',\r\n): SynxObject {\r\n if (!root) {\r\n root = obj;\r\n // \u2500\u2500 :inherit pre-pass (only at root level) \u2500\u2500\r\n applyInheritance(obj);\r\n // Remove private blocks (keys starting with _)\r\n for (const k of Object.keys(obj)) {\r\n if (k.startsWith('_')) delete obj[k];\r\n }\r\n // \u2500\u2500 Load !include directives \u2500\u2500\r\n if (!includesMap && (options as any)._includes) {\r\n includesMap = loadIncludes((options as any)._includes as SynxInclude[], options);\r\n }\r\n }\r\n\r\n // Guard: prevent stack overflow from deeply nested objects\r\n if (_resolveDepth >= MAX_RESOLVE_DEPTH) {\r\n for (const k of Object.keys(obj)) {\r\n if (k !== '__synx') {\r\n obj[k] = 'NESTING_ERR: maximum object nesting depth exceeded';\r\n }\r\n }\r\n return obj;\r\n }\r\n\r\n const metaMap: SynxMetaMap | undefined = (obj as any).__synx;\r\n\r\n for (const key of Object.keys(obj)) {\r\n if (key === '__synx') continue;\r\n\r\n let value = obj[key];\r\n\r\n // Recurse into nested objects\r\n if (value && typeof value === 'object' && !Array.isArray(value)) {\r\n resolve(value as SynxObject, options, root, includesMap, _resolveDepth + 1, _currentPath ? `${_currentPath}.${key}` : key);\r\n }\r\n\r\n // Recurse into arrays of objects\r\n if (Array.isArray(value)) {\r\n for (const item of value) {\r\n if (item && typeof item === 'object' && !Array.isArray(item)) {\r\n resolve(item as SynxObject, options, root, includesMap, _resolveDepth + 1, _currentPath ? `${_currentPath}.${key}` : key);\r\n }\r\n }\r\n }\r\n\r\n // Apply markers\r\n if (!metaMap || !metaMap[key]) continue;\r\n const { markers, args } = metaMap[key];\r\n\r\n // \u2500\u2500 :spam \u2500\u2500\r\n // Syntax: key:spam:MAX_CALLS:WINDOW_SEC target\r\n // WINDOW_SEC defaults to 1 when omitted.\r\n if (markers.includes('spam')) {\r\n const idx = markers.indexOf('spam');\r\n const maxCalls = parseInt(markers[idx + 1] ?? '0', 10);\r\n const windowSec = Math.max(1, parseInt(markers[idx + 2] ?? '1', 10) || 1);\r\n\r\n if (!Number.isFinite(maxCalls) || maxCalls <= 0) {\r\n obj[key] = 'SPAM_ERR: invalid limit, use :spam:MAX[:WINDOW_SEC]';\r\n continue;\r\n }\r\n\r\n const target = String(obj[key] ?? key);\r\n const bucketKey = `${key}::${target}`;\r\n if (!allowSpamAccess(bucketKey, maxCalls, windowSec)) {\r\n obj[key] = `SPAM_ERR: '${target}' exceeded ${maxCalls} calls per ${windowSec}s`;\r\n continue;\r\n }\r\n\r\n const resolvedTarget = deepGet(root, target) ?? deepGet(obj, target);\r\n if (resolvedTarget !== undefined) {\r\n obj[key] = resolvedTarget;\r\n }\r\n }\r\n\r\n // \u2500\u2500 :include \u2500\u2500\r\n if (markers.includes('include') && typeof obj[key] === 'string') {\r\n if (!fs || !pathModule) {\r\n obj[key] = 'INCLUDE_ERR: :include is not supported in browser';\r\n continue;\r\n }\r\n const maxDepth = options.maxIncludeDepth ?? DEFAULT_MAX_INCLUDE_DEPTH;\r\n const currentDepth = (options as any)._includeDepth ?? 0;\r\n if (currentDepth >= maxDepth) {\r\n obj[key] = `INCLUDE_ERR: max include depth (${maxDepth}) exceeded`;\r\n continue;\r\n }\r\n const includePath = String(obj[key]);\r\n const basePath = options.basePath || (typeof process !== 'undefined' ? process.cwd() : '.');\r\n try {\r\n const fullPath = jailPath(basePath, includePath);\r\n checkFileSize(fullPath);\r\n const text = fs.readFileSync(fullPath, 'utf-8');\r\n const { root: included, mode: includedMode } = parseData(text);\r\n if (includedMode === 'active') {\r\n resolve(included, { ...options, basePath: pathModule.dirname(fullPath), _includeDepth: currentDepth + 1 } as any, root);\r\n }\r\n obj[key] = included;\r\n } catch (e: any) {\r\n obj[key] = `INCLUDE_ERR: ${e.message}`;\r\n }\r\n continue;\r\n }\r\n\r\n // \u2500\u2500 :env \u2500\u2500\r\n if (markers.includes('env')) {\r\n const varName = String(value);\r\n const envSource = options.env || (typeof process !== 'undefined' ? process.env : {});\r\n const envVal = envSource[varName];\r\n\r\n // Check for :default in the marker chain\r\n const defaultIdx = markers.indexOf('default');\r\n // Check if key has (string) type hint \u2014 if so, skip auto-detection\r\n const forceString = metaMap[key]?.typeHint === 'string';\r\n if (envVal !== undefined && envVal !== '') {\r\n obj[key] = forceString ? envVal : (isNaN(Number(envVal)) ? envVal : Number(envVal));\r\n } else if (defaultIdx !== -1 && markers.length > defaultIdx + 1) {\r\n // :env:default:VALUE \u2014 join all parts after 'default' back with ':'\r\n // to preserve IPs (0.0.0.0) and compound values\r\n const fallback = markers.slice(defaultIdx + 1).join(':');\r\n obj[key] = forceString ? fallback : (isNaN(Number(fallback)) ? fallback : Number(fallback));\r\n } else {\r\n obj[key] = null;\r\n }\r\n }\r\n\r\n // \u2500\u2500 :random \u2500\u2500\r\n if (markers.includes('random') && Array.isArray(obj[key])) {\r\n const arr = obj[key] as SynxValue[];\r\n if (arr.length === 0) {\r\n obj[key] = null;\r\n continue;\r\n }\r\n\r\n if (args && args.length > 0) {\r\n // Weighted random\r\n const weights = args.map(Number);\r\n obj[key] = weightedRandom(arr, weights);\r\n } else {\r\n // Equal probability\r\n obj[key] = arr[Math.floor(Math.random() * arr.length)];\r\n }\r\n }\r\n\r\n // \u2500\u2500 :ref \u2500\u2500\r\n // Like :alias but feeds the resolved value into subsequent markers.\r\n // Supports :ref:calc shorthand: key:ref:calc:*2 base_rate \u2192 resolves base_rate, then applies \"VALUE * 2\".\r\n if (markers.includes('ref') && typeof obj[key] === 'string') {\r\n const target = obj[key] as string;\r\n const resolved = deepGet(root, target) ?? deepGet(obj, target);\r\n if (resolved !== undefined) {\r\n obj[key] = resolved;\r\n // If :calc follows, prepend the resolved value to the calc expression\r\n if (markers.includes('calc')) {\r\n const calcIdx = markers.indexOf('calc');\r\n const calcExpr = markers[calcIdx + 1] ?? '';\r\n if (calcExpr && typeof resolved === 'number') {\r\n // Shorthand: :ref:calc:*2 \u2192 VALUE * 2, :ref:calc:+10 \u2192 VALUE + 10\r\n const first = calcExpr.charAt(0);\r\n if ('+-*/%'.includes(first)) {\r\n const fullExpr = `${resolved} ${calcExpr}`;\r\n try {\r\n obj[key] = safeCalc(fullExpr);\r\n } catch {\r\n obj[key] = resolved;\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n obj[key] = null;\r\n }\r\n }\r\n\r\n // \u2500\u2500 :i18n \u2500\u2500\r\n // Selects a localized value from a nested object based on options.lang.\r\n // Syntax: name:i18n\\n en Plains\\n ru \u0420\u0430\u0432\u043D\u0438\u043D\u044B\r\n if (markers.includes('i18n') && obj[key] && typeof obj[key] === 'object' && !Array.isArray(obj[key])) {\r\n const translations = obj[key] as SynxObject;\r\n const lang = options.lang || 'en';\r\n const val = translations[lang] ?? translations['en'] ?? Object.values(translations)[0] ?? null;\r\n obj[key] = val;\r\n }\r\n\r\n // \u2500\u2500 :calc \u2500\u2500\r\n if (markers.includes('calc') && typeof obj[key] === 'string') {\r\n let expr = obj[key] as string;\r\n if (expr.length > MAX_CALC_EXPR_LEN) {\r\n obj[key] = `CALC_ERR: expression too long (${expr.length} chars, max ${MAX_CALC_EXPR_LEN})`;\r\n continue;\r\n }\r\n // Collect already-resolved numeric variables from root + local scope.\r\n // Keys that appear later in iteration order and still hold a marker\r\n // value (e.g. an unresolved :env string) are not yet numbers and will\r\n // be absent from vars \u2014 place :calc keys after their dependencies.\r\n const vars = new Map<string, string>();\r\n for (const rKey of Object.keys(root)) {\r\n if (typeof root[rKey] === 'number') vars.set(rKey, String(root[rKey]));\r\n }\r\n for (const rKey of Object.keys(obj)) {\r\n if (rKey !== key && typeof obj[rKey] === 'number') vars.set(rKey, String(obj[rKey]));\r\n }\r\n // Substitute whole-word occurrences without building RegExp objects\r\n if (vars.size > 0) expr = replaceVars(expr, vars);\r\n try {\r\n obj[key] = safeCalc(expr);\r\n } catch (e: any) {\r\n obj[key] = `CALC_ERR: ${e.message}`;\r\n }\r\n }\r\n\r\n // \u2500\u2500 :alias \u2500\u2500\r\n if (markers.includes('alias') && typeof obj[key] === 'string') {\r\n const target = obj[key] as string;\r\n // Detect direct self-reference (bare key or full dot-path)\r\n const currentKeyPath = _currentPath ? `${_currentPath}.${key}` : key;\r\n if (target === key || target === currentKeyPath) {\r\n obj[key] = `ALIAS_ERR: self-referential alias: ${currentKeyPath} \u2192 ${target}`;\r\n } else {\r\n // Detect one-hop cycle: a \u2192 b \u2192 a\r\n // Only flag as cycle if the target key ALSO has an :alias marker.\r\n // Without this check, plain string values that happen to match the current\r\n // key name would produce false-positive ALIAS_ERR results.\r\n const targetVal = deepGet(root, target);\r\n // Check if the target key has an :alias marker in metadata.\r\n // Must look up the target's PARENT object's __synx, not the root's,\r\n // to correctly handle nested keys like \"section.foo\".\r\n const lastDot = target.lastIndexOf('.');\r\n const targetParentPath = lastDot >= 0 ? target.slice(0, lastDot) : '';\r\n const targetLeafKey = lastDot >= 0 ? target.slice(lastDot + 1) : target;\r\n const targetParentObj = targetParentPath ? deepGet(root, targetParentPath) : root;\r\n const targetParentMeta = (targetParentObj != null && typeof targetParentObj === 'object')\r\n ? (targetParentObj as any).__synx as Record<string, any> | undefined\r\n : undefined;\r\n const targetHasAlias: boolean =\r\n targetParentMeta?.[targetLeafKey]?.markers?.includes('alias') ?? false;\r\n const isCycle = targetHasAlias && typeof targetVal === 'string' && targetVal === key;\r\n if (isCycle) {\r\n obj[key] = `ALIAS_ERR: circular alias detected: ${key} \u2192 ${target}`;\r\n } else {\r\n obj[key] = targetVal ?? null;\r\n }\r\n }\r\n }\r\n\r\n // \u2500\u2500 :secret \u2500\u2500\r\n if (markers.includes('secret')) {\r\n obj[key] = new SynxSecret(String(obj[key])) as any;\r\n }\r\n\r\n // \u2500\u2500 :unique \u2500\u2500\r\n if (markers.includes('unique') && Array.isArray(obj[key])) {\r\n const seen = new Set<string>();\r\n obj[key] = (obj[key] as SynxValue[]).filter((item) => {\r\n const s = String(item);\r\n if (seen.has(s)) return false;\r\n seen.add(s);\r\n return true;\r\n });\r\n }\r\n\r\n // \u2500\u2500 :geo \u2500\u2500\r\n if (markers.includes('geo') && Array.isArray(obj[key])) {\r\n const region = options.region || 'US';\r\n const arr = obj[key] as string[];\r\n const found = arr.find((item) => String(item).startsWith(region + ' '));\r\n if (found) {\r\n obj[key] = found.substring(region.length + 1).trim();\r\n } else {\r\n // Fallback to first entry\r\n const first = arr[0];\r\n if (typeof first === 'string' && first.includes(' ')) {\r\n obj[key] = first.substring(first.indexOf(' ') + 1).trim();\r\n } else {\r\n obj[key] = first ?? null;\r\n }\r\n }\r\n }\r\n\r\n // \u2500\u2500 :template (legacy \u2014 handled by auto-{} below) \u2500\u2500\r\n\r\n // \u2500\u2500 :split \u2500\u2500\r\n if (markers.includes('split') && typeof obj[key] === 'string') {\r\n const splitIdx = markers.indexOf('split');\r\n const delimArg = (splitIdx + 1 < markers.length) ? markers[splitIdx + 1] : ',';\r\n const sep = delimiterFromKeyword(delimArg);\r\n obj[key] = (obj[key] as string).split(sep).map(s => s.trim()).filter(s => s !== '').map(s => castPrimitive(s));\r\n }\r\n\r\n // \u2500\u2500 :join \u2500\u2500\r\n if (markers.includes('join') && Array.isArray(obj[key])) {\r\n const joinIdx = markers.indexOf('join');\r\n const delimArg = (joinIdx + 1 < markers.length) ? markers[joinIdx + 1] : ',';\r\n const sep = delimiterFromKeyword(delimArg);\r\n obj[key] = (obj[key] as SynxValue[]).map(v => String(v)).join(sep);\r\n }\r\n\r\n // \u2500\u2500 :default (standalone, not combined with :env) \u2500\u2500\r\n if (markers.includes('default') && !markers.includes('env')) {\r\n if (obj[key] === null || obj[key] === undefined || obj[key] === '') {\r\n const defaultIdx = markers.indexOf('default');\r\n if (defaultIdx !== -1 && markers.length > defaultIdx + 1) {\r\n const fallback = markers.slice(defaultIdx + 1).join(':');\r\n const forceStr = metaMap[key]?.typeHint === 'string';\r\n obj[key] = forceStr ? fallback : (isNaN(Number(fallback)) ? fallback : Number(fallback));\r\n }\r\n }\r\n }\r\n\r\n // \u2500\u2500 :clamp \u2500\u2500\r\n // Syntax: key:clamp:MIN:MAX value\r\n if (markers.includes('clamp')) {\r\n const idx = markers.indexOf('clamp');\r\n const lo = parseFloat(markers[idx + 1] ?? '');\r\n const hi = parseFloat(markers[idx + 2] ?? '');\r\n if (!isNaN(lo) && !isNaN(hi)) {\r\n if (lo > hi) {\r\n obj[key] = `CONSTRAINT_ERR: clamp min (${lo}) > max (${hi})`;\r\n } else if (typeof obj[key] === 'number') {\r\n obj[key] = Math.min(hi, Math.max(lo, obj[key] as number));\r\n }\r\n }\r\n }\r\n\r\n // \u2500\u2500 :round \u2500\u2500\r\n // Syntax: key:round:N value (N = decimal places, default 0)\r\n if (markers.includes('round')) {\r\n const idx = markers.indexOf('round');\r\n const decimals = parseInt(markers[idx + 1] ?? '0', 10) || 0;\r\n if (typeof obj[key] === 'number') {\r\n const factor = Math.pow(10, decimals);\r\n obj[key] = Math.round((obj[key] as number) * factor) / factor;\r\n }\r\n }\r\n\r\n // \u2500\u2500 :map \u2500\u2500\r\n // Syntax: key:map:source_key\\n - lookup_val result_text\r\n if (markers.includes('map') && Array.isArray(obj[key])) {\r\n const idx = markers.indexOf('map');\r\n const sourceKey = markers[idx + 1] ?? '';\r\n const lookupVal = String(sourceKey ? (deepGet(root, sourceKey) ?? deepGet(obj, sourceKey) ?? '') : '');\r\n const arr = obj[key] as string[];\r\n const found = arr.find((item) => {\r\n const s = String(item);\r\n const sep = s.indexOf(' ');\r\n return sep !== -1 && s.substring(0, sep).trim() === lookupVal;\r\n });\r\n obj[key] = found\r\n ? castPrimitive(found.substring(found.indexOf(' ') + 1).trim())\r\n : null;\r\n }\r\n\r\n // \u2500\u2500 :format \u2500\u2500\r\n // Syntax: key:format:PATTERN value (e.g. %.2f, %05d)\r\n if (markers.includes('format')) {\r\n const idx = markers.indexOf('format');\r\n const pattern = markers[idx + 1] ?? '%s';\r\n obj[key] = applyFormatPattern(pattern, obj[key]);\r\n }\r\n\r\n // \u2500\u2500 :fallback \u2500\u2500\r\n // Syntax: key:fallback:DEFAULT_PATH value\r\n // If value is empty OR file does not exist, use the fallback.\r\n if (markers.includes('fallback')) {\r\n const idx = markers.indexOf('fallback');\r\n const defaultVal = markers[idx + 1] ?? '';\r\n const current = obj[key];\r\n let useFallback = current === null || current === undefined || current === '';\r\n if (!useFallback && typeof current === 'string' && fs && pathModule && options.basePath) {\r\n try {\r\n const fullPath = jailPath(options.basePath, current);\r\n useFallback = !fs.existsSync(fullPath);\r\n } catch {\r\n useFallback = true; // path escapes jail \u2192 treat as missing \u2192 use fallback\r\n }\r\n }\r\n if (useFallback && defaultVal) {\r\n obj[key] = defaultVal;\r\n }\r\n }\r\n\r\n // \u2500\u2500 :once \u2500\u2500\r\n // Syntax: key:once or key:once:uuid or key:once:random or key:once:timestamp\r\n // Generates a value once and persists it in a .synx.lock file.\r\n if (markers.includes('once')) {\r\n const idx = markers.indexOf('once');\r\n const genType = markers[idx + 1] ?? 'uuid';\r\n const lockPath = pathModule && options.basePath\r\n ? pathModule.resolve(options.basePath, '.synx.lock')\r\n : '.synx.lock';\r\n\r\n const existing = readLockValue(lockPath, key);\r\n if (existing !== null) {\r\n obj[key] = existing;\r\n } else {\r\n let generated: string;\r\n if (genType === 'uuid') {\r\n generated = generateUuid();\r\n } else if (genType === 'timestamp') {\r\n generated = String(Date.now());\r\n } else if (genType === 'random') {\r\n generated = String(Math.floor(Math.random() * 2147483647));\r\n } else {\r\n generated = generateUuid();\r\n }\r\n writeLockValue(lockPath, key, generated);\r\n obj[key] = generated;\r\n }\r\n }\r\n\r\n // \u2500\u2500 :version \u2500\u2500\r\n // Syntax: key:version:OP:REQUIRED value\r\n // Compares current version string against required, returns bool.\r\n if (markers.includes('version') && typeof obj[key] === 'string') {\r\n const idx = markers.indexOf('version');\r\n const op = markers[idx + 1] ?? '>=';\r\n const required = markers[idx + 2] ?? '0';\r\n obj[key] = compareVersions(obj[key] as string, op, required) as any;\r\n }\r\n\r\n // \u2500\u2500 :watch \u2500\u2500\r\n // Syntax: key:watch:KEY_PATH ./file (reads at parse time)\r\n if (markers.includes('watch') && typeof obj[key] === 'string') {\r\n if (!fs || !pathModule) {\r\n obj[key] = 'WATCH_ERR: not supported in browser';\r\n } else {\r\n const maxDepth = options.maxIncludeDepth ?? DEFAULT_MAX_INCLUDE_DEPTH;\r\n const currentDepth = (options as any)._includeDepth ?? 0;\r\n if (currentDepth >= maxDepth) {\r\n obj[key] = `WATCH_ERR: max include depth (${maxDepth}) exceeded`;\r\n } else {\r\n const filePath = obj[key] as string;\r\n const basePath = options.basePath || (typeof process !== 'undefined' ? process.cwd() : '.');\r\n const idx = markers.indexOf('watch');\r\n const keyPath = markers[idx + 1];\r\n try {\r\n const fullPath = jailPath(basePath, filePath);\r\n checkFileSize(fullPath);\r\n const content = fs.readFileSync(fullPath, 'utf-8');\r\n const ext = pathModule.extname(fullPath).slice(1);\r\n if (keyPath) {\r\n obj[key] = extractFromFileContent(content, keyPath, ext) as any;\r\n } else {\r\n obj[key] = content.trim();\r\n }\r\n } catch (e: any) {\r\n obj[key] = `WATCH_ERR: ${e.message}`;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // \u2500\u2500 :prompt \u2500\u2500\r\n // Converts a subtree to a SYNX-formatted string wrapped in a labeled code fence.\r\n if (markers.includes('prompt')) {\r\n const idx = markers.indexOf('prompt');\r\n const label = markers[idx + 1] ?? key;\r\n const val = obj[key];\r\n const synxText = stringifyValue(val, 0);\r\n obj[key] = `${label} (SYNX):\\n\\`\\`\\`synx\\n${synxText}\\`\\`\\``;\r\n }\r\n\r\n // \u2500\u2500 :vision \u2500\u2500\r\n // Metadata-only marker. Recognized (no error), value passes through.\r\n\r\n // \u2500\u2500 :audio \u2500\u2500\r\n // Metadata-only marker. Recognized (no error), value passes through.\r\n\r\n // \u2500\u2500 Constraint validation (always last, after all markers resolved) \u2500\u2500\r\n if (metaMap && metaMap[key]?.constraints) {\r\n validateConstraints(obj, key, metaMap[key].constraints!);\r\n }\r\n }\r\n\r\n // \u2500\u2500 Auto-{} interpolation (separate pass, runs on ALL string values) \u2500\u2500\r\n for (const key of Object.keys(obj)) {\r\n if (key === '__synx') continue;\r\n if (typeof obj[key] === 'string' && (obj[key] as string).includes('{')) {\r\n obj[key] = resolveInterpolation(obj[key] as string, root, obj, includesMap);\r\n }\r\n }\r\n\r\n return obj;\r\n}\r\n\r\n// \u2500\u2500\u2500 Inheritance pre-pass \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction applyInheritance(obj: SynxObject): void {\r\n const metaMap: SynxMetaMap | undefined = (obj as any).__synx;\r\n if (!metaMap) return;\r\n\r\n for (const key of Object.keys(obj)) {\r\n if (key === '__synx') continue;\r\n const meta = metaMap[key];\r\n if (!meta || !meta.markers.includes('inherit')) continue;\r\n\r\n const idx = meta.markers.indexOf('inherit');\r\n const parentName = meta.markers[idx + 1];\r\n if (!parentName) continue;\r\n\r\n const parentObj = obj[parentName];\r\n if (!parentObj || typeof parentObj !== 'object' || Array.isArray(parentObj)) continue;\r\n\r\n const childObj = obj[key];\r\n if (!childObj || typeof childObj !== 'object' || Array.isArray(childObj)) continue;\r\n\r\n // Merge: parent fields first, child fields override\r\n const merged: SynxObject = { ...(parentObj as SynxObject), ...(childObj as SynxObject) };\r\n // Copy over __synx metadata from both parent and child\r\n const parentMeta: SynxMetaMap | undefined = (parentObj as any).__synx;\r\n const childMeta: SynxMetaMap | undefined = (childObj as any).__synx;\r\n if (parentMeta || childMeta) {\r\n const mergedMeta = { ...(parentMeta || {}), ...(childMeta || {}) };\r\n Object.defineProperty(merged, '__synx', {\r\n value: mergedMeta,\r\n enumerable: false,\r\n writable: true,\r\n configurable: true,\r\n });\r\n }\r\n obj[key] = merged;\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 Auto-{} interpolation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/**\r\n * Resolve {key}, {key.nested}, {key:alias}, {key:include} placeholders.\r\n * - {key} \u2014 look up in root, then local scope\r\n * - {key:alias} \u2014 look up in included file with that alias\r\n * - {key:include} \u2014 look up in the first (only) included file\r\n */\r\nfunction resolveInterpolation(\r\n tpl: string,\r\n root: SynxObject,\r\n local: SynxObject,\r\n includesMap?: Map<string, SynxObject>,\r\n): string {\r\n return tpl.replace(/\\{(\\w+(?:\\.\\w+)*)(?::(\\w+(?:[./\\\\][\\w./\\\\]*)?))?\\}/g, (_match, ref: string, scope: string | undefined) => {\r\n if (scope) {\r\n // {key:alias} or {key:include}\r\n if (scope === 'include') {\r\n if (!includesMap || includesMap.size === 0) return _match;\r\n if (includesMap.size > 1) return 'INCLUDE_ERR: multiple !include \u2014 specify alias';\r\n const firstInclude = includesMap.values().next().value!;\r\n const val = deepGet(firstInclude, ref);\r\n return val != null ? String(val) : _match;\r\n }\r\n // Look up by alias\r\n if (includesMap) {\r\n const incl = includesMap.get(scope);\r\n if (incl) {\r\n const val = deepGet(incl, ref);\r\n return val != null ? String(val) : _match;\r\n }\r\n }\r\n return _match;\r\n }\r\n // {key} \u2014 local file\r\n const val = deepGet(root, ref) ?? deepGet(local, ref);\r\n return val != null ? String(val) : _match;\r\n });\r\n}\r\n\r\n// \u2500\u2500\u2500 !include loader \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction loadIncludes(\r\n includes: SynxInclude[],\r\n options: SynxOptions,\r\n): Map<string, SynxObject> {\r\n const map = new Map<string, SynxObject>();\r\n if (!fs || !pathModule) return map;\r\n const basePath = options.basePath || (typeof process !== 'undefined' ? process.cwd() : '.');\r\n const maxDepth = options.maxIncludeDepth ?? DEFAULT_MAX_INCLUDE_DEPTH;\r\n const currentDepth = (options as any)._includeDepth ?? 0;\r\n if (currentDepth >= maxDepth) return map;\r\n for (const inc of includes) {\r\n try {\r\n const fullPath = jailPath(basePath, inc.path);\r\n checkFileSize(fullPath);\r\n const text = fs.readFileSync(fullPath, 'utf-8');\r\n const { root, mode } = parseData(text);\r\n if (mode === 'active') {\r\n resolve(root, { ...options, basePath: pathModule.dirname(fullPath), _includeDepth: currentDepth + 1 } as any, undefined, map);\r\n }\r\n map.set(inc.alias, root);\r\n } catch (e: any) {\r\n // Include loading failed \u2014 skip silently\r\n }\r\n }\r\n return map;\r\n}\r\n\r\n// \u2500\u2500\u2500 Constraint enforcement \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction validateConstraints(obj: SynxObject, key: string, c: import('./types').SynxConstraints): void {\r\n const val = obj[key];\r\n\r\n // required\r\n if (c.required && (val === null || val === undefined || val === '')) {\r\n obj[key] = `CONSTRAINT_ERR: '${key}' is required`;\r\n return;\r\n }\r\n if (val === null || val === undefined) return;\r\n\r\n // type check\r\n if (c.type) {\r\n const ok = (() => {\r\n switch (c.type) {\r\n case 'int': return typeof val === 'number' && Number.isInteger(val);\r\n case 'float': return typeof val === 'number';\r\n case 'bool': return typeof val === 'boolean';\r\n case 'string': return typeof val === 'string';\r\n default: return true;\r\n }\r\n })();\r\n if (!ok) {\r\n obj[key] = `CONSTRAINT_ERR: '${key}' expected type '${c.type}'`;\r\n return;\r\n }\r\n }\r\n\r\n // enum check\r\n if (c.enum) {\r\n const strVal = String(val);\r\n if (!c.enum.includes(strVal)) {\r\n obj[key] = `CONSTRAINT_ERR: '${key}' must be one of [${c.enum.join('|')}]`;\r\n return;\r\n }\r\n }\r\n\r\n // min / max (numbers: value range; strings: length range)\r\n const n = typeof val === 'number' ? val\r\n : typeof val === 'string' && (c.min !== undefined || c.max !== undefined)\r\n ? val.length : null;\r\n if (n !== null) {\r\n if (c.min !== undefined && n < c.min) {\r\n obj[key] = `CONSTRAINT_ERR: '${key}' value ${n} is below min ${c.min}`;\r\n return;\r\n }\r\n if (c.max !== undefined && n > c.max) {\r\n obj[key] = `CONSTRAINT_ERR: '${key}' value ${n} exceeds max ${c.max}`;\r\n return;\r\n }\r\n }\r\n\r\n // pattern (regex match \u2014 reject pathological patterns to prevent ReDoS)\r\n if (c.pattern && typeof val === 'string') {\r\n if (c.pattern.length > 128) return;\r\n try {\r\n if (!new RegExp(c.pattern).test(val)) {\r\n obj[key] = `CONSTRAINT_ERR: '${key}' does not match pattern /${c.pattern}/`;\r\n return;\r\n }\r\n } catch { /* invalid regex \u2014 skip silently */ }\r\n }\r\n}\r\n\r\n// \u2500\u2500\u2500 New-marker helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\nfunction applyFormatPattern(pattern: string, value: unknown): string {\r\n const n = typeof value === 'number' ? value : parseFloat(String(value));\r\n if (isNaN(n)) return String(value);\r\n\r\n // %.2f \u2192 fixed decimals\r\n const floatMatch = pattern.match(/^%\\.(\\d+)f$/);\r\n if (floatMatch) return n.toFixed(parseInt(floatMatch[1], 10));\r\n\r\n // %05d \u2192 zero-padded integer\r\n const intMatch = pattern.match(/^%0(\\d+)d$/);\r\n if (intMatch) return String(Math.round(n)).padStart(parseInt(intMatch[1], 10), '0');\r\n\r\n // %5d \u2192 right-padded integer\r\n const widthMatch = pattern.match(/^%(\\d+)d$/);\r\n if (widthMatch) return String(Math.round(n)).padStart(parseInt(widthMatch[1], 10));\r\n\r\n // %e \u2192 exponential\r\n if (pattern === '%e') return n.toExponential();\r\n\r\n return String(value);\r\n}\r\n\r\nfunction readLockValue(lockPath: string, key: string): string | null {\r\n if (!fs) return null;\r\n try {\r\n const content = fs.readFileSync(lockPath, 'utf-8');\r\n for (const line of content.split(/\\r?\\n/)) {\r\n if (line.startsWith(key + ' ')) {\r\n return line.substring(key.length + 1);\r\n }\r\n }\r\n } catch { /* file doesn't exist yet */ }\r\n return null;\r\n}\r\n\r\nfunction writeLockValue(lockPath: string, key: string, value: string): void {\r\n if (!fs) return;\r\n let lines: string[] = [];\r\n try { lines = fs.readFileSync(lockPath, 'utf-8').split(/\\r?\\n/); } catch { /* ok */ }\r\n const newLine = `${key} ${value}`;\r\n const idx = lines.findIndex((l) => l.startsWith(key + ' '));\r\n if (idx !== -1) {\r\n lines[idx] = newLine;\r\n } else {\r\n lines.push(newLine);\r\n }\r\n try { fs.writeFileSync(lockPath, lines.filter(Boolean).join('\\n') + '\\n', 'utf-8'); } catch { /* ok */ }\r\n}\r\n\r\nfunction generateUuid(): string {\r\n if (typeof crypto !== 'undefined' && typeof (crypto as any).randomUUID === 'function') {\r\n return (crypto as any).randomUUID();\r\n }\r\n // Fallback manual generation\r\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\r\n const r = Math.random() * 16 | 0;\r\n return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);\r\n });\r\n}\r\n\r\nfunction compareVersions(current: string, op: string, required: string): boolean {\r\n const parseVer = (s: string) => s.split('.').map((p) => parseInt(p, 10) || 0);\r\n const cv = parseVer(current);\r\n const rv = parseVer(required);\r\n const len = Math.max(cv.length, rv.length);\r\n let cmp = 0;\r\n for (let i = 0; i < len; i++) {\r\n const a = cv[i] ?? 0;\r\n const b = rv[i] ?? 0;\r\n if (a !== b) { cmp = a > b ? 1 : -1; break; }\r\n }\r\n switch (op) {\r\n case '>=': return cmp >= 0;\r\n case '<=': return cmp <= 0;\r\n case '>': return cmp > 0;\r\n case '<': return cmp < 0;\r\n case '==': case '=': return cmp === 0;\r\n case '!=': return cmp !== 0;\r\n default: return false;\r\n }\r\n}\r\n\r\nfunction extractFromFileContent(content: string, keyPath: string, ext: string): unknown {\r\n if (ext === 'json') {\r\n try {\r\n const obj = JSON.parse(content);\r\n return keyPath.split('.').reduce((o: any, k) => o?.[k], obj) ?? null;\r\n } catch { return null; }\r\n }\r\n // SYNX key lookup \u2014 parse the file and do a deep-get by dot-path\r\n try {\r\n const { root: parsed } = parseData(content);\r\n return deepGet(parsed, keyPath) ?? null;\r\n } catch { return null; }\r\n}\r\n\r\n// \u2500\u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n/** Serialize a value to SYNX format string (for :prompt marker). */\r\nfunction stringifyValue(value: unknown, indent: number): string {\r\n const sp = ' '.repeat(indent);\r\n if (value === null || value === undefined) return `${sp}null\\n`;\r\n if (typeof value === 'boolean' || typeof value === 'number') return `${sp}${value}\\n`;\r\n if (typeof value === 'string') return `${sp}${value}\\n`;\r\n if (Array.isArray(value)) {\r\n let out = '';\r\n for (const item of value) out += `${sp} - ${String(item)}\\n`;\r\n return out;\r\n }\r\n if (typeof value === 'object') {\r\n let out = '';\r\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\r\n if (k === '__synx') continue;\r\n if (v && typeof v === 'object' && !Array.isArray(v)) {\r\n out += `${sp}${k}\\n`;\r\n out += stringifyValue(v, indent + 2);\r\n } else if (Array.isArray(v)) {\r\n out += `${sp}${k}\\n`;\r\n for (const item of v) out += `${sp} - ${String(item)}\\n`;\r\n } else {\r\n out += `${sp}${k} ${v ?? 'null'}\\n`;\r\n }\r\n }\r\n return out;\r\n }\r\n return `${sp}${String(value)}\\n`;\r\n}\r\n\r\nfunction castPrimitive(val: string): SynxValue {\r\n if (val === 'true') return true;\r\n if (val === 'false') return false;\r\n if (val === 'null') return null;\r\n if (/^-?\\d+$/.test(val)) return parseInt(val, 10);\r\n if (/^-?\\d+\\.\\d+$/.test(val)) return parseFloat(val);\r\n return val;\r\n}\r\n\r\nconst DELIM_MAP: Record<string, string> = {\r\n space: ' ', pipe: '|', dash: '-', dot: '.', semi: ';', tab: '\\t', slash: '/',\r\n};\r\n\r\nfunction delimiterFromKeyword(keyword: string): string {\r\n return DELIM_MAP[keyword] || keyword;\r\n}\r\n\r\nfunction weightedRandom(items: SynxValue[], weights: number[]): SynxValue {\r\n const w: number[] = [...weights];\r\n if (w.length < items.length) {\r\n const assigned = w.reduce((a, b) => a + b, 0);\r\n // When assigned < 100: distribute remaining budget equally.\r\n // When assigned >= 100: give each unassigned item the same average weight\r\n // as the assigned ones so they remain reachable.\r\n const perItem = assigned < 100\r\n ? (100 - assigned) / (items.length - w.length)\r\n : assigned / w.length;\r\n while (w.length < items.length) w.push(perItem);\r\n }\r\n\r\n const total = w.reduce((a, b) => a + b, 0);\r\n if (total <= 0) return items[Math.floor(Math.random() * items.length)];\r\n\r\n const rand = Math.random();\r\n let cumulative = 0;\r\n for (let i = 0; i < items.length; i++) {\r\n cumulative += w[i] / total;\r\n if (rand <= cumulative) return items[i];\r\n }\r\n return items[items.length - 1];\r\n}\r\n\r\n// \u2500\u2500\u2500 Word-boundary variable substitution (replaces per-key RegExp creation) \u2500\r\n\r\nfunction isWordChar(code: number): boolean {\r\n return (code >= 48 && code <= 57) // 0-9\r\n || (code >= 65 && code <= 90) // A-Z\r\n || (code >= 97 && code <= 122) // a-z\r\n || code === 95; // _\r\n}\r\n\r\nfunction replaceWord(haystack: string, word: string, replacement: string): string {\r\n const wLen = word.length;\r\n const hLen = haystack.length;\r\n let result = '';\r\n let i = 0;\r\n while (i <= hLen - wLen) {\r\n if (haystack.slice(i, i + wLen) === word) {\r\n const before = i === 0 || !isWordChar(haystack.charCodeAt(i - 1));\r\n const after = i + wLen >= hLen || !isWordChar(haystack.charCodeAt(i + wLen));\r\n if (before && after) {\r\n result += replacement;\r\n i += wLen;\r\n continue;\r\n }\r\n }\r\n result += haystack[i++];\r\n }\r\n while (i < hLen) result += haystack[i++];\r\n return result;\r\n}\r\n\r\n/** Substitute all variable references in `expr` without creating RegExp objects. */\r\nfunction replaceVars(expr: string, vars: Map<string, string>): string {\r\n // Process longer keys first to avoid partial-match issues (e.g. \"hp\" vs \"base_hp\")\r\n const sorted = [...vars.entries()].sort((a, b) => b[0].length - a[0].length);\r\n let result = expr;\r\n for (const [k, v] of sorted) result = replaceWord(result, k, v);\r\n return result;\r\n}\r\n\r\nfunction allowSpamAccess(bucketKey: string, maxCalls: number, windowSec: number): boolean {\r\n const now = Date.now();\r\n const windowMs = windowSec * 1000;\r\n const calls = SPAM_BUCKETS.get(bucketKey) ?? [];\r\n const filtered = calls.filter((ts) => now - ts <= windowMs);\r\n\r\n if (filtered.length >= maxCalls) {\r\n SPAM_BUCKETS.set(bucketKey, filtered);\r\n return false;\r\n }\r\n\r\n if (filtered.length === 0 && calls.length > 0) {\r\n SPAM_BUCKETS.delete(bucketKey);\r\n }\r\n\r\n filtered.push(now);\r\n SPAM_BUCKETS.set(bucketKey, filtered);\r\n return true;\r\n}\r\n\r\nfunction deepGet(obj: SynxObject, path: string): SynxValue | undefined {\r\n // Try direct key first (own property only)\r\n if (Object.prototype.hasOwnProperty.call(obj, path)) return obj[path];\r\n // Try dot-path\r\n const parts = path.split('.');\r\n let current: any = obj;\r\n for (const part of parts) {\r\n if (current == null || typeof current !== 'object') return undefined;\r\n if (!Object.prototype.hasOwnProperty.call(current, part)) return undefined;\r\n current = current[part];\r\n }\r\n return current;\r\n}\r\n", "/**\r\n * SYNX Types \u2014 @aperturesyndicate/synx\r\n * Core type definitions for the SYNX parser.\r\n */\r\n\r\n/** Primitive value types that SYNX supports */\r\nexport type SynxPrimitive = string | number | boolean | null;\r\n\r\n/** A SYNX value can be a primitive, an array, or a nested object */\r\nexport type SynxValue = SynxPrimitive | SynxArray | SynxObject;\r\n\r\n/** SYNX array (list of values) */\r\nexport type SynxArray = SynxValue[];\r\n\r\n/** SYNX object (key-value map) */\r\nexport interface SynxObject {\r\n [key: string]: SynxValue;\r\n}\r\n\r\n/** File mode: static (no functions) or active (functions + constraints enabled) */\r\nexport type SynxMode = 'static' | 'active';\r\n\r\n/** Supported function markers */\r\nexport type SynxMarker =\r\n | 'random'\r\n | 'calc'\r\n | 'env'\r\n | 'alias'\r\n | 'ref'\r\n | 'inherit'\r\n | 'i18n'\r\n | 'secret'\r\n | 'default'\r\n | 'unique'\r\n | 'include'\r\n | 'geo'\r\n | 'template'\r\n | 'split'\r\n | 'join'\r\n | 'clamp'\r\n | 'round'\r\n | 'map'\r\n | 'format'\r\n | 'fallback'\r\n | 'once'\r\n | 'version'\r\n | 'watch'\r\n | 'prompt'\r\n | 'vision'\r\n | 'audio';\r\n\r\n/** Constraint types for [] validation */\r\nexport interface SynxConstraints {\r\n min?: number;\r\n max?: number;\r\n type?: string;\r\n required?: boolean;\r\n pattern?: string;\r\n enum?: string[];\r\n readonly?: boolean;\r\n}\r\n\r\n/** Internal metadata attached to a key (non-enumerable) */\r\nexport interface SynxMeta {\r\n markers: string[];\r\n args?: string[]; // e.g. percentages for :random\r\n constraints?: SynxConstraints;\r\n typeHint?: string; // e.g. 'string', 'int', 'float'\r\n}\r\n\r\n/** Map of key \u2192 metadata for a single object level */\r\nexport interface SynxMetaMap {\r\n [key: string]: SynxMeta;\r\n}\r\n\r\n/** Include directive parsed from !include */\r\nexport interface SynxInclude {\r\n path: string;\r\n alias: string;\r\n}\r\n\r\n/** Raw parse result before engine resolution */\r\nexport interface SynxParseResult {\r\n mode: SynxMode;\r\n root: SynxObject;\r\n locked?: boolean;\r\n includes?: SynxInclude[];\r\n}\r\n\r\n/** Options for Synx.parse() / Synx.load() */\r\nexport interface SynxOptions {\r\n /** Base directory for :include resolution (default: cwd) */\r\n basePath?: string;\r\n /** Override environment variables (for testing) */\r\n env?: Record<string, string>;\r\n /** Region code for :geo (e.g. \"RU\", \"US\") */\r\n region?: string;\r\n /** Language code for :i18n (e.g. \"en\", \"ru\", \"de\") */\r\n lang?: string;\r\n /** Throw if marker resolution produces runtime error strings (INCLUDE_ERR, WATCH_ERR, etc.) */\r\n strict?: boolean;\r\n /** Maximum include/import nesting depth (default: 16) */\r\n maxIncludeDepth?: number;\r\n}\r\n\r\n/** Structural diff result from Synx.diff() */\r\nexport interface SynxDiff {\r\n added: Record<string, SynxValue>;\r\n removed: Record<string, SynxValue>;\r\n changed: Record<string, { from: SynxValue; to: SynxValue }>;\r\n unchanged: string[];\r\n}\r\n\r\n/**\r\n * Typed error thrown by SYNX in strict mode.\r\n * The `code` field contains the error prefix (e.g. \"CALC_ERR\", \"ALIAS_ERR\").\r\n */\r\nexport class SynxError extends Error {\r\n readonly code: string;\r\n\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'SynxError';\r\n // Extract prefix up to first ':'\r\n const colonIdx = message.indexOf(':');\r\n this.code = colonIdx !== -1 ? message.slice(0, colonIdx) : 'SYNX_ERR';\r\n }\r\n}\r\n", "/**\r\n * SYNX Browser Bundle \u2014 @aperturesyndicate/synx\r\n *\r\n * Lightweight browser-compatible build.\r\n * No Node.js dependencies (fs, path).\r\n * Provides: parse, stringify.\r\n */\r\n\r\nimport { parseData } from './parser';\r\nimport { resolve } from './engine';\r\nimport type { SynxObject, SynxOptions } from './types';\r\n\r\nexport type { SynxObject, SynxOptions, SynxValue, SynxArray, SynxPrimitive } from './types';\r\nexport { SynxError } from './types';\r\n\r\nclass Synx {\r\n static parse<T extends SynxObject = SynxObject>(text: string, options: SynxOptions = {}): T {\r\n const { root, mode } = parseData(text);\r\n if (mode === 'active') {\r\n resolve(root, options);\r\n }\r\n return root as T;\r\n }\r\n\r\n static stringify(obj: SynxObject, active = false): string {\r\n let out = '';\r\n if (active) {\r\n out += '!active\\n';\r\n }\r\n out += serializeObject(obj, 0);\r\n return out;\r\n }\r\n}\r\n\r\nfunction serializeObject(obj: SynxObject, indent: number): string {\r\n let out = '';\r\n const spaces = ' '.repeat(indent);\r\n\r\n for (const [key, val] of Object.entries(obj)) {\r\n if (Array.isArray(val)) {\r\n out += `${spaces}${key}\\n`;\r\n for (const item of val) {\r\n if (item && typeof item === 'object' && !Array.isArray(item)) {\r\n const entries = Object.entries(item as SynxObject);\r\n if (entries.length > 0) {\r\n const [firstKey, firstVal] = entries[0];\r\n out += `${spaces} - ${firstKey} ${firstVal}\\n`;\r\n for (let i = 1; i < entries.length; i++) {\r\n out += `${spaces} ${entries[i][0]} ${entries[i][1]}\\n`;\r\n }\r\n }\r\n } else {\r\n out += `${spaces} - ${item}\\n`;\r\n }\r\n }\r\n } else if (val && typeof val === 'object') {\r\n out += `${spaces}${key}\\n`;\r\n out += serializeObject(val as SynxObject, indent + 2);\r\n } else if (typeof val === 'string' && val.includes('\\n')) {\r\n out += `${spaces}${key} |\\n`;\r\n for (const line of val.split('\\n')) {\r\n out += `${spaces} ${line}\\n`;\r\n }\r\n } else {\r\n out += `${spaces}${key} ${val}\\n`;\r\n }\r\n }\r\n\r\n return out;\r\n}\r\n\r\nexport default Synx;\r\nexport { Synx };\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["castType", "val", "len", "c0", "closeIdx", "hint", "raw", "n", "firstDigit", "fc", "allNumeric", "dotPos", "i", "ch", "stripInlineComment", "result", "slashIdx", "hashIdx", "parseConstraints", "constraints", "start", "end", "part", "colonIdx", "key", "value", "saveMeta", "obj", "markers", "args", "mode", "typeHint", "metaMap", "meta", "LINE_REGEX", "parseData", "text", "lines", "root", "stack", "locked", "includes", "currentBlock", "currentList", "inBlockComment", "rawLine", "rawLen", "indent", "trimEndPos", "trimmed", "trimmedLen", "parts", "inclPath", "alias", "line", "nextNonEmpty", "nl", "ni", "nextLine", "nextIndent", "nfc", "itemObj", "itemMatch", "iKey", "iTypeHint", "iVal", "iValue", "constraintStr", "markerChain", "rawValue", "hasSpecial", "spaceIdx", "j", "match", "valStart", "markerArgs", "nums", "s", "parent", "peekIdx", "pl", "pi", "tokenize", "expr", "tokens", "i", "ch", "num", "ExprParser", "result", "left", "op", "right", "tok", "val", "safeCalc", "fs", "pathModule", "MAX_CALC_EXPR_LEN", "MAX_FILE_SIZE", "DEFAULT_MAX_INCLUDE_DEPTH", "MAX_RESOLVE_DEPTH", "jailPath", "base", "filePath", "resolved", "normalizedBase", "checkFileSize", "stat", "SynxSecret", "value", "hint", "SPAM_BUCKETS", "resolve", "obj", "options", "root", "includesMap", "_resolveDepth", "_currentPath", "applyInheritance", "k", "loadIncludes", "metaMap", "key", "item", "markers", "args", "idx", "maxCalls", "windowSec", "target", "bucketKey", "allowSpamAccess", "resolvedTarget", "deepGet", "maxDepth", "currentDepth", "includePath", "basePath", "fullPath", "text", "included", "includedMode", "parseData", "e", "varName", "envVal", "defaultIdx", "forceString", "fallback", "arr", "weights", "weightedRandom", "calcIdx", "calcExpr", "first", "fullExpr", "safeCalc", "translations", "lang", "val", "expr", "vars", "rKey", "replaceVars", "currentKeyPath", "targetVal", "lastDot", "targetParentPath", "targetLeafKey", "targetParentObj", "seen", "s", "region", "found", "splitIdx", "delimArg", "sep", "delimiterFromKeyword", "castPrimitive", "joinIdx", "v", "forceStr", "lo", "hi", "decimals", "factor", "sourceKey", "lookupVal", "pattern", "applyFormatPattern", "defaultVal", "current", "useFallback", "genType", "lockPath", "existing", "readLockValue", "generated", "generateUuid", "writeLockValue", "op", "required", "compareVersions", "keyPath", "content", "ext", "extractFromFileContent", "label", "synxText", "stringifyValue", "validateConstraints", "resolveInterpolation", "meta", "parentName", "parentObj", "childObj", "merged", "parentMeta", "childMeta", "mergedMeta", "tpl", "local", "_match", "ref", "scope", "firstInclude", "incl", "includes", "map", "inc", "mode", "c", "strVal", "n", "floatMatch", "intMatch", "widthMatch", "line", "lines", "newLine", "r", "parseVer", "p", "cv", "rv", "len", "cmp", "i", "a", "b", "o", "parsed", "indent", "sp", "out", "DELIM_MAP", "keyword", "items", "w", "assigned", "perItem", "total", "rand", "cumulative", "isWordChar", "code", "replaceWord", "haystack", "word", "replacement", "wLen", "hLen", "result", "before", "after", "sorted", "now", "windowMs", "calls", "filtered", "ts", "path", "parts", "part", "SynxError", "message", "colonIdx", "Synx", "text", "options", "root", "mode", "parseData", "resolve", "obj", "active", "out", "serializeObject", "indent", "spaces", "key", "val", "item", "entries", "firstKey", "firstVal", "i", "line", "browser_default"]
|
|
7
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SYNX Types — @aperturesyndicate/synx
|
|
3
|
+
* Core type definitions for the SYNX parser.
|
|
4
|
+
*/
|
|
5
|
+
/** Primitive value types that SYNX supports */
|
|
6
|
+
export type SynxPrimitive = string | number | boolean | null;
|
|
7
|
+
/** A SYNX value can be a primitive, an array, or a nested object */
|
|
8
|
+
export type SynxValue = SynxPrimitive | SynxArray | SynxObject;
|
|
9
|
+
/** SYNX array (list of values) */
|
|
10
|
+
export type SynxArray = SynxValue[];
|
|
11
|
+
/** SYNX object (key-value map) */
|
|
12
|
+
export interface SynxObject {
|
|
13
|
+
[key: string]: SynxValue;
|
|
14
|
+
}
|
|
15
|
+
/** File mode: static (no functions) or active (functions + constraints enabled) */
|
|
16
|
+
export type SynxMode = 'static' | 'active';
|
|
17
|
+
/** Supported function markers */
|
|
18
|
+
export type SynxMarker = 'random' | 'calc' | 'env' | 'alias' | 'ref' | 'inherit' | 'i18n' | 'secret' | 'default' | 'unique' | 'include' | 'geo' | 'template' | 'split' | 'join' | 'clamp' | 'round' | 'map' | 'format' | 'fallback' | 'once' | 'version' | 'watch' | 'prompt' | 'vision' | 'audio';
|
|
19
|
+
/** Constraint types for [] validation */
|
|
20
|
+
export interface SynxConstraints {
|
|
21
|
+
min?: number;
|
|
22
|
+
max?: number;
|
|
23
|
+
type?: string;
|
|
24
|
+
required?: boolean;
|
|
25
|
+
pattern?: string;
|
|
26
|
+
enum?: string[];
|
|
27
|
+
readonly?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** Internal metadata attached to a key (non-enumerable) */
|
|
30
|
+
export interface SynxMeta {
|
|
31
|
+
markers: string[];
|
|
32
|
+
args?: string[];
|
|
33
|
+
constraints?: SynxConstraints;
|
|
34
|
+
typeHint?: string;
|
|
35
|
+
}
|
|
36
|
+
/** Map of key → metadata for a single object level */
|
|
37
|
+
export interface SynxMetaMap {
|
|
38
|
+
[key: string]: SynxMeta;
|
|
39
|
+
}
|
|
40
|
+
/** Include directive parsed from !include */
|
|
41
|
+
export interface SynxInclude {
|
|
42
|
+
path: string;
|
|
43
|
+
alias: string;
|
|
44
|
+
}
|
|
45
|
+
/** Raw parse result before engine resolution */
|
|
46
|
+
export interface SynxParseResult {
|
|
47
|
+
mode: SynxMode;
|
|
48
|
+
root: SynxObject;
|
|
49
|
+
locked?: boolean;
|
|
50
|
+
includes?: SynxInclude[];
|
|
51
|
+
}
|
|
52
|
+
/** Options for Synx.parse() / Synx.load() */
|
|
53
|
+
export interface SynxOptions {
|
|
54
|
+
/** Base directory for :include resolution (default: cwd) */
|
|
55
|
+
basePath?: string;
|
|
56
|
+
/** Override environment variables (for testing) */
|
|
57
|
+
env?: Record<string, string>;
|
|
58
|
+
/** Region code for :geo (e.g. "RU", "US") */
|
|
59
|
+
region?: string;
|
|
60
|
+
/** Language code for :i18n (e.g. "en", "ru", "de") */
|
|
61
|
+
lang?: string;
|
|
62
|
+
/** Throw if marker resolution produces runtime error strings (INCLUDE_ERR, WATCH_ERR, etc.) */
|
|
63
|
+
strict?: boolean;
|
|
64
|
+
/** Maximum include/import nesting depth (default: 16) */
|
|
65
|
+
maxIncludeDepth?: number;
|
|
66
|
+
}
|
|
67
|
+
/** Structural diff result from Synx.diff() */
|
|
68
|
+
export interface SynxDiff {
|
|
69
|
+
added: Record<string, SynxValue>;
|
|
70
|
+
removed: Record<string, SynxValue>;
|
|
71
|
+
changed: Record<string, {
|
|
72
|
+
from: SynxValue;
|
|
73
|
+
to: SynxValue;
|
|
74
|
+
}>;
|
|
75
|
+
unchanged: string[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Typed error thrown by SYNX in strict mode.
|
|
79
|
+
* The `code` field contains the error prefix (e.g. "CALC_ERR", "ALIAS_ERR").
|
|
80
|
+
*/
|
|
81
|
+
export declare class SynxError extends Error {
|
|
82
|
+
readonly code: string;
|
|
83
|
+
constructor(message: string);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE7D,oEAAoE;AACpE,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/D,kCAAkC;AAClC,MAAM,MAAM,SAAS,GAAG,SAAS,EAAE,CAAC;AAEpC,kCAAkC;AAClC,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,mFAAmF;AACnF,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3C,iCAAiC;AACjC,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,MAAM,GACN,KAAK,GACL,OAAO,GACP,KAAK,GACL,SAAS,GACT,MAAM,GACN,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,SAAS,GACT,KAAK,GACL,UAAU,GACV,OAAO,GACP,MAAM,GACN,OAAO,GACP,OAAO,GACP,KAAK,GACL,QAAQ,GACR,UAAU,GACV,MAAM,GACN,SAAS,GACT,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,OAAO,CAAC;AAEZ,yCAAyC;AACzC,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,2DAA2D;AAC3D,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,sDAAsD;AACtD,MAAM,WAAW,WAAW;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAC;CACzB;AAED,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+FAA+F;IAC/F,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,8CAA8C;AAC9C,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,EAAE,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,OAAO,EAAE,MAAM;CAO5B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SYNX Types — @aperturesyndicate/synx
|
|
4
|
+
* Core type definitions for the SYNX parser.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.SynxError = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Typed error thrown by SYNX in strict mode.
|
|
10
|
+
* The `code` field contains the error prefix (e.g. "CALC_ERR", "ALIAS_ERR").
|
|
11
|
+
*/
|
|
12
|
+
class SynxError extends Error {
|
|
13
|
+
constructor(message) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'SynxError';
|
|
16
|
+
// Extract prefix up to first ':'
|
|
17
|
+
const colonIdx = message.indexOf(':');
|
|
18
|
+
this.code = colonIdx !== -1 ? message.slice(0, colonIdx) : 'SYNX_ERR';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.SynxError = SynxError;
|
|
22
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA8GH;;;GAGG;AACH,MAAa,SAAU,SAAQ,KAAK;IAGlC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,iCAAiC;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACxE,CAAC;CACF;AAVD,8BAUC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aperturesyndicate/synx-format",
|
|
3
|
+
"version": "3.6.0",
|
|
4
|
+
"description": "SYNX: The Active Data Format. Faster than JSON, cheaper for AI tokens, built-in logic.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"synx": "bin/synx.js"
|
|
9
|
+
},
|
|
10
|
+
"browser": "dist/synx.browser.mjs",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"require": "./dist/index.js",
|
|
15
|
+
"import": "./dist/synx.browser.mjs"
|
|
16
|
+
},
|
|
17
|
+
"./browser": {
|
|
18
|
+
"types": "./dist/browser.d.ts",
|
|
19
|
+
"require": "./dist/synx.browser.js",
|
|
20
|
+
"import": "./dist/synx.browser.mjs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"bin",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE",
|
|
28
|
+
"SPECIFICATION.md"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc",
|
|
32
|
+
"build:browser": "node build-browser.js",
|
|
33
|
+
"build:all": "tsc && node build-browser.js",
|
|
34
|
+
"test": "npx jest --config jest.config.js",
|
|
35
|
+
"lint": "eslint src/",
|
|
36
|
+
"prepublishOnly": "npm run build:all"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"synx",
|
|
40
|
+
"parser",
|
|
41
|
+
"config",
|
|
42
|
+
"json-alternative",
|
|
43
|
+
"yaml-alternative",
|
|
44
|
+
"ai-optimized",
|
|
45
|
+
"data-format",
|
|
46
|
+
"active-config"
|
|
47
|
+
],
|
|
48
|
+
"author": "APERTURESyndicate <support@aperturesyndicate.com>",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/kaiserrberg/synx-format"
|
|
53
|
+
},
|
|
54
|
+
"homepage": "https://github.com/kaiserrberg/synx-format",
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/jest": "^29.5.0",
|
|
57
|
+
"@types/node": "^20.0.0",
|
|
58
|
+
"esbuild": "^0.27.3",
|
|
59
|
+
"jest": "^29.7.0",
|
|
60
|
+
"ts-jest": "^29.1.0",
|
|
61
|
+
"typescript": "^5.4.0"
|
|
62
|
+
}
|
|
63
|
+
}
|