camelToSnake and snakeCamelMapper() drop the underscore when a digit precedes a camelCase boundary

Aperta Adatta ai principianti
#4,855 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
85/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
postgresql, typescript
Ambito
api

Direzione di ricerca

Il bug risiede in camelToSnake in packages/typescript-client/src/column-mapper.ts, la cui regex di confine /([a-z_])([A-Z])/g non rileva le transizioni da cifra a maiuscola. Esegui il repro dell'issue per vedere sha256Hash diventare sha256hash. È completato quando camelToSnake restituisce sha256_hash, oauth2_token, address1_line e v2_payload, e i test di column-mapper coprono i confini con le cifre.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Versions

  • Client: typescript, @electric-sql/client 1.5.28 (also on main 3f9809fb0b, Node v26.13.0)
  • Electric: any (happens client-side before the request reaches Electric)

Bug description

snakeToCamel converts a column like sha256_hash into sha256Hash, and its doc comment states that the transform is round-trippable via camelToSnake. However, camelToSnake in packages/typescript-client/src/column-mapper.ts only inserts _ before an uppercase letter that follows [a-z_], so camelToSnake("sha256Hash") returns "sha256hash".

When ShapeStream or compileExpression uses snakeCamelMapper(), incoming rows are decoded with key sha256Hash, while columns, where, and subset expressions encode sha256Hash as sha256hash, sending a column name that does not exist in Postgres.

// repro.mjs
// npm i @electric-sql/[email protected] && node repro.mjs
import {
  ShapeStream,
  snakeCamelMapper,
  snakeToCamel,
  camelToSnake,
  compileExpression,
} from "@electric-sql/client"

for (const col of ["sha256_hash", "oauth2_token", "address1_line", "v2_payload"]) {
  const camel = snakeToCamel(col)
  console.log(`${col} -> ${camel} -> ${camelToSnake(camel)}`)
}

console.log(
  "compileExpression:",
  compileExpression({ type: "ref", column: "sha256Hash" }, snakeCamelMapper().encode)
)

const fetchClient = async (url) => {
  const u = new URL(url)
  console.log("columns sent:", u.searchParams.get("columns"))
  console.log("where sent:", u.searchParams.get("where"))
  return new Response("[]", { status: 400 })
}

const stream = new ShapeStream({
  url: "http://localhost:3000/v1/shape",
  params: {
    table: "files",
    columns: ["id", "sha256Hash"],
    where: "sha256Hash = $1",
    params: ["abc"],
  },
  columnMapper: snakeCamelMapper(),
  subscribe: false,
  fetchClient,
  onError: () => stream.unsubscribeAll(),
})
stream.subscribe(() => {})

Actual output:

sha256_hash -> sha256Hash -> sha256hash
oauth2_token -> oauth2Token -> oauth2token
address1_line -> address1Line -> address1line
v2_payload -> v2Payload -> v2payload
compileExpression: "sha256hash"
columns sent: "id","sha256hash"
where sent: sha256hash = $1

Expected behavior

camelToSnake should return sha256_hash, oauth2_token, address1_line, and v2_payload, compileExpression should return "sha256_hash", columns should be "id","sha256_hash", and where should be sha256_hash = $1. Changing the first boundary regex in camelToSnake from /([a-z_])([A-Z])/g to /([a-z0-9_])([A-Z])/g preserves the underscore after digits.

Credit: https://ucsbplse.github.io/

Lingua principale
TypeScript
Stelle
10.4k
Fork
399
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di electric-sql/electric

Tutte le issue di electric-sql/electric

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.