§ Open Source

(っ◔◡◔)っ fig. 1. Inter-dependencies within the monorepo.

§ Flagship Libraries

Each one solves a certain business problem.

detergent — as a business, how do we ensure an efortless and safe copy briefs handover between teams while automating the invisible character cleaning and text formatting?

email-comb — as a business, how do we deliver the best customer experience on emails we send, considering the template file sizes are limited by truncation (in Gmail, for example) and each new code improvement (hybrid layout, for example) increases template's file size?

📦 detergent 5.11.6
Extracts, cleans and encodes text
📦 email-comb 3.10.3
Remove unused CSS from email templates
📦 html-crush 2.0.8
Minifies HTML/CSS: valid or broken, pure or mixed with other languages

§ Range Libraries Σ=12   

What are ranges? Composable string amendment instructions. They are arrays containing "from" and "to" string indexes.

For example, a range [1, 5] means an instruction to delete characters which would otherwise fall into String.slice(1, 5).

For example, a range [2, 6, "foo"] means an instruction to replace characters which would otherwise fall into String.slice(2, 6) with string "foo".

That's all there is — we note pieces of string to be deleted or replaced using character indexes and arrays.

The whole point of ranges is to gather all the string tasks, to postpone any string-mutation actions until the end and then mutate the string, in one go.

Read more

📦 ranges-push 3.7.21
Gather string index ranges
📦 ranges-apply 3.2.2
Take an array of string index ranges, delete/replace the string according to them
📦 ranges-merge 5.0.2
Merge and sort string index ranges
📦 ranges-sort 3.13.2
Sort string index ranges
📦 string-range-expander 1.11.10
Expands string index ranges within whitespace boundaries until letters are met
📦 ranges-crop 2.1.2
Crop array of ranges when they go beyond the reference string's length
📦 ranges-ent-decode 2.1.2
Recursive HTML entity decoding for Ranges workflow
📦 ranges-invert 2.1.48
Invert string index ranges
📦 ranges-is-index-within 1.15.1
Checks if index is within any of the given string index ranges
📦 ranges-iterate 1.1.47
Iterate a string and any changes within given string index ranges
📦 ranges-process-outside 2.2.34
Iterate string considering ranges, as if they were already applied
📦 ranges-regex 2.1.2
Integrate regex operations into Ranges workflow

§ HTML Processing Libraries Σ=14   

They all process HTML and CSS. Our speciality is so-called scanerless parsing algorithm — we don't parse and then work on AST and then render. We aim to work on the source code directly while traversing it as a string.

The whole idea is, if you don't parse the HTML, you can support broken or mixed code. Unless you write your parser, it becomes a bottleneck — parser throws here and there, and you can do nothing about it.

It is vital to support broken code because this allows us to make broken code fixing programs.

It is equally vital to support mixed code because both web page and email template HTML can contain anything from templating languages to programming languages.

📦 emlint 2.18.15
Pluggable email template code linter
📦 html-crush 2.0.8
Minifies HTML/CSS: valid or broken, pure or mixed with other languages
📦 string-strip-html 6.0.3
Strips HTML tags from strings. No parser, accepts mixed sources.
📦 detect-is-it-html-or-xhtml 3.9.61
Answers, is the string input string more an HTML or XHTML (or neither)
📦 html-table-patcher 2.0.11
Visual helper to place templating code around table tags into correct places
📦 is-html-tag-opening 1.8.2
Is given opening bracket a beginning of a tag?
📦 is-html-attribute-closing 1.2.7
Is a character on a given index a closing of an HTML attribute?
📦 is-language-code 1.0.11
Is given string a language code (as per IANA)
📦 html-img-alt 1.4.63
Adds missing alt attributes to img tags. Non-parsing.
📦 is-media-descriptor 1.2.18
Is given string a valid media descriptor (including media query)?
📦 is-relative-uri 1.0.19
Is given string a relative URI?
📦 is-char-suitable-for-html-attr-name 1.1.8
Is given character suitable to be in an HTML attribute's name?
📦 html-entities-not-email-friendly 0.2.8
All HTML entities which are not email template friendly
📦 html-all-known-attributes 2.0.7
All HTML attributes known to the Humanity

