qsu 1.8.0 copy "qsu: ^1.8.0" to clipboard
qsu: ^1.8.0 copied to clipboard

Everyday helpers you would otherwise write yourself: slugs, text case, date math, file size formatting, deep clone and merge, validation and hashing.

Changelog (Dart) #

vNext (2026--) #

1.8.0 - 2026-09-20 #

Changes #

  • The net category was added, with fetchData. It takes the same options the other packages take, names the method either with method or with one of the get, post, put, delete and patch flags, and decodes the response by what it says it is: a Map or List for JSON, a String for text, a List<int> for a file and the raw stream with toStream. A request that fails returns null, after onError is called. It needs a platform with networking of its own, so it throws an UnsupportedError on the web
  • Every function the other packages have is now in this one, apart from getMacAddress and getTimezone, whose pages say why
  • encrypt and decrypt were added. They take the same aes-<bits>-<mode> names the other packages take, with cbc, gcm, ctr, ofb and cfb, and produce the same iv:encrypted (or iv:authTag:encrypted) string byte for byte, so a value encrypted in one package reads back in either of the others. The test suite decrypts a ciphertext the JavaScript package produced, to keep it that way
  • pointycastle was added as a dependency. It is the only pure Dart library carrying all five of those modes, and it is what the ciphers run on
  • logBox, getGroupKeys and getFileHashFromStream were ported as well, which leaves encrypt, decrypt and fetchData as the only functions the other packages have and this one does not. logBox counts a wide character as two columns, so a row holding Korean or an emoji still lines up, and it falls back to 80 columns where there is no terminal to ask, including on the web. A value that is not a string is written with Dart's own toString() rather than with the inspector the JavaScript package uses
  • Eight functions the other packages already had were ported: sortByObjectKey, objToPrettyStr, objFindItemRecursiveByKey, objMergeNewKey, objUpdate, strBlindRandom, generateLicense and isFileHidden. None of them was missing for a reason; they had simply not been written yet. generateLicense returns the same text the JavaScript package returns, down to the byte
  • isFileHidden asks Windows for the hidden attribute directly rather than reading the output of attrib, so nothing is spawned for it. Everywhere else a name beginning with a dot is what makes a file hidden, which the path alone answers
  • The os category was added, with 29 of the 31 functions the other packages carry. It reports the machine the program runs on: the platform, the architecture, the processor and how busy it is, the memory and the disk, how long the machine and the process have been running, the host name, the user and the directories that belong to them. getMacAddress and getTimezone have no Dart port, for the reasons the documentation gives on their pages
  • The os functions ask the operating system directly rather than running commands, through sysctl on macOS and iOS, /proc on Linux and Android, and the system libraries on Windows. That is what lets them work on iOS, which forbids a program from starting another one. Only getHostname on macOS, getMachineId on macOS and getSid run a command, and each says so on its page
  • getLocalIp: The address is the one behind the default route, found the way the other two packages find it: a datagram socket is connected, which only asks the kernel which interface would carry the traffic, and closed again. dart:io has no datagram connect, so the socket calls are made directly. All three packages now name the same interface on a machine that has several
  • Android and iOS are not separate implementations: Android reads the same /proc files as Linux and iOS answers the same system calls as macOS. What differs is what their sandbox permits, which every os page sets out per platform
  • The package still compiles for the web, where the whole os category throws an UnsupportedError. dart:ffi cannot be imported there at all, so the platform layer behind these functions is chosen at compile time and the web gets one that answers nothing
  • package:ffi was added as a dependency. It is the Dart team's own package, and it is what the os functions allocate the buffers for a system call with

1.7.0 - 2026-09-12 #

Breaking changes #

  • sortNumeric: The order no longer depends on the package. A string is cut into runs of digits and runs of everything else, and the runs are compared in three passes over the whole string: the letters, then the accents on them, then upper against lower case. Whitespace sorts before punctuation, punctuation before numbers and numbers before letters, and a run of digits is compared by length before value, so a number too long for a number type still sorts correctly. The three packages now return the same order for the same input, which they never did. compareNatural from package:collection used to decide it, which compared code points, so Apple, Banana and Zebra all came before apple, and File-3.txt came before file-1.txt

