magic_map 2.1.3
magic_map: ^2.1.3 copied to clipboard
Path-based, typed access to nested Dart maps and lists - safe deep reads, deep writes, glob queries, immutable updates and JSON helpers, plus optional dot access.
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.1.3 - 2026-09-12 #
Changed #
- README: added an Author section with GitHub and LinkedIn links. Docs only, no code changes.
2.1.2 - 2026-09-12 #
Changed #
- README: added a table of contents, and retitled every method subsection by bare method name with the signature in a code block beneath, so in-page links are short and predictable on GitHub and pub.flutter-io.cn. Typed access and JSON are split into per-method subsections. Docs only, no code changes.
2.1.1 - 2026-09-12 #
Changed #
- README: new "Plain maps and lists" subsection explaining
getAs<Map<String, dynamic>>(returns the live underlying map), why a narrower value type such asMap<String, int>needsgetMapOf, and whygetAs<List>returns theMagicListview. Docs only, no code changes.
2.1.0 - 2026-09-12 #
Added #
- Typed accessors on
MagicMapandMagicList, available on nested views too:getAs<T>(),requireAs<T>(),getListOf<T>()andgetMapOf<V>(). The collection variants rebuild the list or map with the requested element type, sogetListOf<String>('tags')returns a realList<String>where a cast of the decodedList<dynamic>would throw.intwidens todouble, a wholedoublenarrows toint, ISO-8601 strings convert toDateTime, and aMagicMapview converts to its plainMap<String, dynamic>. Parsing numbers and booleans out of strings is opt-in viaparseStrings: true.requireAsthrows aMagicMapExceptionthat names the path and the actual type. MagicMap.view()andMagicList.view()wrap an existing collection without copying it, for large data you already own.topicsin the pubspec.
Changed #
- The package no longer depends on the Flutter SDK. It is a pure Dart
package usable from server, CLI and Flutter projects alike. Dev
dependencies moved from
flutter_test/flutter_lintstotest/lints. Nothing changes for existing Flutter users. - README leads with typed and path-based access and states what the package is for: data whose shape you do not control.
- Clarified in the 2.0.0 notes that
==andhashCodeuse the identity of the underlying collection, not its contents.
2.0.1 - 2026-09-06 #
Changed #
- README and package description now lead with the path API (
getPath,set,getWithGlob,setImmutable, JSON helpers) and present dynamic dot access as an optional extra with its trade-offs listed. No code changes.
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. ==andhashCodeare based on the identity of the underlying collection, so two views over the same data are equal and a view is safe to use as a map key.- 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.