UNPKG

mlld

Version:

mlld: llm scripting language

1,099 lines (1,090 loc) 35.8 kB
import { resolveValue, ResolutionContext, isVariable } from './chunk-DUS6QZAC.mjs'; import { FieldAccessError } from './chunk-V5XE5YB5.mjs'; import { isTimeDurationNode, isVariableReferenceNode } from './chunk-6PZVQRSR.mjs'; import { wrapStructured, createArrayVariable, isStructuredValue, asData, asText, inheritExpressionProvenance } from './chunk-RKGZ44GZ.mjs'; import { isLoadContentResult } from './chunk-TZUIAYSF.mjs'; import { __name, __publicField } from './chunk-NJQT543K.mjs'; import * as fs from 'fs'; import * as util from 'util'; // interpreter/utils/array-operations/slice/SliceHandler.ts var _SliceHandler = class _SliceHandler { perform(items, start, end) { const len = items.length; const actualStart = this.normalizeIndex(start, len, 0); const actualEnd = this.normalizeIndex(end, len, len); if (actualStart >= actualEnd) { return []; } return items.slice(actualStart, actualEnd); } normalizeIndex(index, length, defaultValue) { if (index === null || index === void 0) { return defaultValue; } if (index < 0) { return Math.max(0, length + index); } return Math.min(index, length); } }; __name(_SliceHandler, "SliceHandler"); var SliceHandler = _SliceHandler; // interpreter/utils/array-operations/filter/DurationComparator.ts var _DurationComparator = class _DurationComparator { compare(fieldValue, operator, duration) { const fieldDate = new Date(fieldValue); if (isNaN(fieldDate.getTime())) { console.warn(`Invalid date value for duration comparison: ${fieldValue}`); return false; } const now = /* @__PURE__ */ new Date(); const ageInMs = now.getTime() - fieldDate.getTime(); const durationInMs = this.durationToMs(duration); switch (operator) { case ">": return ageInMs > durationInMs; case ">=": return ageInMs >= durationInMs; case "<": return ageInMs < durationInMs; case "<=": return ageInMs <= durationInMs; case "==": return Math.abs(ageInMs - durationInMs) < 6e4; // Within 1 minute case "!=": return Math.abs(ageInMs - durationInMs) >= 6e4; default: console.warn(`Invalid operator for duration comparison: ${operator}`); return false; } } durationToMs(duration) { const value = duration.value; switch (duration.unit) { case "seconds": return value * 1e3; case "minutes": return value * 60 * 1e3; case "hours": return value * 60 * 60 * 1e3; case "days": return value * 24 * 60 * 60 * 1e3; case "weeks": return value * 7 * 24 * 60 * 60 * 1e3; case "years": return value * 365 * 24 * 60 * 60 * 1e3; default: console.warn(`Unknown duration unit: ${duration.unit}`); return 0; } } }; __name(_DurationComparator, "DurationComparator"); var DurationComparator = _DurationComparator; // interpreter/utils/array-operations/filter/FieldAccessor.ts var _FieldAccessor = class _FieldAccessor { get(item, field) { if (typeof field === "string") { return this.getSimpleField(item, field); } let current = item; for (const key of field) { if (current == null) { return void 0; } current = this.getSimpleField(current, key); } return current; } getSimpleField(obj, field) { if (obj == null) { return void 0; } if (typeof obj === "object") { return obj[field]; } return void 0; } }; __name(_FieldAccessor, "FieldAccessor"); var FieldAccessor = _FieldAccessor; // interpreter/utils/array-operations/filter/FilterEvaluator.ts var _FilterEvaluator = class _FilterEvaluator { constructor() { __publicField(this, "durationComparator", new DurationComparator()); __publicField(this, "fieldAccessor", new FieldAccessor()); } async evaluate(item, condition, env) { const fieldValue = this.fieldAccessor.get(item, condition.field); if (!condition.operator) { return this.isTruthy(fieldValue); } const compareValue = await this.resolveCompareValue(condition.value, env); if (isTimeDurationNode(compareValue)) { return this.durationComparator.compare(fieldValue, condition.operator, compareValue); } return this.compareValues(fieldValue, condition.operator, compareValue); } async resolveCompareValue(value, env) { if (value?.type === "VariableReference") { const variable = env.getVariable(value.identifier); if (!variable) { console.warn(`Variable not found in filter: ${value.identifier}`); return void 0; } const { resolveVariable, ResolutionContext: ResolutionContext2 } = await import('./variable-resolution-HFG3FTZK.mjs'); return await resolveVariable(variable, env, ResolutionContext2.Equality); } return value; } compareValues(left, op, right) { switch (op) { case "==": return this.equalityCompare(left, right); case "!=": return !this.equalityCompare(left, right); case "~": return this.containsCompare(left, right); case ">": return this.numericCompare(left, ">", right); case ">=": return this.numericCompare(left, ">=", right); case "<": return this.numericCompare(left, "<", right); case "<=": return this.numericCompare(left, "<=", right); default: console.warn(`Unknown filter operator: ${op}`); return false; } } equalityCompare(left, right) { if (this.isFalsy(left) && this.isFalsy(right)) { return true; } return left == right; } containsCompare(left, right) { const leftStr = String(left); const rightStr = String(right); return leftStr.includes(rightStr); } numericCompare(left, op, right) { const leftNum = Number(left); const rightNum = Number(right); if (!isNaN(leftNum) && !isNaN(rightNum)) { switch (op) { case ">": return leftNum > rightNum; case ">=": return leftNum >= rightNum; case "<": return leftNum < rightNum; case "<=": return leftNum <= rightNum; } } const leftStr = String(left); const rightStr = String(right); switch (op) { case ">": return leftStr > rightStr; case ">=": return leftStr >= rightStr; case "<": return leftStr < rightStr; case "<=": return leftStr <= rightStr; } return false; } isTruthy(value) { if (value === void 0 || value === null) return false; if (value === false || value === "false") return false; if (value === "" || value === 0) return false; return true; } isFalsy(value) { return !this.isTruthy(value); } }; __name(_FilterEvaluator, "FilterEvaluator"); var FilterEvaluator = _FilterEvaluator; // interpreter/utils/array-operations/filter/FilterHandler.ts var _FilterHandler = class _FilterHandler { constructor() { __publicField(this, "evaluator", new FilterEvaluator()); } async perform(items, condition, env) { const results = []; for (const item of items) { const passed = await this.evaluator.evaluate(item, condition, env); if (passed) { results.push(item); } } return results; } }; __name(_FilterHandler, "FilterHandler"); var FilterHandler = _FilterHandler; // interpreter/utils/array-operations/metadata/MetadataPreserver.ts var _MetadataPreserver = class _MetadataPreserver { preserveType(arrayData, transformed) { switch (arrayData.type) { case "array-variable": return this.preserveArrayVariable(arrayData.original, transformed); case "ast-array": return { type: "array", items: transformed }; case "structured-value": { const wrapper = arrayData.original; return wrapStructured(transformed, wrapper && wrapper.type || "array", JSON.stringify(transformed), wrapper?.mx, wrapper?.internal); } case "plain-array": default: return transformed; } } preserveArrayVariable(original, transformed) { return createArrayVariable(original.name, transformed, original.isComplex || false, original.source, { mx: { ...original.mx }, internal: { ...original.internal, transformedBy: "array-operation" } }); } }; __name(_MetadataPreserver, "MetadataPreserver"); var MetadataPreserver = _MetadataPreserver; // interpreter/utils/array-operations/ArrayOperationsHandler.ts var _ArrayOperationsHandler = class _ArrayOperationsHandler { constructor() { __publicField(this, "slice", new SliceHandler()); __publicField(this, "filter", new FilterHandler()); __publicField(this, "preserver", new MetadataPreserver()); } async handle(value, field, env) { const arrayData = this.extractArrayData(value); if (!arrayData) { console.warn(`Array operation ${field.type} on non-array value`); return field.type === "arraySlice" ? [] : value; } switch (field.type) { case "arraySlice": return await this.handleSlice(arrayData, field, env); case "arrayFilter": return await this.handleFilter(arrayData, field, env); default: return null; } } async handleSlice(arrayData, node, env) { const start = await this.resolveSliceIndex(node.start, env); const end = await this.resolveSliceIndex(node.end, env); const sliced = this.slice.perform(arrayData.items, start, end); return this.preserver.preserveType(arrayData, sliced); } async resolveSliceIndex(index, env) { if (index === null || index === void 0) { return null; } if (typeof index === "number") { return index; } if (isVariableReferenceNode(index)) { const variable = env.getVariable(index.identifier); if (!variable) { throw new Error(`Variable not found for slice index: @${index.identifier}`); } const resolved = await resolveValue(variable, env, ResolutionContext.StringInterpolation); const value = isVariable(resolved) ? resolved.value : resolved; if (typeof value !== "number") { throw new Error(`Slice index must resolve to a number, got ${typeof value} from @${index.identifier}`); } return value; } throw new Error(`Invalid slice index type: ${typeof index}`); } async handleFilter(arrayData, node, env) { const filtered = await this.filter.perform(arrayData.items, node.condition, env); return this.preserver.preserveType(arrayData, filtered); } extractArrayData(value) { if (isStructuredValue(value) && value.type === "array") { const data = asData(value); if (Array.isArray(data)) { return { type: "structured-value", items: data, original: value }; } } if (isVariable(value) && value.type === "array") { return { type: "array-variable", items: value.value, original: value }; } if (Array.isArray(value)) { return { type: "plain-array", items: value, original: value }; } if (value?.type === "array" && value.items) { return { type: "ast-array", items: value.items, original: value }; } return null; } }; __name(_ArrayOperationsHandler, "ArrayOperationsHandler"); var ArrayOperationsHandler = _ArrayOperationsHandler; // interpreter/utils/field-access.ts function getObjectField(obj, fieldName) { if (obj.entries && Array.isArray(obj.entries)) { for (const entry of obj.entries) { if (entry.type === "pair" && entry.key === fieldName) { return entry.value; } } return void 0; } if (obj.properties && typeof obj.properties === "object") { return obj.properties[fieldName]; } return void 0; } __name(getObjectField, "getObjectField"); function hasObjectField(obj, fieldName) { if (obj.entries && Array.isArray(obj.entries)) { return obj.entries.some((entry) => entry.type === "pair" && entry.key === fieldName); } if (obj.properties && typeof obj.properties === "object") { return fieldName in obj.properties; } return false; } __name(hasObjectField, "hasObjectField"); function isObjectAST(value) { if (!value || typeof value !== "object" || value.type !== "object") { return false; } if (Array.isArray(value.entries)) { return value.entries.every((entry) => entry && typeof entry === "object" && (entry.type === "pair" && typeof entry.key === "string" && "value" in entry || entry.type === "spread" && "value" in entry)); } return Boolean(value.properties && typeof value.properties === "object"); } __name(isObjectAST, "isObjectAST"); function isPlainObjectValue(value) { if (!value || typeof value !== "object") { return false; } if (Array.isArray(value)) { return false; } if (isObjectAST(value)) { return false; } if (isLoadContentResult(value)) { return false; } const proto = Object.getPrototypeOf(value); return proto === Object.prototype || proto === null; } __name(isPlainObjectValue, "isPlainObjectValue"); function createObjectUtilityMxView(mx, data) { if (!mx || typeof mx !== "object") { return mx; } if (!isPlainObjectValue(data)) { return mx; } const obj = data; const keys = Object.keys(obj); const view = Object.create(mx); Object.defineProperty(view, "keys", { value: keys, enumerable: true, configurable: true }); Object.defineProperty(view, "values", { value: keys.map((key) => obj[key]), enumerable: true, configurable: true }); Object.defineProperty(view, "entries", { value: keys.map((key) => [ key, obj[key] ]), enumerable: true, configurable: true }); return view; } __name(createObjectUtilityMxView, "createObjectUtilityMxView"); var STRING_JSON_ACCESSORS = /* @__PURE__ */ new Set([ "data", "json" ]); var STRING_TEXT_ACCESSORS = /* @__PURE__ */ new Set([ "text", "content" ]); async function accessField(value, field, options) { const parentVariable = isVariable(value) ? value : value?.__variable; let rawValue = isVariable(value) ? value.value : value; const structuredWrapper = isStructuredValue(rawValue) ? rawValue : void 0; const structuredCtx = structuredWrapper?.mx ?? void 0; if (structuredWrapper) { rawValue = structuredWrapper.data; } if (isVariable(value) && field.type === "field") { const fieldName2 = String(field.value); const CORE_METADATA = [ "type", "isComplex", "source", "metadata", "internal", "mx", "raw", "totalTokens", "maxTokens" ]; if (CORE_METADATA.includes(fieldName2)) { const metadataValue = (() => { if (fieldName2 !== "mx") { return value[fieldName2]; } const baseMx = structuredCtx ?? (isLoadContentResult(rawValue) ? rawValue.mx : void 0) ?? value.mx; return createObjectUtilityMxView(baseMx, rawValue); })(); if (options?.preserveContext) { return { value: metadataValue, parentVariable: value, accessPath: [ ...options.parentPath || [], fieldName2 ], isVariable: false }; } return metadataValue; } const GUARD_QUANTIFIERS = [ "all", "any", "none" ]; if (GUARD_QUANTIFIERS.includes(fieldName2)) { const fieldExistsInData = rawValue && typeof rawValue === "object" && fieldName2 in rawValue; if (!fieldExistsInData) { const metadataValue = value[fieldName2]; if (options?.preserveContext) { return { value: metadataValue, parentVariable: value, accessPath: [ ...options.parentPath || [], fieldName2 ], isVariable: false }; } return metadataValue; } } } const fieldValue = field.value; if (process.env.MLLD_DEBUG === "true" && String(fieldValue) === "try") { console.log("\u{1F50D} FIELD ACCESS PRE-CHECK:", { isVar: isVariable(value), rawValueType: typeof rawValue, rawValueKeys: Object.keys(rawValue || {}), rawValueTypeField: rawValue?.type, isObjectAST: isObjectAST(rawValue) }); } let accessedValue; const fieldName = String(fieldValue); switch (field.type) { case "field": case "stringIndex": case "bracketAccess": { const name = String(fieldValue); if (process.env.MLLD_DEBUG_FIX === "true" && name === "length") { console.error("[field-access] length access", { isVariable: isVariable(value), rawType: typeof rawValue, rawKeys: rawValue && typeof rawValue === "object" ? Object.keys(rawValue) : null, rawValueTypeField: rawValue?.type }); try { const preview = Array.isArray(rawValue) && rawValue.length > 0 ? { isArray: true, length: rawValue.length, first: rawValue[0] } : rawValue && typeof rawValue === "object" ? { isArray: Array.isArray(rawValue), sample: util.inspect(rawValue, { depth: 2, breakLength: 120 }) } : rawValue; fs.appendFileSync("/tmp/mlld-debug.log", JSON.stringify({ source: "field-access", field: name, isVariable: isVariable(value), rawType: typeof rawValue, rawKeys: rawValue && typeof rawValue === "object" ? Object.keys(rawValue) : null, rawValueTypeField: rawValue?.type, preview }) + "\n"); } catch { } } if (structuredWrapper) { if (name === "text") { if (rawValue && typeof rawValue === "object" && name in rawValue && structuredWrapper.mx?.source !== "load-content") { accessedValue = rawValue[name]; } else { accessedValue = asText(structuredWrapper); } break; } if (name === "data") { if (rawValue && typeof rawValue === "object" && name in rawValue) { accessedValue = rawValue[name]; } else { accessedValue = asData(structuredWrapper); } break; } if (name === "keepStructured") { if (structuredWrapper.internal) { structuredWrapper.internal.keepStructured = true; } else { structuredWrapper.internal = { keepStructured: true }; } accessedValue = structuredWrapper; break; } if (name === "keep") { if (structuredWrapper.internal) { structuredWrapper.internal.keepStructured = true; } else { structuredWrapper.internal = { keepStructured: true }; } accessedValue = structuredWrapper; break; } if (name === "type") { accessedValue = structuredWrapper.type; break; } if (name === "metadata") { accessedValue = structuredWrapper.metadata; break; } if (name === "mx") { accessedValue = createObjectUtilityMxView(structuredWrapper.mx, rawValue); break; } if (structuredCtx && typeof structuredCtx === "object" && name in structuredCtx && structuredCtx[name] !== void 0) { accessedValue = structuredCtx[name]; break; } } if (process.env.MLLD_DEBUG_STRUCTURED === "true") { const debugKeys = typeof rawValue === "object" && rawValue !== null ? Object.keys(rawValue) : void 0; const dataKeys = structuredWrapper && structuredWrapper.data && typeof structuredWrapper.data === "object" ? Object.keys(structuredWrapper.data) : void 0; console.error("[field-access]", { name, rawValueType: typeof rawValue, hasStructuredWrapper: Boolean(structuredWrapper), keys: debugKeys, dataKeys }); } if (typeof rawValue === "string") { if (STRING_JSON_ACCESSORS.has(name)) { const trimmed2 = rawValue.trim(); try { accessedValue = JSON.parse(trimmed2); break; } catch { const chain = [ ...options?.parentPath || [], name ]; throw new FieldAccessError(`String value cannot be parsed as JSON for accessor "${name}"`, { baseValue: rawValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: name }, { sourceLocation: options?.sourceLocation, env: options?.env }); } } if (STRING_TEXT_ACCESSORS.has(name)) { accessedValue = rawValue; break; } if (name === "length") { accessedValue = rawValue.length; break; } const trimmed = rawValue.trim(); if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) { const chain = [ ...options?.parentPath || [], name ]; throw new FieldAccessError(`Cannot access field "${name}" on JSON string. Use \`.data.${name}\` or pipe through \`| @json\` first.`, { baseValue: rawValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: name, isJsonString: true }, { sourceLocation: options?.sourceLocation, env: options?.env }); } } if (typeof rawValue !== "object" || rawValue === null) { if (structuredCtx && typeof structuredCtx === "object" && name in structuredCtx && structuredCtx[name] !== void 0) { accessedValue = structuredCtx[name]; break; } const chain = [ ...options?.parentPath || [], name ]; const msg = `Cannot access field "${name}" on non-object value (${typeof rawValue})`; throw new FieldAccessError(msg, { baseValue: rawValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: name }, { sourceLocation: options?.sourceLocation, env: options?.env }); } if (isLoadContentResult(rawValue)) { if (name in rawValue) { const result = rawValue[name]; if (result !== void 0) { accessedValue = result; break; } } if (rawValue.json !== void 0) { const jsonData = rawValue.json; if (jsonData && typeof jsonData === "object" && name in jsonData) { accessedValue = jsonData[name]; break; } } { const chain = [ ...options?.parentPath || [], name ]; const msg = `Field "${name}" not found in LoadContentResult`; throw new FieldAccessError(msg, { baseValue: rawValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: name }, { sourceLocation: options?.sourceLocation, env: options?.env }); } } if (structuredWrapper && structuredWrapper.type === "array") { if (name === "content" || name === "text") { accessedValue = structuredWrapper.text; break; } if (name === "length") { accessedValue = structuredWrapper.data.length; break; } const result = rawValue[name]; if (result !== void 0) { accessedValue = result; break; } } if (rawValue.type === "object" && rawValue.value && !isObjectAST(rawValue)) { const actualValue = rawValue.value; if (!(name in actualValue)) { if (options?.returnUndefinedForMissing) { accessedValue = void 0; break; } { const chain = [ ...options?.parentPath || [], name ]; const msg = `Field "${name}" not found in object`; throw new FieldAccessError(msg, { baseValue: actualValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: name }, { sourceLocation: options?.sourceLocation, env: options?.env }); } } accessedValue = actualValue[name]; break; } if (isObjectAST(rawValue)) { if (!hasObjectField(rawValue, name)) { if (options?.returnUndefinedForMissing) { accessedValue = void 0; break; } { const chain = [ ...options?.parentPath || [], name ]; const msg = `Field "${name}" not found in object`; throw new FieldAccessError(msg, { baseValue: rawValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: name }, { sourceLocation: options?.sourceLocation, env: options?.env }); } } accessedValue = getObjectField(rawValue, name); break; } if (rawValue && typeof rawValue === "object" && rawValue.type === "array" && Array.isArray(rawValue.items)) { if (name === "length") { if (process.env.MLLD_DEBUG_FIX === "true") { console.error("[field-access] AST array length", { length: rawValue.items.length, itemsPreview: rawValue.items.slice(0, 2) }); } accessedValue = rawValue.items.length; break; } } if (process.env.MLLD_DEBUG === "true" && name === "try") { console.log("\u{1F50D} FIELD ACCESS DEBUG:", { fieldName: name, rawValueType: typeof rawValue, rawValueKeys: Object.keys(rawValue || {}), hasField: name in rawValue, fieldValue: rawValue?.[name] }); } if (!(name in rawValue)) { if (structuredCtx && typeof structuredCtx === "object" && name in structuredCtx && structuredCtx[name] !== void 0) { accessedValue = structuredCtx[name]; break; } if (options?.returnUndefinedForMissing) { accessedValue = void 0; break; } const chain = [ ...options?.parentPath || [], name ]; const availableKeys = rawValue && typeof rawValue === "object" ? Object.keys(rawValue) : []; throw new FieldAccessError(`Field "${name}" not found in object`, { baseValue: rawValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: name, accessPath: chain, availableKeys }, { sourceLocation: options?.sourceLocation, env: options?.env }); } accessedValue = rawValue[name]; break; } case "numericField": { const numKey = String(fieldValue); if (typeof rawValue !== "object" || rawValue === null) { const chain = [ ...options?.parentPath || [], numKey ]; throw new FieldAccessError(`Cannot access numeric field "${numKey}" on non-object value`, { baseValue: rawValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: numKey, accessPath: chain }); } if (isObjectAST(rawValue)) { if (!hasObjectField(rawValue, numKey)) { if (options?.returnUndefinedForMissing) { accessedValue = void 0; break; } const chain = [ ...options?.parentPath || [], numKey ]; throw new FieldAccessError(`Numeric field "${numKey}" not found in object`, { baseValue: rawValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: numKey, accessPath: chain }); } accessedValue = getObjectField(rawValue, numKey); break; } if (!(numKey in rawValue)) { if (options?.returnUndefinedForMissing) { accessedValue = void 0; break; } const chain = [ ...options?.parentPath || [], numKey ]; throw new FieldAccessError(`Numeric field "${numKey}" not found in object`, { baseValue: rawValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: numKey, accessPath: chain }); } accessedValue = rawValue[numKey]; break; } case "arrayIndex": { const index = Number(fieldValue); if (rawValue && typeof rawValue === "object" && rawValue.type === "array" && rawValue.items) { const items = rawValue.items; if (index < 0 || index >= items.length) { const chain = [ ...options?.parentPath || [], String(index) ]; throw new FieldAccessError(`Array index ${index} out of bounds (array length: ${items.length})`, { baseValue: rawValue, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: index, accessPath: chain, availableKeys: Array.from({ length: items.length }, (_, i) => String(i)) }); } accessedValue = items[index]; break; } const arrayData = isStructuredValue(rawValue) ? asData(rawValue) : rawValue; if (!Array.isArray(arrayData)) { const numKey = String(fieldValue); if (typeof arrayData === "object" && arrayData !== null) { if (isObjectAST(arrayData)) { if (hasObjectField(arrayData, numKey)) { accessedValue = getObjectField(arrayData, numKey); break; } } else if (numKey in arrayData) { accessedValue = arrayData[numKey]; break; } } { const chain = [ ...options?.parentPath || [], String(index) ]; const msg = `Cannot access index ${index} on non-array value (${typeof arrayData})`; throw new FieldAccessError(msg, { baseValue: arrayData, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: index }); } } if (index < 0 || index >= arrayData.length) { const chain = [ ...options?.parentPath || [], String(index) ]; const msg = `Array index ${index} out of bounds (length: ${arrayData.length})`; throw new FieldAccessError(msg, { baseValue: arrayData, fieldAccessChain: [], failedAtIndex: Math.max(0, chain.length - 1), failedKey: index }); } accessedValue = arrayData[index]; break; } case "arraySlice": case "arrayFilter": { const arrayOps = new ArrayOperationsHandler(); const env = options?.env; if (!env && field.type === "arrayFilter") { throw new FieldAccessError("Environment required for array filter operations", { baseValue: value, fieldAccessChain: options?.parentPath || [], failedAtIndex: options?.parentPath ? options.parentPath.length : 0, failedKey: "arrayFilter" }); } accessedValue = await arrayOps.handle(value, field, env); break; } case "variableIndex": { const env = options?.env; if (!env) { throw new FieldAccessError("Environment required for variable index resolution", { baseValue: value, fieldAccessChain: options?.parentPath || [], failedAtIndex: options?.parentPath ? options.parentPath.length : 0, failedKey: field.value }); } const { evaluateDataValue } = await import('./data-value-evaluator-6G4NQGOF.mjs'); const indexNode = typeof field.value === "object" ? field.value : { type: "VariableReference", valueType: "varIdentifier", identifier: String(field.value) }; const indexValue = await evaluateDataValue(indexNode, env); const resolvedField = { type: "bracketAccess", value: indexValue }; return accessField(value, resolvedField, options); } default: throw new FieldAccessError(`Unknown field access type: ${field.type}`, { baseValue: value, fieldAccessChain: options?.parentPath || [], failedAtIndex: options?.parentPath ? options.parentPath.length : 0, failedKey: String(field.type || "unknown") }); } const provenanceSource = parentVariable ?? structuredWrapper ?? value; if (provenanceSource) { inheritExpressionProvenance(accessedValue, provenanceSource); } if (options?.preserveContext) { const accessPath = [ ...options.parentPath || [], fieldName ]; const resultIsVariable = isVariable(accessedValue); return { value: accessedValue, parentVariable, accessPath, isVariable: resultIsVariable }; } return accessedValue; } __name(accessField, "accessField"); async function accessFields(value, fields, options) { let current = value; let path = options?.parentPath || []; let parentVar = isVariable(value) ? value : void 0; const shouldPreserveContext = options?.preserveContext !== false; for (const field of fields) { const result = await accessField(current, field, { preserveContext: shouldPreserveContext, parentPath: path, returnUndefinedForMissing: options?.returnUndefinedForMissing, env: options?.env, sourceLocation: options?.sourceLocation }); if (shouldPreserveContext) { current = result.value; path = result.accessPath; if (result.isVariable && isVariable(result.value)) { parentVar = result.value; } } else { current = result; } } if (shouldPreserveContext) { return { value: current, parentVariable: parentVar, accessPath: path, isVariable: isVariable(current) }; } return current; } __name(accessFields, "accessFields"); function createFieldAccessVariable(result, source) { if (result.isVariable && isVariable(result.value)) { return result.value; } const internalSource = source ?? result.parentVariable?.source; return { type: "computed", name: result.accessPath.join("."), value: result.value, internal: { source: internalSource, parentVariable: result.parentVariable, accessPath: result.accessPath, fieldAccess: true } }; } __name(createFieldAccessVariable, "createFieldAccessVariable"); export { accessField, accessFields, createFieldAccessVariable }; //# sourceMappingURL=chunk-3VW6WZGZ.mjs.map //# sourceMappingURL=chunk-3VW6WZGZ.mjs.map