mlld
Version:
mlld: llm scripting language
1,099 lines (1,090 loc) • 35.8 kB
JavaScript
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 \`| \` 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