feat(pwa): move app.logicsrc.com from Turso/libSQL to Postgres via @profullstack/libsql-pg (#218)

Production reads DATABASE_URL (postgres://) through @profullstack/libsql-pg,
which keeps the @libsql/client surface; no query changed. A missing,
non-Postgres or leftover libsql:// URL fails at boot in production. Dev and
tests keep libSQL (file:/:memory:) as a devDependency. Postgres migrations in
src/migrations-pg/ (converted with libsql-pg convert-schema, same file names
so the copied _migrations ledger matches); migrate.mjs picks the dialect.
Tests run against Postgres with PWA_TEST_DATABASE_URL.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Anthony Ettinger 2026-09-25 09:28:40 -07:00 • committed by GitHub
parent c535aaa32c
commit 4ac750e65b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 507 additions and 29 deletions

227
package-lock.json generated
View file

@ -164,12 +164,15 @@
"name": "@logicsrc/pwa",
"version": "0.1.1",
"dependencies": {
"@libsql/client": "^0.14.0",
"@profullstack/libsql-pg": "^0.1.2",
"@simplewebauthn/browser": "^13.3.0",
"@simplewebauthn/server": "^13.1.0",
"cookie-parser": "^1.4.7",
"express": "^4.21.2"
},
"devDependencies": {
"@libsql/client": "^0.14.0"
},
"engines": {
"node": ">=20"
}
@ -178,6 +181,7 @@
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@libsql/client/-/client-0.14.0.tgz",
"integrity": "sha512-/9HEKfn6fwXB5aTEEoMeFh4CtG0ZzbncBb1e++OCdVpgKZ/xyMsIVYXm0w7Pv4RUel803vE6LwniB3PqD72R0Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@libsql/core": "^0.14.0",
@ -191,6 +195,7 @@
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@libsql/core/-/core-0.14.0.tgz",
"integrity": "sha512-nhbuXf7GP3PSZgdCY2Ecj8vz187ptHlZQ0VRc751oB2C1W8jQUXKKklvt7t1LJiUTQBVJuadF628eUk+3cRi4Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"js-base64": "^3.7.5"
@ -203,6 +208,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -216,6 +222,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -226,6 +233,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,
"license": "MIT",
"dependencies": {
"@libsql/isomorphic-fetch": "^0.3.1",
@ -241,6 +249,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -254,6 +263,7 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -267,6 +277,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -280,6 +291,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -293,6 +305,7 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -373,6 +386,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,
"license": "Apache-2.0",
"engines": {
"node": ">=8"
@ -472,6 +486,7 @@
"arm64",
"wasm32"
],
"dev": true,
"license": "MIT",
"os": [
"darwin",
@ -2532,6 +2547,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==",
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">=18.0.0"
@ -3270,6 +3286,70 @@
"node": ">=20.11"
}
},
"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/@profullstack/libsql-pg/node_modules/@libsql/client": {
"version": "0.15.15",
"resolved": "https://registry.npmjs.org/@libsql/client/-/client-0.15.15.tgz",
"integrity": "sha512-twC0hQxPNHPKfeOv3sNT6u2pturQjLcI+CnpTM0SjRpocEGgfiZ7DWKXLNnsothjyJmDqEsBQJ5ztq9Wlu470w==",
"license": "MIT",
"optional": true,
"dependencies": {
"@libsql/core": "^0.15.14",
"@libsql/hrana-client": "^0.7.0",
"js-base64": "^3.7.5",
"libsql": "^0.5.22",
"promise-limit": "^2.7.0"
}
},
"node_modules/@profullstack/libsql-pg/node_modules/@libsql/core": {
"version": "0.15.15",
"resolved": "https://registry.npmjs.org/@libsql/core/-/core-0.15.15.tgz",
"integrity": "sha512-C88Z6UKl+OyuKKPwz224riz02ih/zHYI3Ho/LAcVOgjsunIRZoBw7fjRfaH9oPMmSNeQfhGklSG2il1URoOIsA==",
"license": "MIT",
"optional": true,
"dependencies": {
"js-base64": "^3.7.5"
}
},
"node_modules/@profullstack/libsql-pg/node_modules/@libsql/hrana-client": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@libsql/hrana-client/-/hrana-client-0.7.0.tgz",
"integrity": "sha512-OF8fFQSkbL7vJY9rfuegK1R7sPgQ6kFMkDamiEccNUvieQ+3urzfDFI616oPl8V7T9zRmnTkSjMOImYCAVRVuw==",
"license": "MIT",
"optional": true,
"dependencies": {
"@libsql/isomorphic-fetch": "^0.3.1",
"@libsql/isomorphic-ws": "^0.1.5",
"js-base64": "^3.7.5",
"node-fetch": "^3.3.2"
}
},
"node_modules/@profullstack/logicsrc-mcp": {
"resolved": "packages/logicsrc-mcp",
"link": true
@ -4859,6 +4939,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==",
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 12"
@ -5424,6 +5505,7 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"devOptional": true,
"funding": [
{
"type": "github",
@ -5480,6 +5562,7 @@
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"fetch-blob": "^3.1.2"
@ -6602,6 +6685,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",
"devOptional": true,
"funding": [
{
"type": "github",
@ -6621,6 +6705,7 @@
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
@ -6894,6 +6979,95 @@
"url": "https://github.com/sponsors/KillyMXI"
}
},
"node_modules/pg": {
"version": "8.23.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.23.0.tgz",
"integrity": "sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==",
"license": "MIT",
"dependencies": {
"pg-connection-string": "^2.14.0",
"pg-pool": "^3.14.0",
"pg-protocol": "^1.16.0",
"pg-types": "2.2.0",
"pgpass": "1.0.5"
},
"engines": {
"node": ">= 16.0.0"
},
"optionalDependencies": {
"pg-cloudflare": "^1.4.0"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
},
"peerDependenciesMeta": {
"pg-native": {
"optional": true
}
}
},
"node_modules/pg-cloudflare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.0.tgz",
"integrity": "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==",
"license": "MIT",
"optional": true
},
"node_modules/pg-connection-string": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.0.tgz",
"integrity": "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==",
"license": "MIT"
},
"node_modules/pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
"license": "ISC",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/pg-pool": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz",
"integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==",
"license": "MIT",
"peerDependencies": {
"pg": ">=8.0"
}
},
"node_modules/pg-protocol": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.16.0.tgz",
"integrity": "sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==",
"license": "MIT"
},
"node_modules/pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"license": "MIT",
"dependencies": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/pgpass": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
"license": "MIT",
"dependencies": {
"split2": "^4.1.0"
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@ -7032,6 +7206,45 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/postgres-bytea": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz",
"integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"license": "MIT",
"dependencies": {
"xtend": "^4.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/process-warning": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz",
@ -8736,6 +8949,7 @@
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
"devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 8"
@ -8855,6 +9069,15 @@
"node": ">=16.0.0"
}
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"license": "MIT",
"engines": {
"node": ">=0.4"
}
},
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@ -8963,7 +9186,7 @@
},
"packages/cli": {
"name": "@logicsrc/cli",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"@fission-ai/openspec": "^1.13.0",
"@logicsrc/account-core": "file:../account-core",