OpenViSTAI · Agents · Blockchain · Crypto
Menu
OPENVIST RECIPES

Find repeated keys in configuration assignments with JavaScript

JavaScript

Audit a JSON list of key=value assignments without printing their values.

JavaScript code excerpt: Find repeated keys in configuration assignments with JavaScript. Version 0.1.0. Read the full recipe for code, sources and recorded test scope.

Audit a JSON list of key=value assignments without printing their values. This is a local data check under the documented conventions; it does not execute tools or contact a service.

Before you start

  • Save the code as recipe.cjs and run node recipe.cjs using Node.js 22, supplying the JSON document through stdin. No CLI arguments or help option are accepted.
  • Only node:fs is loaded, and its only operation is bounded readSync calls on stdin descriptor 0. The CLI does not open input paths, write files, execute external commands or contact a network.
  • Input must be a JSON array containing at most 100 strings. Each string must contain an equals sign; the first equals sign separates the key from the value.
  • Keys contain 1–64 ASCII characters: an ASCII letter followed by ASCII letters, digits or underscores. Matching is full-string, including rejection of a final newline. Keys are case-sensitive and are not trimmed or normalized.
  • Empty values and additional equals signs in values are allowed. Values are never included in output or diagnostics.
  • Successful processing exits 0 and emits exactly one JSON object, followed by a newline, with no stderr. The repeated array contains only keys occurring at least twice, sorted by ASCII key, with ascending one-based positions.
  • Invalid arguments, invalid input and stdin read failures exit 2, emit no stdout and use the generic lowercase stderr diagnostic error: invalid request.

Build and check

  1. Use Node.js 22 CommonJS. Save the code as recipe.cjs.
  2. Save the supplied JSON example as input.json, encoded as UTF-8 without a BOM.
  3. Run: node recipe.cjs < input.json
  4. Compare the output with the expected result; handle exit code 2 as invalid input.

Limits to understand

  • The CLI reads at most 65537 bytes and rejects input exceeding 65536 bytes. It can reject oversized input without waiting for EOF.
  • UTF-8 decoding is strict. TextDecoder uses fatal:true and ignoreBOM:true, preserving a leading BOM so JSON.parse rejects it. Native JSON.parse semantics apply.
  • The parsed input is held in memory alongside the byte buffer, decoded text and grouping data. Memory use includes runtime and parser overhead, not just the input byte count.
  • Stdin may block while waiting for data or EOF.
  • Successful output reveals repeated key names and their positions, which may be sensitive even though assignment values are excluded.
  • This does not parse shell syntax, expand variables or load an environment.
  • Output-write failures are excluded from the exit-status, stdout and stderr guarantees.

Run it

node recipe.cjs < input.json

Example input

["TOKEN=secret", "HOST=local", "TOKEN=other"]

Expected output

{"repeated": [{"key": "TOKEN", "positions": [1, 3]}]}
INSPECT THE SCRIPT

Inspect, copy and run the documented checks.

This browser preview builds code locally. It does not contact an API or run the code.

Default example ready.

JavaScript example
'use strict';

const fs = require('node:fs');

let output;
try {
  if (process.argv.length !== 2) {
    throw new Error();
  }

  const maxBytes = 65536;
  const buffer = Buffer.alloc(maxBytes + 1);
  let used = 0;

  while (used < buffer.length) {
    const count = fs.readSync(0, buffer, used, buffer.length - used, null);
    if (count === 0) break;
    used += count;
  }

  if (used > maxBytes) {
    throw new Error();
  }

  const decoder = new TextDecoder('utf-8', {
    fatal: true,
    ignoreBOM: true
  });
  const text = decoder.decode(buffer.subarray(0, used));
  const assignments = JSON.parse(text);

  if (!Array.isArray(assignments) || assignments.length > 100) {
    throw new Error();
  }

  const positionsByKey = new Map();
  const keyPattern = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;

  for (let i = 0; i < assignments.length; i += 1) {
    const assignment = assignments[i];
    if (typeof assignment !== 'string') {
      throw new Error();
    }

    const separator = assignment.indexOf('=');
    if (separator < 0) {
      throw new Error();
    }

    const key = assignment.slice(0, separator);
    const match = keyPattern.exec(key);
    if (match === null || match[0] !== key) {
      throw new Error();
    }

    const position = i + 1;
    if (!Number.isSafeInteger(position)) {
      throw new Error();
    }

    let positions = positionsByKey.get(key);
    if (positions === undefined) {
      positions = [];
      positionsByKey.set(key, positions);
    }
    positions.push(position);
  }

  const repeated = [];
  for (const [key, positions] of positionsByKey) {
    if (positions.length >= 2) {
      repeated.push({ key, positions });
    }
  }

  repeated.sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
  output = JSON.stringify({ repeated }) + '\n';
} catch {
  process.stderr.write('error: invalid request\n');
  process.exit(2);
}

// Output-write failures are deliberately outside the input-error guarantee.
process.stdout.write(output);
What to verify after running
  • The supplied example must match the documented JSON output.
  • Error cases must exit 2 with no stdout. Review sensitive successful output before sharing it.

Request or format preview

Illustrative preview. No provider response, price or balance is fetched.

Change a setting to inspect the preview.

Official sources and related profiles

    Code license: MIT. Keep the license notice with your copy.

    Example version 0.1.0 · Documentation reviewed 2026-10-14.

    Six independent CLI fixtures and 10 curated supplementary checks passed in the pinned offline Node.js 22 CommonJS container. This does not establish exhaustive correctness, production performance or compatibility with an external provider.

    Related browser tools

    Inspect related data locally in your browser. These tools have their own input rules and limits; they do not execute this recipe.