qsu 1.5.0
qsu: ^1.5.0 copied to clipboard
qsu is a utility library that contains useful and frequently used functions. Start with your preferred language and the modern development environment.
Changelog (Dart) #
1.5.0 - 2026-08-07 #
-
unescapeHtml: Added. Turns the five entitiesescapeHtmlproduces back into their characters. The string is walked once rather than replaced five times in a row, so&lt;comes back as the literal text<instead of being unescaped twice, and only those five entities are recognised, so and'are left as they are -
escapeHtml: Added. Escapes&,<,>,"and'so a value can be dropped into a page as text rather than read as markup.'is written as'rather than', which HTML 4 never defined. It lives in thewebcategory, next togetSlug, and leavesescapeRegExpas the pattern-oriented one -
objClone: Added. Copies an object, deeply by default and top level only withdeep: false. AMap,ListandSetare rebuilt with their contents copied, while aDateTime(immutable) or a class instance is handed back as it is. A structure that points back at itself is rebuilt with the same shape rather than recursing until the stack runs out -
objMerge: Added. Merges any number of objects into one new object, going down through nested maps, with the later source winning. Two maps under the same key are merged into a new map, so neither source is shared with the result or modified. Lists are replaced whole rather than merged index by index as Lodash does, andnullis returned when an entry is not a map -
objGet: Added. Reads a nested value out of an object by dot and/or bracket path (a.b.c,list[0],list[1].d), returning thefallbackwhen the path is not there. A bracket may carry a quoted key, so["a.b"]reads one key rather than walking two levels, and a storednullcounts as a value rather than a missing path -
objPick: Added. Returns a new object containing only the listed keys, accepting a single key or a list of keys. Only the top level is inspected, and a key the map does not have is skipped rather than carried over asnull -
pad: Added. Pads a string until it reaches the given length, with onepositionnamed parameter (start,endorboth) covering what Lodash splits acrosspad,padStartandpadEnd.bothis the default and gives the extra character to the end, a multi-charactercharis repeated and truncated, and the length is counted in code points so an emoji counts as one in every language -
strToConstantCase: Added. Converts a string toCONSTANT_CASE, uppercasing every word and joining them with an underscore. It splits withwords, soXMLHttpRequestbecomesXML_HTTP_REQUEST. Dart applies the simple Unicode case mapping where JavaScript and Python apply the full one, sostraßebecomesSTRAßEhere andSTRASSEthere, which the documentation states rather than papering over -
strToPascalCase: Added. Converts a string toPascalCase, giving every word an uppercase first letter and a lowercase rest. It splits withwords, soXMLHttpRequestbecomesXmlHttpRequest.capitalizeEachWordsstays the one that keeps the original separators -
strToKebabCase: Added. Converts a string tokebab-case, lowercasing every word and joining them with a hyphen. It splits withwords, soXMLHttpRequestbecomesxml-http-request.getSlugstays the URL-oriented one -
strToSnakeCase: Added. Converts a string tosnake_case, lowercasing every word and joining them with an underscore. It splits withwords, soXMLHttpRequestbecomesxml_http_requestandabc12defbecomesabc_12_def -
strToCamelCase: Added. Converts a string tocamelCase, lowercasing the first word and giving every word after it an uppercase first letter. It splits withwords, so an acronym stays whole (XMLHttpRequestbecomesxmlHttpRequest) and a run of digits is its own word (abc12defbecomesabc12Def) -
min: Added. Returns the smallest of the given numbers, taking a single array exactly likesum.NaNis skipped, because it loses every comparison and would otherwise win by being seen first, and an empty list returnsnull. It shadowsminfromdart:math, so a file that needs both has to import one of them with a prefix -
max: Added. Returns the largest of the given numbers, taking a single array exactly likesum.NaNis skipped, because it loses every comparison and would otherwise win by being seen first, and an empty list returnsnull. It shadowsmaxfromdart:math, so a file that needs both has to import one of them with a prefix -
floor: Added. Rounds a number down, to the given number of decimal places, a negative precision rounding down to tens, hundreds and so on. Rounding goes toward negative infinity, sofloor(-4.006)is-5. The value is shifted through its shortest string representation, sofloor(1.1, 1)is1.1, and a whole result is handed back as anint -
ceil: Added. Rounds a number up, to the given number of decimal places, a negative precision rounding up to tens, hundreds and so on. Rounding goes toward positive infinity, soceil(-4.006)is-4. The value is shifted through its shortest string representation, soceil(1.1, 1)is1.1and not1.2, and a whole result is handed back as anint -
round: Added. Rounds a number to the given number of decimal places, a negative precision rounding to tens, hundreds and so on. Ties go away from zero, which is whatnum.roundalready does but not what JavaScript'sMath.roundor Lodash do. The value is shifted through its shortest string representation rather than multiplied by a power of ten, soround(1.005, 2)is1.01and not1, and a whole result is handed back as anintsoround(1234, -2)is1200rather than1200.0 -
clamp: Added. Restricts a number to an inclusive range, returningminbelow it andmaxabove it. The upper bound is applied first, sominwins when the two are passed the wrong way round, where the built-innum.clampthrows on an inverted range instead -
retry: Added. Runs the given function again on failure until it succeeds or the attempts run out, rethrowing the last error with its original stack trace if they all fail.timescounts total attempts (default3),delaywaits between them andbackoffmultiplies that wait after each failure -
throttle: Added. Limits how often a function may run to at most once perwaitwindow, the counterpart ofdebounce.leadingandtrailing(bothtrueby default) choose which edge of the window runs -
objInvert: Added. Returns a new object with the keys and values swapped. Values are converted to text because keys are always strings, a wholedoublelosing its fractional part so the result matches the JavaScript implementation, and the later entry wins when two share a value -
objMapKeys: Added. Returns a new object whose keys are the values returned by the callback, with the values carried over untouched. The callback receives(value, key), and the later key wins when two map onto the same name -
objPickBy: Added. Returns a new object containing only the entries for which the callback returnstrue. The callback receives(value, key), and only the top level is inspected -
uncapitalizeFirst: Added. Converts the first letter of the entire string to lowercase, the inverse ofcapitalizeFirst. Only the first character is touched, soTESTbecomestEST -
escapeRegExp: Added. Escapes every regular expression metacharacter (^ $ . * + ? ( ) [ ] { } |and\) so a value can be matched literally.-and#are left alone: they are special only inside a character class. The private helper behindremoveSpecialCharandreplaceBetween, which does also escape-and/because its result lands inside a character class, is now named_escapeRegExpInClassto keep the two apart -
deburr: Added. Replaces accented Latin letters with their unaccented equivalents (déjà vubecomesdeja vu), spelling outÆ,ß,Þ,ŒandIJ, and dropping combining marks. Covers the Latin-1 Supplement and Latin Extended-A blocks -
words: Added. Splits a string into the words it is made of. Anything that is neither a letter nor a digit separates words, and camelCase boundaries, runs of capitals (XMLHttpRequestisXML,Http,Request) and runs of digits are split as well -
arrIntersection: Added. Returns the values that are present in every one of the given arrays. The result is unique and keeps the order of the first array -
arrDifference: Added. Returns the values of the first array that are not contained in any of the other arrays. Values are compared by value rather than by identity, so nested lists and maps are matched as well -
arrCompact: Added. Returns a new array with every falsy value removed (null,false,0,'',NaN). An empty list and an empty map are kept, matching the JavaScript implementation
1.4.0 (2026-08-) #
- BREAKING CHANGES:
isValidFileNamenow rejects an empty name and any name carrying a control character (U+0000-U+001ForU+007F).NULis the one that matters: it terminates the path in the system call underneath every filesystem, so a name carrying one was reported as valid and then silently truncated on the way to disk - BREAKING CHANGES:
isValidFileNamenow rejects a name ending in a dot or a space on the Windows path. Windows strips it instead of reporting an error, soreport.quietly becomesreportand overwrites it. Unix keeps them, so they stay valid withunixType - BREAKING CHANGES:
isValidFileNamenow measures its 255 limit in UTF-8 bytes rather than characters, which is what ext4, APFS and NTFS enforce.'가' * 100is 100 characters but 300 bytes and cannot be created - BREAKING CHANGES:
headFileandtailFilenow replace malformed UTF-8 withU+FFFDinstead of throwing aFormatException, matching the JavaScript and Python implementations. One bad byte in a log file no longer stops it from being read - BREAKING CHANGES:
headFileandtailFilenow keep a leading byte order mark. Dart's UTF-8 decoder drops it, which silently changed text that JavaScript and Python both return whole - BREAKING CHANGES:
moveFilenow moves a directory as well as a file, with everything inside it.File(path).renamereports an error on a directory, so the entity is opened as what it actually is - BREAKING CHANGES:
getFileInfoandgetFileSizenow throw theFileSystemExceptionas it is instead of wrapping it inException(err.toString()), which droppedosErrorandpathand left a caller unable to tell a missing file from a permission error.headFileandtailFileno longer wrap theirs either - BREAKING CHANGES:
toValidFilePathnow resolves a leading..against the root, so'../../etc/passwd'returns/etc/passwdinstead of/../../etc/passwd - BREAKING CHANGES:
getCopyFileNamenow takes anIterable<String>instead of aList<String>, and reads aSetas it is. Naming n files into one directory calls this n times, and rebuilding the set on every call made that loop quadratic — 16,000 names took 21 seconds through aListand 0.01 seconds through a reusedSet tailFile: Read backwards from the end of the file a chunk at a time instead of streaming it from the start. On a 108 MB log the last line took 0.73 seconds and now takes 0.002headFile: Read forwards a chunk at a time and stop as soon as enough lines are in hand, rather than running the whole file through a stream transformermoveFile: Fall back to a copy and a remove when the operating system reports a cross-device error.renamecannot cross a filesystem boundary, so moving out of the temporary directory, into a mounted volume or onto another drive failed outrightisFileExists: Answer with a singleFileSystemEntity.typecall rather than askingFile.existsand thenDirectory.exists, which cost two system calls for every directorycreateDirectory: Drop theexistscall that ran before everycreate.createis already a no-op for an existing directory and already reports a file in the waydeleteAllFileFromDirectory: Delete up to 32 entries at a time instead of awaiting each one in turnhasBadWords: Catch a banned word broken up by digits (ad1min,사1과,사123과), a common way of hiding a word in Korean. A digit that opens or closes a word is still read as a letter, so a number in front of a word (2시 발표) is not read away
1.3.0 - 2026-07-28 #
- BREAKING CHANGES:
numberHashnow returns the low 32 bits as a signed value, so it can be negative as documented and matches the JavaScript and Python implementations (numberHash('k10000')is-1184917978, not3110049318) - BREAKING CHANGES: The
base64urlhash encoding is now unpadded, andbinarynow returns the raw digest as latin-1 characters instead of a string of 0s and 1s, both matching the JavaScript and Python implementations - BREAKING CHANGES:
truncateExpectno longer inserts the literal textnullinto the result whenendStringCharis omitted (truncateExpect('Hi. Bye.', 3)returned'Hinull') - BREAKING CHANGES:
numUniquenow returns a millisecond timestamp combined with a per-millisecond sequence (16 digits) instead of a timestamp combined with a random number (18 digits). Repeated calls within a process are now always unique and strictly increasing - BREAKING CHANGES:
isValidDatenow rejects years0100-1599, which the JavaScript and Python implementations also reject. Two-digit years16-99and four-digit years1600-9999remain valid - BREAKING CHANGES:
dayDiffnow returns the absolute difference, so swapping the arguments no longer flips the sign - BREAKING CHANGES:
arrMoveno longer modifies the list it is given; it returns a new one - BREAKING CHANGES:
strRandomreturns an empty string andfuncTimesreturns an empty list for a non-positive count, instead of throwing, matching the JavaScript and Python implementations - BREAKING CHANGES:
objTo1dnow rejects anullseparator, which used to be interpolated into every nested key as the literal textnull - BREAKING CHANGES:
isMatchPathnamenow throws for an empty matcher list instead of quietly returningfalse strUnique: Deduplicate by code point, so characters outside the BMP (emoji) are no longer broken apartcapitalizeFirst,capitalizeEachWords: Return an empty string instead of throwing aRangeErroron empty inputreplaceBetween: Escape the whole delimiter, so multi-character delimiters produce a valid pattern;replaceWithnow defaults to an empty string as documentedremoveSpecialChar,removeLocalePrefix: Escape the caller's characters before building the pattern, so values like']'orzh.CNare matched literally instead of being interpreted as a patternisMatchPathname,removeLocalePrefix: Accept any iterable, not onlyList<String>. AList<dynamic>(what JSON decoding produces) used to be stringified whole and never matchedmd5Hash,sha1Hash,sha256Hash,sha512Hash: Fall back to hex whenencodingis explicitlynullinstead of throwingisBotAgent: Remove 84 of the 172 alternatives that were substrings of another one (botalready matchesnaverbot,bingbot, ...) and could never change the outcome — verified identical on 200,000 inputs. Roughly halves the matching costisBotAgent,isMobile,getSlug,removeSpecialChar,replaceBetween,trim,capitalizeEverySentence,getParsedInfoFromAddress: Compile regular expressions once instead of on every call —getSlugwas building three per characterobjectId,strShuffle,strRandom,numPick: Reuse a singleRandominstance instead of constructing one per draw- BREAKING CHANGES:
getParentFilePathnow handles relative paths (relative/path->/relative), UNC paths, and trailing separators correctly - BREAKING CHANGES:
toValidFilePathnow resolves.and..segments and preserves the UNC\\prefix - BREAKING CHANGES:
getFilePathLevelno longer counts a trailing separator as an extra level (/home/user/now returns the same level as/home/user) - BREAKING CHANGES:
getCopyFileNamenow preserves the original file extension casing (e.g.Report.PDFcopies toReport (1).PDFinstead ofReport (1).pdf) - BREAKING CHANGES:
isValidFileNamenow validates the whole name including its extension (sohello.:txtis invalid) and rejects Windows device names (CON,NUL,COM1-COM9,LPT1-LPT9, etc.) - BREAKING CHANGES:
createFileWithDummynow throws for a negative size instead of returningfalse - BREAKING CHANGES:
createDirectory,moveFile, andcreateFilenow propagate filesystem errors instead of silently ignoring them duration: AdddurationmethodarrPick: AddarrPickmethodgetParsedInfoFromAddress: AddgetParsedInfoFromAddressmethodgetSlug: AddgetSlugmethodhasBadWords: AddhasBadWordsmethodcapitalizeEachWords: If thenaturaloption is not enabled, characters that are already uppercase will not be converted to lowercase
1.2.0 - 2026-04-14 #
- BREAKING CHANGES:
strToNumberHashhas renamed tonumberHash md5Hash,sha1Hash,sha256Hash: Add an encoding option for hash functions- Add
sortNumericmethod - Add
sha512Hashmethod
1.1.12 - 2026-03-31 #
- BREAKING CHANGES:
numRandomhas renamed tonumPick getFileName: Fix incorrect directory name with include dot character- Add
getCopyFileNamemethod - Add
divmethod - Add
mulmethod - Add
submethod - Add
summethod - Add
createDateListFromRangemethod - Add
dateToYYYYMMDDmethod - Add
dayDiffmethod - Add
isValidDatemethod - Add
todaymethod
1.1.11 - 2025-12-10 #
- Add
splitmethod - Add
isMobilemethod - Add
objDeleteKeyByValuemethod
1.1.10 - 2025-11-25 #
- Fix package dependencies
1.1.9 - 2025-11-25 #
- Add
getFileSizemethod - Add
normalizeFilemethod - Add
headFilemethod - Add
tailFilemethod - Add
removeLocalePrefixmethod - Add
isMatchPathnamemethod - Add
isBotAgentmethod - Add
ceilargument to thefileSizeFormatmethod
1.1.8 - 2025-11-13 #
- Add
createDirectorymethod - Add
getParentFilePathmethod - Add
deleteFilemethod - Add
createFilemethod - Add
deleteAllFileFromDirectorymethod - Add
moveFilemethod - Add
createFileWithDummymethod - Add
getFileInfomethod - Add
joinFilePathmethod - Add
getFileHashFromPathmethod
1.1.7 - 2025-11-03 #
- BREAKING CHANGES:
getFileSizehas renamed tofileSizeFormat - BREAKING CHANGES:
safeJSONParse: 'fallback' parameters has changed to named parameter - BREAKING CHANGES:
objToArray: 'recursive' parameters has changed to named parameter - Add
getFileNameandgetFileExtensionmethods - Add
isFileExistsmethod - Add
isValidFileNamemethod - Add
toPosixFilePathmethod - Add
getFilePathLevelmethod - Add
toValidFilePathmethod
1.1.6 - 2025-10-15 #
isEmail: addonlyLowerCaseparameter- Add
consolemethod - Add
getStrBytesmethod
1.1.5 - 2025-03-06 #
- Update
README.md
1.1.4 - 2025-02-28 #
- Update documentation
1.1.3 - 2025-02-14 #
- Fix
isUrlparameters
1.1.2 - 2025-02-14 #
- Add
debouncemethod - Add
isUrlmethod - Add
isObjectmethod - Add
isEqualmethod - Add
isEqualStrictmethod - Add
isEmptymethod
1.1.1 - 2024-11-26 #
- Fix
objTo1dparameters
1.1.0 - 2024-11-26 #
- Add
arrCountmethod - Add
betweenmethod - Add
arrGroupByMaxCountmethod - Add
numPickmethod - Add
lenmethod - Add
isTrueMinimumNumberOfTimesmethod - Add
objToQueryStringmethod - Add
objToArraymethod - Add
objTo1dmethod
1.0.0 - 2024-10-19 #
- Add
fileSizemethod - Add
fileExtmethod - Add
safeParseIntmethod - Add
isEmailmethod - Add
fileNamemethod - Add
safeJSONParsemethod - Add
md5Hashmethod - Add
sha1Hashmethod - Add
sha256Hashmethod - Add
encodeBase64method - Add
decodeBase64method - Add
strToNumberHashmethod - Add
objectIdmethod
0.0.4 - 2024-10-02 #
- Add
averagemethod - Add
arrMovemethod - Add
arrTo1dArraymethod - Add
arrRepeatmethod
0.0.3 - 2024-10-02 #
- Add
strShufflemethod - Add
strRandommethod - Add
truncateExpectmethod - Add
strUniquemethod - Add
strToAsciimethod - Add
urlJoinmethod - Add
arrWithDefaultmethod - Add
arrWithNumbermethod - Add
funcTimesmethod - Add
is2dArraymethod - Add
arrUniquemethod
0.0.2 - 2024-09-10 #
- Add
trimmethod - Add
replaceBetweenmethod - Add
removeNewLinemethod - Add
capitalizeEverySentencemethod - Add
containsmethod - Add
capitalizeEachWordsmethod - Add
strCountmethod - Add
sleepmethod - Add
arrShufflemethod - Add
removeSpecialCharmethod
0.0.1 - 2024-09-02 - Not for Production #
- Initial release