magic_map 2.0.0
magic_map: ^2.0.0 copied to clipboard
A Dart package that allows JavaScript-like dot-access to deeply nested Maps and Lists.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.
2.0.0 - 2026-09-06 #
Internal rewrite around one invariant: the underlying data is always plain
Map<String, dynamic> / List<dynamic> containers, and every view writes
through to it. Most of the previously documented behaviour now actually works.
Fixed #
getPath()resolves list indices (user.hobbies.0); it returned the default before.set()through a list index (user.hobbies.0) no longer throws or replaces the list with an empty map.set()with a map or list value no longer stores wrapper objects in the data, which madetoJsonString()andrawunusable afterwards.- Direct list mutation through dot access (
d.user.hobbies[1] = 'x',.add(...)) now writes through instead of modifying a throwaway copy. - Writes into maps built from narrowly typed literals (for example
{'name': 'Alice'}inferred asMap<String, String>) no longer throw type errors: input is deep-copied intoMap<String, dynamic>. - Non-string keys in the input are converted with
toString()instead of failing lazily on access. getPath()no longer swallows every error with a barecatch.- The
replacerparameter oftoJsonString()now behaves like the JavaScriptJSON.stringifyreplacer it was documented as; the previous parameter wasJsonEncoder'stoEncodableand never saw string values.
Added #
MagicList: a realListview returned for nested lists, with write-through[]=,add,insert,removeAt,sort, and so on.- Nested views are
MagicMapinstances, sogetPath,set,getWithGlob,setImmutable,toJsonString,rawand friends work at any depth. - Bracket index syntax in paths:
users[0].name,items[*].id. - Backslash escaping of
.and[inside keys. hasPath(),removePath(),clone(),toJson().- Glob patterns support
*and?inside a segment and**for any depth. MagicList.fromJsonString().toJsonString(toEncodable: ...)for values JSON cannot encode.MagicMap.omitsentinel for dropping entries from a replacer.set()creates intermediate lists for integer segments and appends when the index equals the list length.- Cyclic input is rejected with
MagicMapExceptioninstead of hanging. ==andhashCodecompare the underlying collection, so two views over the same data are equal.- A test suite (
flutter test) covering the public API.
Changed (breaking) #
MagicMap(...)deep-copies its argument; it used to hold a reference, so mutations no longer show up in the original map. It requires aMap(orMagicMap, ornull) and throwsMagicMapExceptionfor other input.toJsonStringnow takes named parameters:toJsonString(indent: 2, replacer: ..., toEncodable: ...).rawis typedMap<String, dynamic>and returns the live data.set()throwsMagicMapExceptioninstead of silently replacing a scalar or a list with an empty map when a path descends through it, and for list indices that are out of range.toString()prints the plain map ({a: 1}) rather thanMagicMap({a: 1}).- Assigning a
MagicMap/MagicListor a raw collection stores a deep copy rather than an alias. MagicMap.fromJsonStringthrowsMagicMapExceptionfor invalid JSON or a non-object root.- Removed the unused
globdependency.
1.0.4 - 2025-04-19 #
Added #
- Introduced
MagicMapclass for flexible, dynamic map access. - Support for dot-separated path-based value retrieval using
getPath(). - Support for dot-separated dynamic nested value assignment using
set(). - Bash-style glob pattern matching support with
getWithGlob(). - Immutable data updates using
setImmutable(). - JSON serialization via
toJsonString()andfromJsonString(). - Dynamic property access using
noSuchMethodon_MagicMapImpl. - Custom
MagicMapExceptionclass with detailed error messages.
Internal #
- Wrapped and unwrapped data to maintain consistent structure using
_wrap()and_unwrap()utilities. - Recursive collection of matched entries for glob matching.