Changes #

  • package:collection is no longer a dependency. compareNatural was the only thing this package used it for, and sortNumeric no longer calls it, so the package now rests on path, crypto and unorm_dart alone
  • durationParts: Added. Breaks a duration into its units and hands them back as a List<DurationPart> rather than a string, so a duration can be written in a language this package does not know. duration labels the units in English and builds the plural by adding an s, which is a rule only English follows: Polish has three plural forms and Arabic six. It takes the named parameters of duration that decide which units are used, and duration is now built on it, so the two cannot disagree
  • fileSizeParts: Added. Splits a file size in bytes into the scaled number and the unit it belongs to, returning a FileSizeParts rather than a string, so a size can be written in a language this package does not know. Hand value to a NumberFormat from intl and take the unit name from exponent; the value is deliberately left unrounded, so that formatter rounds it once instead of rounding an already rounded number
  • fileSizeFormat: Two named parameters were added. standard picks the divisor and the unit names: jedec (the default) divides by 1024 and writes KB as it always has, iec divides by 1024 and writes KiB, and si divides by 1000 and writes kB. unitDisplay writes the unit as an abbreviation (1.18 MB) or as a whole word (1.18 Megabytes), taking the singular when the rounded number is one. Leaving both out returns exactly the string it returned before, which the tests now pin
  • fileSizeFormat: A size past the largest unit no longer throws a RangeError by indexing past the end of the unit table. The exponent is held at the last unit instead, matching what the JavaScript and Python packages now do

1.6.0 - 2026-08-29 #

  • truncate, truncateExpect: The length is now counted in code points, as pad already did, so a character outside the Basic Multilingual Plane counts as one in every language. A Dart string is indexed in UTF-16 units, so truncate('a👋b', 2) used to cut between the two halves of the emoji and hand back a broken character, and truncateExpect stopped at a different sentence than Python did on the same text
  • truncateExpect: endStringChar now takes a List<String> as well as a single String, and defaults to the full stop as each script writes it (., 。, ., 。). Japanese and Chinese text used to come back untouched, because a text with no ASCII . in it split into one piece and the expected length was never reached. ! and ? are left out of the default on purpose, so that the same sentence is not split differently depending on the script it is written in. A longer ending character is matched before a shorter one, so . next to ... no longer cuts ... short

