Skip to Content
  • Website
Codsen
  • Home
  • Open Source
  • Articles
  • About

prevOpen Source→js-row-numnext

js-row-num7.2.1

Update all row numbers in all console.logs in JS code

Downloads per monthChangelogMIT Licenselibera manifesto
  • the top
  • Installation
  • Quick Take
  • Examples
  • PURPOSE
  • API — FIXROWNUMS()
  • API — DEFAULTS
  • API — VERSION
  • API — TYPES
  • RULES
  • OPTS — OVERRIDEROWN…
  • OPTS — RETURNRANGES
  • OPTS — TRIGGERKEYWO…
  • OPTS — EXTRACTEDLOG…
  • Changelog

Installation

Quick Take

Examples

  • Custom logging trigger
  • Process already-extracted log contents
  • Override every detected row number
  • Custom line-number padding
  • Inspect the replacement ranges

Purpose

It updates the numbers in console.logs so that you can know what’s happening on which line:

console.log(`056 SET counter = ${counter}`);
//            ^  └-----------------------┘
//          where      what happened

Every single package on our monorepo relies on eslint rule eslint-plugin-row-num which is driven by this package.

Result from real life — a snippet of detergent one test dev build’s terminal output:

detergent terminal output on dev mode
detergent terminal output on dev mode

Notice numbers in front of each logged statement, 073 and 134 and so on. We casually deal with source files spanning thousands of lines.

API — fixRowNums()

The main function fixRowNums() is imported like this:

It’s a function which takes two input arguments:

The optional options object has the following shape:

KeyTypeDefault valueDescription
padStart
Type: Zero, natural number or anything falsy
padStartZero, natural number or anything falsy3Sets how much digits will be padded
overrideRowNum
Type: integer or something falsy
overrideRowNuminteger or something falsynullIf you have console.log contents already extracted and know the row number, you can pass that row number here. Multiple console.logs on multiple lines won’t be recognised; the program assumes you’ll process each console.log one by one.
returnRangesOnly
Type: boolean
returnRangesOnlybooleanfalseWhen enabled, instead of string, program will return result in ranges notation.
triggerKeywords
Type: null or array of zero or more strings
triggerKeywordsnull or array of zero or more strings["console.log"]After this string, first met chunks of numbers will be replaced with padded row number, unless letter is met first
extractedLogContentsWereGiven
Type: boolean
extractedLogContentsWereGivenbooleanfalseNormally the program expects a whole line to be given, but if you give extracted contents of console.log, activate this flag.

Here are all defaults in one place for copying:

Function returns a string unless ranges were requested via opts.returnRangesOnly.

API — defaults

You can import defaults:

It's a plain object:

The main function calculates the options to be used by merging the options you passed with these defaults.

API — version

You can import version:

API — types

This package is written in TypeScript and exports the following types:

TypeDescription
Opts
Type: Opts
OptsThe Optional Options Object of fixRowNums(), documented above.
Res
Type: Res
ResWhat fixRowNums() returns — the result, the ranges applied and a log.
Ranges
Type: Ranges
RangesZero or more ranges, or null — the type of the ranges key above.
import type { Opts, Ranges, Res } from "js-row-num";

Rules

Only the digits within console.log string will be replaced.

If the letter (either case) precedes the number, it will not be replaced. We agree that numbers should be in front of the console.log statement:

This row number will be replaced:

console.log("000 This number in front will be replaced");
// ...replaced into:
console.log("001 This number in front will be replaced");

But not this (because letters precede 000):

// will not be replaced:
console.log("This number: 000 will not be replaced because letter precedes it");

The type of quotes doesn’t matter: single, double or backticks, as long as opening quote matches the closing quote.

All non-letter characters in front of a digit will not be touched.

Only one lump of digits will be replaced. Second lump onwards will not be touched:

console.log("888 999 This number in front will be replaced");
// ...replaced with:
console.log("001 999 This number in front will be replaced"); // it's first line, so "001"

EOL type does not matter; we support all three types of EOL’s: \n, \r and \r\n (see unit tests under group 05.01).

If you don’t use console.log, put your function’s name in opts.triggerKeywords:

fixRowNums(`a\nb\nc\n log(\`1 something\`)`, { triggerKeywords: ["log"] }),
// => "a\nb\nc\n log(\`004 something\`)"

Above, log() is used and it’s on the fourth row and padding is default (three).

opts.overrideRowNum

If you process each console.log one by one (like we do in eslint-plugin-row-num) and you already know the row number, you can use this program to pad it and perform the replacement.

import { fixRowNums } from "js-row-num";
const res = fixRowNums(
  `
console.log('099 something')
`,
  {
    overrideRowNum: 5,
  },
);
console.log(res);
// =>
// console.log('005 something')
//

opts.returnRanges

Upon request, string-strip-html can also return ranges instead of a final string.

import { fixRowNums } from "js-row-num";
const res = fixRowNums(
  `
console.log('099 something')
`,
  {
    overrideRowNum: 5,
    returnRangesOnly: true,
  },
);
console.log(res);
// =>
// [
//    [ 15, 18, "005"]
// ]
//

opts.triggerKeywords

Setting opts.triggerKeywords to null will disable all keywords, program will do nothing. In all other cases, where opts.triggerKeywords is an empty array, undefined or boolean false, the default, console.log will kick in and the input will be processed.

opts.extractedLogContentsWereGiven

Sometimes we have other programs processing the code and console.log contents come in already extracted. We just want this program to extract line numbers and update them. That’s when this option comes in.

Changelog

Open Changelog
↑ back to top
prev next

Copyright

All rights reserved © Roy Revelt 2026
All our open source packages are under MIT licenceopens in a new tab

Activities

🐛 See a bug? Raise an issueopens in a new tab
💘 Check out the Indiewebopens in a new tab and Libera manifestoopens in a new tab