dart_helper_utils
re-export된 convert_object, collection, intl API를 포함한 Dart 유틸리티 및 확장 기능.
Dart Helper 패키지는 Dart 유틸리티의 모음, 동적 객체를 다양한 유형으로 변환하는 도구, 그리고 핵심 Dart 클래스를 확장하는 확장 기능을 제공합니다.
^1.19.1^1.1.0^2.0.8>=0.20.0 <1.0.0^1.17.0^2.0.0^1.0.0^6.0.0^1.29.0아래는 영문 원문 스냅샷입니다. 최신 내용은 GitHub에서 확인하세요.
A batteries-included utility package for Dart. One import gives you type-safe
conversions, ergonomic extensions, a serious debouncer, stream superpowers,
and the APIs you already know from convert_object, collection, and intl.
This repository ships a package-specific agent plugin for Claude Code and OpenAI Codex (this is tooling for coding agents, not a runtime feature of the Dart package). It teaches the agent the exact dart_helper_utils APIs - utility member names and semantics, the Debouncer/throttle/stream lifecycles, the v5-to-v6 breaking migration, and version-aware upgrades.
Install in Claude Code:
/plugin marketplace add omar-hanafy/dart_helper_utils
/plugin install dart-helper-utils@dart-helper-utils-tools
Install in OpenAI Codex (CLI; the IDE extension does not support
plugins - use its $skill-installer there instead):
codex plugin marketplace add omar-hanafy/dart_helper_utils
codex plugin add dart-helper-utils@dart-helper-utils-tools
Start a new agent session after installing so the skills load. Then try
prompts like "debounce this search field with dart_helper_utils and clean it
up on dispose" or "migrate this project from dart_helper_utils 5.x to 6.x",
or invoke a skill explicitly in Claude Code, e.g.
/dart-helper-utils:use-dart-helper-utils.
The plugin is installed from this Git repository (not from the pub.dev archive), contains markdown skills only - no hooks, no MCP servers, no telemetry - and its version tracks the package version. Details, the full capability list, updating, and uninstalling are in tooling/ai/dart-helper-utils/README.md.
dependencies:
dart_helper_utils: ^<latest_version>
import 'package:dart_helper_utils/dart_helper_utils.dart';
// Type-safe map extraction, collection helpers, and intl formatting
// all from a single import.
final map = {'name': 'Omar', 'count': '42', 'items': [1, 2, 3]};
print(map.getString('name')); // Omar
print(map.getInt('count')); // 42
print(map.getList<int>('items').firstOrNull); // 1
print(1234567.89.formatAsReadableNumber()); // 1,234,567.89
print('invoice.pdf'.isPDF); // true
Everything below is available from the single package import:
convert_objectpackage:collection (firstOrNull, groupBy, mapIndexed, ...)intl essentials (DateFormat, NumberFormat, Bidi, Intl)No import soup, no glue code.
Leading or trailing execution, a maxWait ceiling, pause and resume,
a state stream for observability, and optional execution history for debugging.
final debouncer = Debouncer(
delay: const Duration(milliseconds: 300),
maxWait: const Duration(seconds: 2),
);
void onSearchChanged(String q) =>
debouncer.run(() => runSearch(q));
// Screen pauses:
debouncer.pause();
// Resumes later:
debouncer.resume();
// Optional observability.
debouncer.stateStream.listen(print);
// Hold events until you are ready for them.
final paused = sensorStream.asPausable();
// Cap a noisy source at 5 events per second.
final safe = eventStream.rateLimit(5, const Duration(seconds: 1));
// Group events into fixed-size or time-based batches.
final batched = logStream.bufferCount(100);
final windowed = logStream.window(const Duration(seconds: 1));
// Behaviour-subject semantics: late subscribers see the last value.
final replay = priceStream.withLatestValue();
// Run at most 4 uploads at once, results in completion order.
final urls = await files.mapConcurrent(upload, parallelism: 4);
// Soft timeout: the original task keeps running in the background.
try {
final report = await TimeUtils.runWithTimeout(
task: fetchReport,
timeout: const Duration(seconds: 5),
);
} on TimeoutException {
showSlowNetworkBanner();
}
final nested = {
'user': {'name': 'Omar', 'roles': ['admin', 'editor']},
};
final flat = nested.flatMap();
// {user.name: Omar, user.roles.0: admin, user.roles.1: editor}
print(flat.unflatten()); // round-trips back to nested
final payload = {'users': [{'name': 'A'}, {'name': 'B'}]};
print(payload.getPath('users[1].name')); // B
Everyday sugar that you would otherwise write by hand: the full
stringo string toolkit (case conversion,
slugify, truncate, mask, whitespace normalization) re-exported here,
format validators (isValidEmail, isUuid), parseDuration, MIME checks
(isPDF, isImage, isFont), date helpers (isBetween, addBusinessDays,
daysInMonth), Intl formatters (formatAsCurrency, formatAsCompact,
toOrdinal, pluralize), URI builders (rebuild, mergeQueryParameters,
appendPathSegment), and Iterable<num> statistics (mean, median,
percentile, standardDeviation).
Browse the full API: https://pub.dev/documentation/dart_helper_utils/latest/
stringo, which is re-exported here.
Call sites are unchanged; only explicit extension type names differ (see
the CHANGELOG). Depend on stringo directly if you want the
string helpers without the rest of this package.convert_object, which is re-exported here.package:collection, which is now also re-exported.safelyEncodedJson are now toJsonString(...) or
encodeWithIndent from convert_object.Full guide: https://github.com/omar-hanafy/dart_helper_utils/blob/main/migration_guides.md