1.5.0 - 2026-08-07 #

  • unescapeHtml: Added. Turns the five entities escapeHtml produces back into their characters. The string is walked once rather than replaced five times in a row, so &amp;lt; comes back as the literal text &lt; instead of being unescaped twice, and only those five entities are recognised, so &nbsp; and &#x27; 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 &#39; rather than &apos;, which HTML 4 never defined. It lives in the web category, next to getSlug, and leaves escapeRegExp as the pattern-oriented one

  • objClone: Added. Copies an object, deeply by default and top level only with deep: false. A Map, List and Set are rebuilt with their contents copied, while a DateTime (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, and null is 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 the fallback when 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 stored null counts 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 as null

  • pad: Added. Pads a string until it reaches the given length, with one position named parameter (start, end or both) covering what Lodash splits across pad, padStart and padEnd. both is the default and gives the extra character to the end, a multi-character char is 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 to CONSTANT_CASE, uppercasing every word and joining them with an underscore. It splits with words, so XMLHttpRequest becomes XML_HTTP_REQUEST. Dart applies the simple Unicode case mapping where JavaScript and Python apply the full one, so straße becomes STRAßE here and STRASSE there, which the documentation states rather than papering over

  • strToPascalCase: Added. Converts a string to PascalCase, giving every word an uppercase first letter and a lowercase rest. It splits with words, so XMLHttpRequest becomes XmlHttpRequest. capitalizeEachWords stays the one that keeps the original separators

  • strToKebabCase: Added. Converts a string to kebab-case, lowercasing every word and joining them with a hyphen. It splits with words, so XMLHttpRequest becomes xml-http-request. getSlug stays the URL-oriented one

  • strToSnakeCase: Added. Converts a string to snake_case, lowercasing every word and joining them with an underscore. It splits with words, so XMLHttpRequest becomes xml_http_request and abc12def becomes abc_12_def

  • strToCamelCase: Added. Converts a string to camelCase, lowercasing the first word and giving every word after it an uppercase first letter. It splits with words, so an acronym stays whole (XMLHttpRequest becomes xmlHttpRequest) and a run of digits is its own word (abc12def becomes abc12Def)

  • min: Added. Returns the smallest of the given numbers, taking a single array exactly like sum. NaN is skipped, because it loses every comparison and would otherwise win by being seen first, and an empty list returns null. It shadows min from dart: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 like sum. NaN is skipped, because it loses every comparison and would otherwise win by being seen first, and an empty list returns null. It shadows max from dart: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, so floor(-4.006) is -5. The value is shifted through its shortest string representation, so floor(1.1, 1) is 1.1, and a whole result is handed back as an int

  • 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, so ceil(-4.006) is -4. The value is shifted through its shortest string representation, so ceil(1.1, 1) is 1.1 and not 1.2, and a whole result is handed back as an int

  • 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 what num.round already does but not what JavaScript's Math.round or Lodash do. The value is shifted through its shortest string representation rather than multiplied by a power of ten, so round(1.005, 2) is 1.01 and not 1, and a whole result is handed back as an int so round(1234, -2) is 1200 rather than 1200.0

  • clamp: Added. Restricts a number to an inclusive range, returning min below it and max above it. The upper bound is applied first, so min wins when the two are passed the wrong way round, where the built-in num.clamp throws 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. times counts total attempts (default 3), delay waits between them and backoff multiplies that wait after each failure

  • throttle: Added. Limits how often a function may run to at most once per wait window, the counterpart of debounce. leading and trailing (both true by 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 whole double losing 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 returns true. 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 of capitalizeFirst. Only the first character is touched, so TEST becomes tEST

  • 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 behind removeSpecialChar and replaceBetween, which does also escape - and / because its result lands inside a character class, is now named _escapeRegExpInClass to keep the two apart

  • deburr: Added. Replaces accented Latin letters with their unaccented equivalents (déjà vu becomes deja vu), spelling out Æ, ß, Þ, Œ and IJ, 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 (XMLHttpRequest is XML, 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: isValidFileName now rejects an empty name and any name carrying a control character (U+0000-U+001F or U+007F). NUL is 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: isValidFileName now rejects a name ending in a dot or a space on the Windows path. Windows strips it instead of reporting an error, so report. quietly becomes report and overwrites it. Unix keeps them, so they stay valid with unixType
  • BREAKING CHANGES: isValidFileName now measures its 255 limit in UTF-8 bytes rather than characters, which is what ext4, APFS and NTFS enforce. '가' * 100 is 100 characters but 300 bytes and cannot be created
  • BREAKING CHANGES: headFile and tailFile now replace malformed UTF-8 with U+FFFD instead of throwing a FormatException, matching the JavaScript and Python implementations. One bad byte in a log file no longer stops it from being read
  • BREAKING CHANGES: headFile and tailFile now 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: moveFile now moves a directory as well as a file, with everything inside it. File(path).rename reports an error on a directory, so the entity is opened as what it actually is
  • BREAKING CHANGES: getFileInfo and getFileSize now throw the FileSystemException as it is instead of wrapping it in Exception(err.toString()), which dropped osError and path and left a caller unable to tell a missing file from a permission error. headFile and tailFile no longer wrap theirs either
  • BREAKING CHANGES: toValidFilePath now resolves a leading .. against the root, so '../../etc/passwd' returns /etc/passwd instead of /../../etc/passwd
  • BREAKING CHANGES: getCopyFileName now takes an Iterable<String> instead of a List<String>, and reads a Set as 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 a List and 0.01 seconds through a reused Set
  • 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.002
  • headFile: 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 transformer
  • moveFile: Fall back to a copy and a remove when the operating system reports a cross-device error. rename cannot cross a filesystem boundary, so moving out of the temporary directory, into a mounted volume or onto another drive failed outright
  • isFileExists: Answer with a single FileSystemEntity.type call rather than asking File.exists and then Directory.exists, which cost two system calls for every directory
  • createDirectory: Drop the exists call that ran before every create. create is already a no-op for an existing directory and already reports a file in the way
  • deleteAllFileFromDirectory: Delete up to 32 entries at a time instead of awaiting each one in turn
  • hasBadWords: 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: numberHash now 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, not 3110049318)
  • BREAKING CHANGES: The base64url hash encoding is now unpadded, and binary now 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: truncateExpect no longer inserts the literal text null into the result when endStringChar is omitted (truncateExpect('Hi. Bye.', 3) returned 'Hinull')
  • BREAKING CHANGES: numUnique now 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: isValidDate now rejects years 0100-1599, which the JavaScript and Python implementations also reject. Two-digit years 16-99 and four-digit years 1600-9999 remain valid
  • BREAKING CHANGES: dayDiff now returns the absolute difference, so swapping the arguments no longer flips the sign
  • BREAKING CHANGES: arrMove no longer modifies the list it is given; it returns a new one
  • BREAKING CHANGES: strRandom returns an empty string and funcTimes returns an empty list for a non-positive count, instead of throwing, matching the JavaScript and Python implementations
  • BREAKING CHANGES: objTo1d now rejects a null separator, which used to be interpolated into every nested key as the literal text null
  • BREAKING CHANGES: isMatchPathname now throws for an empty matcher list instead of quietly returning false
  • strUnique: Deduplicate by code point, so characters outside the BMP (emoji) are no longer broken apart
  • capitalizeFirst, capitalizeEachWords: Return an empty string instead of throwing a RangeError on empty input
  • replaceBetween: Escape the whole delimiter, so multi-character delimiters produce a valid pattern; replaceWith now defaults to an empty string as documented
  • removeSpecialChar, removeLocalePrefix: Escape the caller's characters before building the pattern, so values like ']' or zh.CN are matched literally instead of being interpreted as a pattern
  • isMatchPathname, removeLocalePrefix: Accept any iterable, not only List<String>. A List<dynamic> (what JSON decoding produces) used to be stringified whole and never matched
  • md5Hash, sha1Hash, sha256Hash, sha512Hash: Fall back to hex when encoding is explicitly null instead of throwing
  • isBotAgent: Remove 84 of the 172 alternatives that were substrings of another one (bot already matches naverbot, bingbot, ...) and could never change the outcome — verified identical on 200,000 inputs. Roughly halves the matching cost
  • isBotAgent, isMobile, getSlug, removeSpecialChar, replaceBetween, trim, capitalizeEverySentence, getParsedInfoFromAddress: Compile regular expressions once instead of on every call — getSlug was building three per character
  • objectId, strShuffle, strRandom, numPick: Reuse a single Random instance instead of constructing one per draw
  • BREAKING CHANGES: getParentFilePath now handles relative paths (relative/path -> /relative), UNC paths, and trailing separators correctly
  • BREAKING CHANGES: toValidFilePath now resolves . and .. segments and preserves the UNC \\ prefix
  • BREAKING CHANGES: getFilePathLevel no longer counts a trailing separator as an extra level (/home/user/ now returns the same level as /home/user)
  • BREAKING CHANGES: getCopyFileName now preserves the original file extension casing (e.g. Report.PDF copies to Report (1).PDF instead of Report (1).pdf)
  • BREAKING CHANGES: isValidFileName now validates the whole name including its extension (so hello.:txt is invalid) and rejects Windows device names (CON, NUL, COM1-COM9, LPT1-LPT9, etc.)
  • BREAKING CHANGES: createFileWithDummy now throws for a negative size instead of returning false
  • BREAKING CHANGES: createDirectory, moveFile, and createFile now propagate filesystem errors instead of silently ignoring them
  • duration: Add duration method
  • arrPick: Add arrPick method
  • getParsedInfoFromAddress: Add getParsedInfoFromAddress method
  • getSlug: Add getSlug method
  • hasBadWords: Add hasBadWords method
  • capitalizeEachWords: If the natural option is not enabled, characters that are already uppercase will not be converted to lowercase

1.2.0 - 2026-04-14 #

  • BREAKING CHANGES: strToNumberHash has renamed to numberHash
  • md5Hash, sha1Hash, sha256Hash: Add an encoding option for hash functions
  • Add sortNumeric method
  • Add sha512Hash method

1.1.12 - 2026-03-31 #

  • BREAKING CHANGES: numRandom has renamed to numPick
  • getFileName: Fix incorrect directory name with include dot character
  • Add getCopyFileName method
  • Add div method
  • Add mul method
  • Add sub method
  • Add sum method
  • Add createDateListFromRange method
  • Add dateToYYYYMMDD method
  • Add dayDiff method
  • Add isValidDate method
  • Add today method

1.1.11 - 2025-12-10 #

  • Add split method
  • Add isMobile method
  • Add objDeleteKeyByValue method

1.1.10 - 2025-11-25 #

  • Fix package dependencies

1.1.9 - 2025-11-25 #

  • Add getFileSize method
  • Add normalizeFile method
  • Add headFile method
  • Add tailFile method
  • Add removeLocalePrefix method
  • Add isMatchPathname method
  • Add isBotAgent method
  • Add ceil argument to the fileSizeFormat method

1.1.8 - 2025-11-13 #

  • Add createDirectory method
  • Add getParentFilePath method
  • Add deleteFile method
  • Add createFile method
  • Add deleteAllFileFromDirectory method
  • Add moveFile method
  • Add createFileWithDummy method
  • Add getFileInfo method
  • Add joinFilePath method
  • Add getFileHashFromPath method

1.1.7 - 2025-11-03 #

  • BREAKING CHANGES: getFileSize has renamed to fileSizeFormat
  • BREAKING CHANGES: safeJSONParse: 'fallback' parameters has changed to named parameter
  • BREAKING CHANGES: objToArray: 'recursive' parameters has changed to named parameter
  • Add getFileName and getFileExtension methods
  • Add isFileExists method
  • Add isValidFileName method
  • Add toPosixFilePath method
  • Add getFilePathLevel method
  • Add toValidFilePath method

1.1.6 - 2025-10-15 #

  • isEmail: add onlyLowerCase parameter
  • Add console method
  • Add getStrBytes method

1.1.5 - 2025-03-06 #

  • Update README.md

1.1.4 - 2025-02-28 #

  • Update documentation

1.1.3 - 2025-02-14 #

  • Fix isUrl parameters

1.1.2 - 2025-02-14 #

  • Add debounce method
  • Add isUrl method
  • Add isObject method
  • Add isEqual method
  • Add isEqualStrict method
  • Add isEmpty method

1.1.1 - 2024-11-26 #

  • Fix objTo1d parameters

1.1.0 - 2024-11-26 #

  • Add arrCount method
  • Add between method
  • Add arrGroupByMaxCount method
  • Add numPick method
  • Add len method
  • Add isTrueMinimumNumberOfTimes method
  • Add objToQueryString method
  • Add objToArray method
  • Add objTo1d method

1.0.0 - 2024-10-19 #

  • Add fileSize method
  • Add fileExt method
  • Add safeParseInt method
  • Add isEmail method
  • Add fileName method
  • Add safeJSONParse method
  • Add md5Hash method
  • Add sha1Hash method
  • Add sha256Hash method
  • Add encodeBase64 method
  • Add decodeBase64 method
  • Add strToNumberHash method
  • Add objectId method

0.0.4 - 2024-10-02 #

  • Add average method
  • Add arrMove method
  • Add arrTo1dArray method
  • Add arrRepeat method

0.0.3 - 2024-10-02 #

  • Add strShuffle method
  • Add strRandom method
  • Add truncateExpect method
  • Add strUnique method
  • Add strToAscii method
  • Add urlJoin method
  • Add arrWithDefault method
  • Add arrWithNumber method
  • Add funcTimes method
  • Add is2dArray method
  • Add arrUnique method

0.0.2 - 2024-09-10 #

  • Add trim method
  • Add replaceBetween method
  • Add removeNewLine method
  • Add capitalizeEverySentence method
  • Add contains method
  • Add capitalizeEachWords method
  • Add strCount method
  • Add sleep method
  • Add arrShuffle method
  • Add removeSpecialChar method

0.0.1 - 2024-09-02 - Not for Production #

  • Initial release
1
likes
160
points
328
downloads

Documentation

API reference

Publisher

verified publishercdget.com

Weekly Downloads

Everyday helpers you would otherwise write yourself: slugs, text case, date math, file size formatting, deep clone and merge, validation and hashing.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#utility #helper #string #validation #crypto

License

MIT (license)

Dependencies

crypto, ffi, path, pointycastle, unorm_dart

More

Packages that depend on qsu