§ String Processing Libraries Σ=29   

They process string inputs, which might be text, code or something else as long as it is of a string-type.

📦 edit-package-json 0.1.35
Edit package.json without parsing, as string, to keep the formatting intact
📦 easy-replace 3.7.63
Replace strings with optional lookarounds, but without regexes
📦 str-indexes-of-plus 2.10.10
Like indexOf but returns array and counts per-grapheme
📦 bitbucket-slug 1.9.64
Generate BitBucket readme header anchor slug URLs. Unofficial, covers whole ASCII and a bit beyond.
📦 email-all-chars-within-ascii 2.9.71
Scans all characters within a string and checks are they within ASCII range
📦 js-row-num 2.7.27
Update all row numbers in all console.logs in JS code
📦 string-apostrophes 1.2.29
Comprehensive, HTML-entities-aware tool to typographically-correct the apostrophes and single/double quotes
📦 string-character-is-astral-surrogate 1.10.63
Tells, is given character a part of astral character, specifically, a high and low surrogate
📦 string-collapse-leading-whitespace 3.0.1
Collapse the leading and trailing whitespace of a string
📦 string-collapse-white-space 5.2.30
Efficient collapsing of white space with optional outer- and/or line-trimming and HTML tag recognition
📦 string-convert-indexes 2.0.1
Convert between native JS string character indexes and grapheme-count-based indexes
📦 string-extract-class-names 5.9.31
Extract class (or id) name from a string
📦 string-extract-sass-vars 1.2.8
Parse SASS variables file into a plain object of CSS key-value pairs
📦 string-find-heads-tails 3.16.15
Finds where are arbitrary templating marker heads and tails located
📦 string-find-malformed 1.1.15
Search for a malformed string. Think of Levenshtein distance but in search.
📦 string-fix-broken-named-entities 3.0.10
Finds and fixes common and not so common broken named HTML entities, returns ranges array of fixes
📦 string-left-right 2.3.30
Looks up the first non-whitespace character to the left/right of a given index
📦 string-match-left-right 4.0.13
Match substrings on the left or right of a given index, ignoring whitespace
📦 string-overlap-one-on-another 1.5.64
Lay one string on top of another, with an optional offset
📦 string-process-comma-separated 1.2.13
Extracts chunks from possibly comma or whatever-separated string
📦 string-range-expander 1.11.10
Expands string index ranges within whitespace boundaries until letters are met
📦 string-remove-duplicate-heads-tails 3.0.72
Detect and (recursively) remove head and tail wrappings around the input string
📦 string-remove-thousand-separators 3.0.71
Detects and removes thousand separators (dot/comma/quote/space) from string-type digits
📦 string-remove-widows 1.6.16
Helps to prevent widow words in a text
📦 string-split-by-whitespace 1.6.71
Split string into array by chunks of whitespace
📦 string-strip-html 6.0.3
Strips HTML tags from strings. No parser, accepts mixed sources.
📦 string-trim-spaces-only 2.8.22
Like String.trim() but you can choose granularly what to trim
📦 string-uglify 1.2.46
Shorten sets of strings deterministically, to be git-friendly
📦 string-unfancy 3.9.64
Replace all n/m dashes, curly quotes with their simpler equivalents

§ Object Processing Libraries Σ=23   

When we say "object" we mean a plain object in JavaScript, for example, { name: "Bob" }. Usually, plain objects come from JSON files, and often they are deeply nested. The following libraries help us to traverse them, set and delete keys and compare objects.

"ast-" in the library's name below just emphasises that it really works on nested objects (so-called Abstract Syntax Trees that come from parsed things).

