diff --git a/shortcutgen.go b/shortcutgen.go index 10814686..80395166 100644 --- a/shortcutgen.go +++ b/shortcutgen.go @@ -383,6 +383,16 @@ func variableValue(variable varValue) map[string]any { if variable.valueType == Variable && variableReference.valueType != "" { refValueType = variableReference.valueType } + // A reference to an action's output has value type Action, not Dict, so + // resolve what the action actually returns. Without this a key access on + // a dictionary-returning action (e.g. getDictionary()) compiles to a + // property lookup, which Shortcuts resolves to an empty value at + // runtime. makeAggrandizement() already does this for inline references. + if refValueType == Action { + if variableAction, ok := variableReference.value.(action); ok && variableAction.def != nil { + refValueType = variableAction.def.outputType + } + } if refValueType == Dict { aggrandizements = append(aggrandizements, map[string]any{ "Type": "WFDictionaryValueVariableAggrandizement", diff --git a/tests/dictionary-action-output.cherri b/tests/dictionary-action-output.cherri new file mode 100644 index 00000000..0530c232 --- /dev/null +++ b/tests/dictionary-action-output.cherri @@ -0,0 +1,19 @@ +/* +Subscripting a dictionary that is the output of an action (e.g. getDictionary()) +must compile to a dictionary-value aggrandizement (Type: WFDictionaryValueVariableAggrandizement), +the same as subscripting a literal dictionary — not a property aggrandizement, +which resolves to nothing at runtime. +*/ + +#include 'actions/scripting' + +@response = "placeholder" +const responseDict = getDictionary(@response) + +// bare subscript on an action-output dictionary +@summary = responseDict['summary'] + +// subscript inside string interpolation (was already correct) +const inline = "{responseDict['summary']}" + +alert("bare: {summary} inline: {inline}", "Dictionary action output")