From 1b67549f3e6ccaf2f44c6977c8c3603c8a8c30c0 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Fri, 25 Sep 2026 16:28:45 +0000 Subject: [PATCH 1/3] 0.1.3: a literal DEFAULT before CHECK, and datetime modifiers, survive schema conversion rewriteDefault/stripDefault measured the start of the DEFAULT value on the code mask, where a string literal is blanked to spaces, so `default 'viewer' check (...)` skipped past 'viewer' and rewrote CHECK as the default value: the converted DDL read `default 'viewer' (CHECK) (role in (...))` and failed to parse. Any app that runs its CREATE TABLE statements at start-up through the client hit this (moshcoding). The gap after DEFAULT is now measured on the text. `default (datetime('now','+7 days'))` was short-circuited to now(), dropping the modifier; only the bare datetime('now') form is special-cased now, and the function rewriter produces (now() + interval '7 days') for the rest. Co-Authored-By: Claude Fable 5.1 --- package.json | 2 +- src/schema.js | 14 ++++++++++---- test/schema.test.js | 10 ++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a00cea0..5f6b1c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@profullstack/libsql-pg", - "version": "0.1.2", + "version": "0.1.3", "type": "module", "description": "Drop-in replacement for @libsql/client that talks to Postgres, plus the tools to move a Turso/libSQL database into it: the same execute/batch/transaction surface, SQLite idioms rewritten on the way through, a schema converter and a row copier.", "keywords": [ diff --git a/src/schema.js b/src/schema.js index 3ff9677..80bb788 100644 --- a/src/schema.js +++ b/src/schema.js @@ -154,9 +154,12 @@ function convertColumnConstraints(constraints, { type, ctx, opts }) { /** Remove a DEFAULT clause (a literal or a parenthesised expression). */ function stripDefault(c) { const mask = codeMask(c); - const m = /(? { assert.match(out, /i double precision default 0\.5/i); assert.match(out, /j bigint default \(extract\(epoch from now\(\)\)::bigint\)/i); }); + + test('keeps a literal DEFAULT that is followed by CHECK, and datetime modifiers in a default', () => { + const out = convertSchema( + "create table m (role text not null default 'viewer' check (role in ('owner','viewer')), expires_at text not null default (datetime('now','+7 days')), n integer default 0 check (n >= 0))", + ); + assert.match(out, /role text not null default 'viewer' check \(role in \('owner','viewer'\)\)/i); + assert.doesNotMatch(out, /\(check\)/i); + assert.match(out, /expires_at timestamptz not null default \(now\(\) \+ interval '7 days'\)/i); + assert.match(out, /n bigint default 0 check \(n >= 0\)/i); + }); test('a TEXT column with a current-time default is promoted to timestamptz unless told not to', () => { assert.match(strip(one("create table p (t text default (datetime('now')))")), /t timestamptz/); assert.match(strip(one("create table p (t text default (datetime('now')))", { promoteTextTimestamps: false })), /t text default now\(\)/i); From a50760a94e52637af80bcf7692f261c4212a17ae Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Fri, 25 Sep 2026 16:30:28 +0000 Subject: [PATCH 2/3] lockfile: 0.1.3 --- package-lock.json | 86 +++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a300b5..fa45a14 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,25 +1,29 @@ { "name": "@profullstack/libsql-pg", - "version": "0.1.0", + "version": "0.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@profullstack/libsql-pg", - "version": "0.1.0", + "version": "0.1.3", "license": "MIT", "dependencies": { + "@profullstack/libsql-pg": "^0.1.1", "pg": "^8.13.0" }, "bin": { "libsql-pg": "bin/libsql-pg.js" }, "devDependencies": { - "@libsql/client": "^0.15.0" + "@libsql/client": "^0.15.15" }, "engines": { "node": ">=20" }, + "optionalDependencies": { + "@libsql/client": "^0.15.0" + }, "peerDependencies": { "@libsql/client": ">=0.5.0" }, @@ -33,7 +37,7 @@ "version": "0.15.15", "resolved": "https://registry.npmjs.org/@libsql/client/-/client-0.15.15.tgz", "integrity": "sha512-twC0hQxPNHPKfeOv3sNT6u2pturQjLcI+CnpTM0SjRpocEGgfiZ7DWKXLNnsothjyJmDqEsBQJ5ztq9Wlu470w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@libsql/core": "^0.15.14", @@ -47,7 +51,7 @@ "version": "0.15.15", "resolved": "https://registry.npmjs.org/@libsql/core/-/core-0.15.15.tgz", "integrity": "sha512-C88Z6UKl+OyuKKPwz224riz02ih/zHYI3Ho/LAcVOgjsunIRZoBw7fjRfaH9oPMmSNeQfhGklSG2il1URoOIsA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "js-base64": "^3.7.5" @@ -60,7 +64,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -74,7 +77,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -85,7 +87,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/@libsql/hrana-client/-/hrana-client-0.7.0.tgz", "integrity": "sha512-OF8fFQSkbL7vJY9rfuegK1R7sPgQ6kFMkDamiEccNUvieQ+3urzfDFI616oPl8V7T9zRmnTkSjMOImYCAVRVuw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@libsql/isomorphic-fetch": "^0.3.1", @@ -98,7 +100,7 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/@libsql/isomorphic-fetch/-/isomorphic-fetch-0.3.1.tgz", "integrity": "sha512-6kK3SUK5Uu56zPq/Las620n5aS9xJq+jMBcNSOmjhNf/MUvdyji4vrMTqD7ptY7/4/CAVEAYDeotUz60LNQHtw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=18.0.0" @@ -108,7 +110,7 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/@libsql/isomorphic-ws/-/isomorphic-ws-0.1.5.tgz", "integrity": "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/ws": "^8.5.4", @@ -122,7 +124,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -136,7 +137,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -150,7 +150,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -164,7 +163,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -178,7 +176,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -192,7 +189,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -206,7 +202,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -217,14 +212,41 @@ "version": "0.0.4", "resolved": "https://registry.npmjs.org/@neon-rs/load/-/load-0.0.4.tgz", "integrity": "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==", - "dev": true, + "devOptional": true, "license": "MIT" }, + "node_modules/@profullstack/libsql-pg": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@profullstack/libsql-pg/-/libsql-pg-0.1.2.tgz", + "integrity": "sha512-6YrQujssWhkyWInB0G4CWOhH6Pj6kydeK4RKrXOosxQ12flpO4VjUEGTabtSh9zZ7FzCRch0hwFNKApJl/7b4w==", + "license": "MIT", + "dependencies": { + "@profullstack/libsql-pg": "^0.1.1", + "pg": "^8.13.0" + }, + "bin": { + "libsql-pg": "bin/libsql-pg.js" + }, + "engines": { + "node": ">=20" + }, + "optionalDependencies": { + "@libsql/client": "^0.15.0" + }, + "peerDependencies": { + "@libsql/client": ">=0.5.0" + }, + "peerDependenciesMeta": { + "@libsql/client": { + "optional": true + } + } + }, "node_modules/@types/node": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.2.tgz", "integrity": "sha512-X1P21scMv4zGKLYqjdGjaKa7COa0RKVYYZZN/NfvLQ1JegxFhdhpZG/Lyn8AXx6CDUavKAd11v6BvfpkDByK8g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~8.9.0" @@ -234,7 +256,7 @@ "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -244,7 +266,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 12" @@ -254,7 +276,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -264,7 +286,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -288,7 +310,7 @@ "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "fetch-blob": "^3.1.2" @@ -301,7 +323,7 @@ "version": "3.9.4", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.9.4.tgz", "integrity": "sha512-PtOMXpEGuP0RRiRXsjzHzl44dMHxSu2CPvAhinupR1tBa88me+1DPqsobl7eupn5UukjLkln1ZnAOAOXOrYG0Q==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause" }, "node_modules/libsql": { @@ -314,7 +336,7 @@ "wasm32", "arm" ], - "dev": true, + "devOptional": true, "license": "MIT", "os": [ "darwin", @@ -342,7 +364,7 @@ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", "deprecated": "Use your platform's native DOMException instead", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -362,7 +384,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", @@ -509,7 +531,7 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/promise-limit/-/promise-limit-2.7.0.tgz", "integrity": "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/split2": { @@ -525,14 +547,14 @@ "version": "8.9.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz", "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 8" @@ -542,7 +564,7 @@ "version": "8.21.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10.0.0" From 41be484f08b41095fb95a2caa68f9a707ec4b2e9 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Fri, 25 Sep 2026 16:35:27 +0000 Subject: [PATCH 3/3] test: let the shell expand the test glob; Node 20 does not --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5f6b1c6..d5efd5e 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "LICENSE" ], "scripts": { - "test": "node --test \"test/*.test.js\"", + "test": "node --test test/*.test.js", "test:unit": "node --test test/rewrite.test.js test/bind.test.js test/result.test.js test/errors.test.js test/schema.test.js test/copy-plan.test.js" }, "engines": {