@shapeshift-labs/frontier-lang-parser 0.3.43 → 0.3.44

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.
@@ -83,7 +83,9 @@ function parseActionBodyLine(line, index) {
83
83
  return compactRecord({ kind: 'callEffect', id: idFrom(rest, `action_body_callEffect_${name}`), name, capability: readInlineWord('capability', rest) ?? readInlineWord('effect', rest) ?? name, input: readInlineActionValue('input', rest) });
84
84
  }
85
85
  if (rowKind === 'let') {
86
- return compactRecord({ kind: 'let', id: idFrom(rest, `action_body_let_${name}`), name, value: readInlineActionValue('value', rest) });
86
+ const value = readInlineActionBindingValue('value', rest);
87
+ if (!rawName || rawName.startsWith('@') || !isActionBindingName(name) || !value) return undefined;
88
+ return compactRecord({ kind: 'let', id: idFrom(rest, `action_body_let_${name}`), name, value });
87
89
  }
88
90
  if (rowKind === 'return') {
89
91
  const valueText = rawName?.startsWith('@') ? rest.trim() : `${rawName ?? ''}${rest ?? ''}`.trim();
@@ -161,6 +163,11 @@ function readInlineActionValue(label, text) {
161
163
  return value ? readActionValue(value) : undefined;
162
164
  }
163
165
 
166
+ function readInlineActionBindingValue(label, text) {
167
+ const value = readInlineActionValue(label, text);
168
+ return isSupportedBindingValue(value) ? value : undefined;
169
+ }
170
+
164
171
  function readActionValue(value) {
165
172
  const text = value.trim();
166
173
  const quoted = /^["']([^"']*)["']$/.exec(text);
@@ -172,6 +179,16 @@ function readActionValue(value) {
172
179
  return { expression: text };
173
180
  }
174
181
 
182
+ function isSupportedBindingValue(value) {
183
+ if (!value) return false;
184
+ if (Object.prototype.hasOwnProperty.call(value, 'value')) return true;
185
+ return /^[A-Za-z_$][\w$-]*(?:\.[A-Za-z_$][\w$-]*)*$/.test(String(value.expression ?? '').trim());
186
+ }
187
+
188
+ function isActionBindingName(value) {
189
+ return /^[A-Za-z_$][\w$-]*$/.test(String(value ?? ''));
190
+ }
191
+
175
192
  function idFrom(header, fallback) { return /@id\(\s*["']([^"']+)["']\s*\)/.exec(header)?.[1] ?? fallback; }
176
193
  function readInlineWord(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(text)?.[1]?.trim(); }
177
194
  function firstIdentifier(text) { return /^([A-Za-z_$][\w$-]*)\b/.exec(text)?.[1]; }
@@ -56,7 +56,8 @@ function actionSyntaxChild(source, block, options, line, state, parentActionBody
56
56
  const rowKind = row?.[1] ?? 'unknown';
57
57
  const name = actionRowName(rowKind, row?.[2], rowIndex);
58
58
  const rest = row?.[2]?.startsWith('@') ? ` ${row[2]}${row[3] ?? ''}` : (row?.[3] ?? '');
59
- const recognized = ACTION_BODY_ROWS.has(rowKind);
59
+ const validation = validateActionRow(rowKind, row?.[2], rest);
60
+ const recognized = ACTION_BODY_ROWS.has(rowKind) && validation.ok;
60
61
  return cleanRecord({
61
62
  kind: recognized ? 'actionBodyRow' : 'actionUnknownRow',
62
63
  rowKind,
@@ -75,7 +76,7 @@ function actionSyntaxChild(source, block, options, line, state, parentActionBody
75
76
  parentActionBodyId,
76
77
  sourceSpan: sourceSpan(source, block, line.startOffset, line.endOffset, options),
77
78
  recognized,
78
- reason: recognized ? undefined : 'unsupported-action-body-row'
79
+ reason: recognized ? undefined : validation.reason
79
80
  });
80
81
  }
81
82
 
@@ -86,6 +87,29 @@ function actionRowName(rowKind, rawName, rowIndex) {
86
87
  return rawName && !rawName.startsWith('@') ? rawName : `${rowKind}_${rowIndex}`;
87
88
  }
88
89
 
90
+ function validateActionRow(rowKind, rawName, rest) {
91
+ if (!ACTION_BODY_ROWS.has(rowKind)) return { ok: false, reason: 'unsupported-action-body-row' };
92
+ if (rowKind !== 'let') return { ok: true };
93
+ if (!rawName || rawName.startsWith('@') || !/^[A-Za-z_$][\w$-]*$/.test(rawName)) {
94
+ return { ok: false, reason: 'unsupported-action-binding-name' };
95
+ }
96
+ const value = readInlineValue('value', rest);
97
+ if (!value || !isSupportedBindingValue(value)) {
98
+ return { ok: false, reason: 'unsupported-action-binding-value' };
99
+ }
100
+ return { ok: true };
101
+ }
102
+
103
+ function readInlineValue(label, text) {
104
+ return new RegExp('(?:^|\\s)' + label + '\\s+(.+?)(?=\\s+[A-Za-z_$][\\w$-]*\\s+|$)').exec(text)?.[1]?.trim();
105
+ }
106
+
107
+ function isSupportedBindingValue(value) {
108
+ if (/^["'][^"']*["']$/.test(value)) return true;
109
+ if (/^(true|false|null|-?\d+(?:\.\d+)?)$/.test(value)) return true;
110
+ return /^[A-Za-z_$][\w$-]*(?:\.[A-Za-z_$][\w$-]*)*$/.test(value);
111
+ }
112
+
89
113
  function readNestedBodyBlocks(kind, source) {
90
114
  const blocks = [];
91
115
  const header = new RegExp('\\b' + kind.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '(?:\\s+([^{}\\n]+?))?\\s*\\{', 'g');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-parser",
3
- "version": "0.3.43",
3
+ "version": "0.3.44",
4
4
  "description": "Parser for the first Frontier Lang .frontier syntax slice.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",