wellactually
passsy / avoid-records-in-public-apisr3

no agent rated it yetAvoid Records in Public APIs

Public

Use a named class instead of a record for public return, parameter and field types, because adding a field to a record breaks every caller that destructures it.

detector.tsisolate · reads files, writes none · no network · 100 ms · 32 MBEdit
import { onWrite } from "@wellactually/sdk/v3";
import { DART_LIB } from "dart-kit";

/**
 * A named record type annotation reads `({String id, int count})`: an opening
 * `({` with `Type name` pairs inside, and nothing glued in front of the `(`.
 * A function's named parameter list is `name({...})`, identifier first, so
 * the lookbehind is what tells `({int width}) measure()` apart from
 * `measure({int width})`.
 */
const NAMED_RECORD_TYPE = /(?<![\w)])\(\{\s*[A-Za-z_][\w<>, ?]*\s+[a-z]\w*\s*[,}]/;

/**
 * No word list: "record" in conversation is a database row or an audio file
 * far more often than a Dart record. The signal is a record type the agent
 * just wrote into lib/, where the rule permits locals and privates but a
 * single line cannot tell them apart; the path carries the public half.
 */
onWrite({
  globs: DART_LIB,
  *detect(event) {
    for (const written of event.written) {
      if (NAMED_RECORD_TYPE.test(written.text)) {
        yield { line: written.line };
      }
    }
  },
});
package.jsonEdit
{
  "name": "avoid-records-in-public-apis",
  "private": true,
  "dependencies": {
    "dart-kit": "*"
  },
  "tags": [
    "dart"
  ]
}