📦 ast-monkey 7.11.21
Traverse and edit AST
📦 ast-monkey-traverse 1.12.19
Utility library to traverse AST
📦 ast-monkey-util 1.1.10
Utility library of AST helper functions
📦 json-comb-core 6.6.33
The inner core of json-comb
📦 json-variables 8.2.17
Resolves custom-marked, cross-referenced paths in parsed JSON
📦 object-merge-advanced 10.11.28
Recursive, deep merge of anything (objects, arrays, strings or nested thereof), which weighs contents by type hierarchy to ensure the maximum content is retained
📦 ast-compare 1.13.18
Compare anything: AST, objects, arrays, strings and nested thereof
📦 ast-contains-only-empty-space 1.9.15
Returns Boolean depending if passed AST contain only empty space
📦 ast-deep-contains 1.1.20
Like t.same assert on array of objects, where element order doesn't matter.
📦 ast-delete-object 1.9.0
Delete all plain objects in AST if they contain a certain key/value pair
📦 ast-get-object 1.9.17
Getter/setter for nested parsed HTML AST's, querying objects by key/value pairs
📦 ast-get-values-by-key 2.6.71
Read or edit parsed HTML (or AST in general)
📦 ast-is-empty 1.10.9
Find out, is nested array/object/string/AST tree is empty
📦 ast-loose-compare 1.8.15
Compare anything: AST, objects, arrays and strings
📦 ast-monkey-traverse-with-lookahead 1.1.11
Utility library to traverse AST, reports upcoming values
📦 object-all-values-equal-to 1.8.24
Does the AST/nested-plain-object/array/whatever contain only one kind of value?
📦 object-boolean-combinations 2.11.65
Generate an array full of object copies, each containing a unique Boolean value combination. Includes overrides.
📦 object-delete-key 1.9.37
Delete keys from all arrays or plain objects, nested within anything, by key or by value or by both, and clean up afterwards. Accepts wildcards.
📦 object-fill-missing-keys 7.10.27
Add missing keys into plain objects, according to a reference object
📦 object-flatten-all-arrays 4.8.22
Merge and flatten any arrays found in all values within plain objects
📦 object-flatten-referencing 4.11.26
Flatten complex nested objects according to a reference objects
📦 object-no-new-keys 2.9.10
Check, does a plain object (AST/JSON) has any unique keys, not present in a reference object (another AST/JSON)
📦 object-set-all-values-to 3.9.66
Recursively walk the input and set all found values in plain objects to something

§ Lerna Libraries Σ=4   

While maintaining our monorepo we found that some essential tools were missing, so we created them!

If you also use Lerna monorepos, check these out:

📦 lerna-clean-changelogs-cli 1.2.68
CLI application to cleanse the lerna-generated changelogs
📦 lerna-link-dep 1.1.35
Like lerna add but does just the symlinking, works on CLI bins too
📦 update-versions 2.4.22
Like npm-check-updates but supports Lerna monorepos and enforces strict semver values
📦 lerna-clean-changelogs 1.3.59
Cleans all the crap from Lerna and Conventional Commits-generated changelogs

§ CLI Apps Σ=11   

All the following libraries are command-line applications. You install them using -g flag via npm, for example, npm i -g json-sort-cli. Often a package/library/program would have its CLI counterpart: you can use a package programmatically, inside your programs, or you can use its CLI in the terminal, as a standalone program.

For example, csv-sort package is string-in, string-out function. It's meant to be used by websites, CLI's and Node programs. csv-sort-cli taps it and adds file I/O layer and lets you read/write/sort files directly, via a command line.

📦 json-comb 0.2.62
Command line app to manage sets of JSON files
📦 update-versions 2.4.22
Like npm-check-updates but supports Lerna monorepos and enforces strict semver values
📦 lerna-clean-changelogs-cli 1.2.68
CLI application to cleanse the lerna-generated changelogs
📦 lerna-link-dep 1.1.35
Like lerna add but does just the symlinking, works on CLI bins too
📦 lect 0.14.3
Maintenance CLI for internal consumption
📦 chlu-cli 1.16.80
CH-ange-L-og U-pdate - Automatically fix errors in your changelog file
📦 csv-sort-cli 1.9.82
Command line app to sort double-entry CSVs coming from internet banking statements
📦 email-all-chars-within-ascii-cli 1.10.78
Command line app to scan email templates, are all their characters within ASCII range
📦 generate-atomic-css-cli 1.1.54
Generates and updates all HTML templates' atomic CSS
📦 js-row-num-cli 1.6.38
Update all row numbers in all console.logs in JS code
📦 json-sort-cli 1.16.2
Command line app to deep sort JSON files, retains package.json special key order

§ Miscellaneous Libraries Σ=25   

That's all programs which don't belong to any of the categories above. Here we have programs doing everything, from CSV sorting to Tap output parsing; from converting colour hex codes to processing arrays.

📦 all-named-html-entities 1.3.6
List of all named HTML entities
📦 array-group-str-omit-num-char 2.1.47
Groups array of strings by omitting number characters
📦 array-includes-with-glob 2.12.41
like _.includes but with wildcards
📦 array-of-arrays-into-ast 1.9.49
turns an array of arrays of data into a nested tree of plain objects
📦 array-of-arrays-sort-by-col 2.12.12
sort array of arrays by column, rippling the sorting outwards from that column
📦 array-pull-all-with-glob 4.12.71
pullAllWithGlob - like _.pullAll but pulling stronger, with globs
📦 arrayiffy-if-string 3.11.37
Put non-empty strings into arrays, turn empty-ones into empty arrays. Bypass everything else.
📦 charcode-is-valid-xml-name-character 1.10.63
Does a given character belong to XML spec's "Production 4 OR 4a" type (is acceptable for XML element's name)
📦 check-types-mini 5.7.72
Check the types of your options object's values after user has customised them
📦 chlu 3.7.75
CH-ange-L-og U-pdate - Automatically fix errors in your changelog file
📦 codsen-parser 0.7.6
Parser aiming at broken or mixed code, especially HTML & CSS
📦 codsen-tokenizer 2.17.6
HTML and CSS lexer aimed at code with fatal errors, accepts mixed coding languages
📦 color-shorthand-hex-to-six-digit 2.10.67
Convert shorthand hex color codes into full
📦 csv-sort 3.0.72
Sorts double-entry bookkeeping CSV coming from internet banking
📦 csv-split-easy 3.0.71
Splits the CSV string into array of arrays, each representing a row of columns
📦 email-homey 2.7.71
Generate homepage in the Browsersync root with links/screenshots to all your email templates
📦 eslint-plugin-row-num 1.2.14
ESLint plugin to update row numbers on each console.log
📦 eslint-plugin-test-num 1.3.8
ESLint plugin to update unit test numbers automatically
📦 gulp-email-remove-unused-css 3.6.96
Gulp plugin to remove unused CSS classes/id's from styles in HTML HEAD and inline within BODY
📦 helga 1.1.38
Your next best friend when editing complex nested code
📦 regex-empty-conditional-comments 1.8.62
Regular expression for matching HTML empty conditional comments
📦 tap-parse-string-to-object 1.2.22
Parses raw Tap: string-to-object or stream-to-a-promise-of-an-object
📦 util-array-object-or-both 2.7.66
Validate and normalise user choice: array, object or both?
📦 util-nonempty 2.9.64
Is the input (plain object, array, string or whatever) not empty?

§ Contributing

All contributions are welcome!

  • If you see an error, raise an issueopens in a new tab.
  • If you want a new feature but can't code it up yourself, also raise an issueopens in a new tab. Let's discuss it.
  • If you want a new feature and can code it up yourself - fork the monorepo through GitLab UI, git-clone your fork into your local machine, hack away, remember to write tests. Finally, git-push and raise a merge request through GitLab UI.
  • If you tried to use a package, but something didn't work out, also raise an issueopens in a new tab. We'll try to help.
  • If have anything to say, good or bad, email us.