generated from tpl/purs
fix: JSON support
This commit is contained in:
parent
e2eb753317
commit
753d14fdd9
@ -1,2 +1,2 @@
|
|||||||
bun 1.0.35
|
bun 1.0.11
|
||||||
purescript 0.15.15
|
purescript 0.15.15
|
||||||
|
202
package-lock.json
generated
Normal file
202
package-lock.json
generated
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
{
|
||||||
|
"name": "purs",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "purs",
|
||||||
|
"dependencies": {
|
||||||
|
"pg": "^8.11.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"bun-types": "1.0.11",
|
||||||
|
"purs-tidy": "^0.10.0",
|
||||||
|
"typescript": "^5.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"postgres-range": "^1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/buffer-writer": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bun-types": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-XaDwjnBlkdTOtBEAcXhDnPSKFMlwFK/526z0iyairYIDhZJMzZM1QU4D7XRiEI2SpKQWexn0S/LN9Mwx5xSJNg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/packet-reader": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
|
||||||
|
},
|
||||||
|
"node_modules/pg": {
|
||||||
|
"version": "8.11.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz",
|
||||||
|
"integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer-writer": "2.0.0",
|
||||||
|
"packet-reader": "1.0.0",
|
||||||
|
"pg-connection-string": "^2.6.2",
|
||||||
|
"pg-pool": "^3.6.1",
|
||||||
|
"pg-protocol": "^1.6.0",
|
||||||
|
"pg-types": "^2.1.0",
|
||||||
|
"pgpass": "1.x"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.0.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"pg-cloudflare": "^1.1.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"pg-native": ">=3.0.1"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"pg-native": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-cloudflare": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"node_modules/pg-connection-string": {
|
||||||
|
"version": "2.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz",
|
||||||
|
"integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA=="
|
||||||
|
},
|
||||||
|
"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==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-pool": {
|
||||||
|
"version": "3.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz",
|
||||||
|
"integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"pg": ">=8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-protocol": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q=="
|
||||||
|
},
|
||||||
|
"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==",
|
||||||
|
"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==",
|
||||||
|
"dependencies": {
|
||||||
|
"split2": "^4.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-bytea": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
|
||||||
|
"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==",
|
||||||
|
"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==",
|
||||||
|
"dependencies": {
|
||||||
|
"xtend": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-range": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/purs-tidy": {
|
||||||
|
"version": "0.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/purs-tidy/-/purs-tidy-0.10.1.tgz",
|
||||||
|
"integrity": "sha512-i1QvMaDEaZXv/GWZNFWs5CISiBOkwPhG4D1S4Rw6zUCGaE+NQNWTjvwY21rifynGa2N2TiBJRC61LkORbmGxrA==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"purs-tidy": "bin/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/split2": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
|
||||||
|
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xtend": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,12 +8,11 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bun-types": "1.0.11",
|
"bun-types": "1.0.11",
|
||||||
"postgres-range": "^1.1.4",
|
|
||||||
"purs-tidy": "^0.10.0",
|
"purs-tidy": "^0.10.0",
|
||||||
"spago": "next"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": { "pg-types": "^4.0.2" }
|
"dependencies": {
|
||||||
|
"postgres-range": "^1.1.4",
|
||||||
|
"pg": "^8.11.3"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
58
spago.lock
58
spago.lock
@ -12,13 +12,16 @@ workspace:
|
|||||||
- foreign
|
- foreign
|
||||||
- lists
|
- lists
|
||||||
- maybe
|
- maybe
|
||||||
|
- mmorph
|
||||||
- newtype
|
- newtype
|
||||||
- node-buffer
|
- node-buffer
|
||||||
- precise-datetime
|
- precise-datetime
|
||||||
- prelude
|
- prelude
|
||||||
|
- simple-json
|
||||||
- transformers
|
- transformers
|
||||||
- unsafe-coerce
|
- unsafe-coerce
|
||||||
test_dependencies:
|
test_dependencies:
|
||||||
|
- foreign-object
|
||||||
- quickcheck
|
- quickcheck
|
||||||
- spec
|
- spec
|
||||||
- spec-quickcheck
|
- spec-quickcheck
|
||||||
@ -45,6 +48,7 @@ workspace:
|
|||||||
- fixed-points
|
- fixed-points
|
||||||
- foldable-traversable
|
- foldable-traversable
|
||||||
- foreign
|
- foreign
|
||||||
|
- foreign-object
|
||||||
- fork
|
- fork
|
||||||
- formatters
|
- formatters
|
||||||
- free
|
- free
|
||||||
@ -80,6 +84,7 @@ workspace:
|
|||||||
- record
|
- record
|
||||||
- refs
|
- refs
|
||||||
- safe-coerce
|
- safe-coerce
|
||||||
|
- simple-json
|
||||||
- spec
|
- spec
|
||||||
- spec-quickcheck
|
- spec-quickcheck
|
||||||
- st
|
- st
|
||||||
@ -88,9 +93,11 @@ workspace:
|
|||||||
- transformers
|
- transformers
|
||||||
- tuples
|
- tuples
|
||||||
- type-equality
|
- type-equality
|
||||||
|
- typelevel-prelude
|
||||||
- unfoldable
|
- unfoldable
|
||||||
- unicode
|
- unicode
|
||||||
- unsafe-coerce
|
- unsafe-coerce
|
||||||
|
- variant
|
||||||
extra_packages: {}
|
extra_packages: {}
|
||||||
packages:
|
packages:
|
||||||
aff:
|
aff:
|
||||||
@ -333,6 +340,23 @@ packages:
|
|||||||
- prelude
|
- prelude
|
||||||
- strings
|
- strings
|
||||||
- transformers
|
- transformers
|
||||||
|
foreign-object:
|
||||||
|
type: registry
|
||||||
|
version: 4.1.0
|
||||||
|
integrity: sha256-q24okj6mT+yGHYQ+ei/pYPj5ih6sTbu7eDv/WU56JVo=
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- foldable-traversable
|
||||||
|
- functions
|
||||||
|
- gen
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- prelude
|
||||||
|
- st
|
||||||
|
- tailrec
|
||||||
|
- tuples
|
||||||
|
- typelevel-prelude
|
||||||
|
- unfoldable
|
||||||
fork:
|
fork:
|
||||||
type: registry
|
type: registry
|
||||||
version: 6.0.0
|
version: 6.0.0
|
||||||
@ -735,6 +759,20 @@ packages:
|
|||||||
integrity: sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU=
|
integrity: sha256-a1ibQkiUcbODbLE/WAq7Ttbbh9ex+x33VCQ7GngKudU=
|
||||||
dependencies:
|
dependencies:
|
||||||
- unsafe-coerce
|
- unsafe-coerce
|
||||||
|
simple-json:
|
||||||
|
type: registry
|
||||||
|
version: 9.0.0
|
||||||
|
integrity: sha256-K3RJaThqsszTd+TEklzZmAdDqvIHWgXIfKqlsoykU1c=
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- exceptions
|
||||||
|
- foreign
|
||||||
|
- foreign-object
|
||||||
|
- nullable
|
||||||
|
- prelude
|
||||||
|
- record
|
||||||
|
- typelevel-prelude
|
||||||
|
- variant
|
||||||
spec:
|
spec:
|
||||||
type: registry
|
type: registry
|
||||||
version: 7.6.0
|
version: 7.6.0
|
||||||
@ -852,6 +890,13 @@ packages:
|
|||||||
version: 4.0.1
|
version: 4.0.1
|
||||||
integrity: sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw=
|
integrity: sha256-Hs9D6Y71zFi/b+qu5NSbuadUQXe5iv5iWx0226vOHUw=
|
||||||
dependencies: []
|
dependencies: []
|
||||||
|
typelevel-prelude:
|
||||||
|
type: registry
|
||||||
|
version: 7.0.0
|
||||||
|
integrity: sha256-uFF2ph+vHcQpfPuPf2a3ukJDFmLhApmkpTMviHIWgJM=
|
||||||
|
dependencies:
|
||||||
|
- prelude
|
||||||
|
- type-equality
|
||||||
unfoldable:
|
unfoldable:
|
||||||
type: registry
|
type: registry
|
||||||
version: 6.0.0
|
version: 6.0.0
|
||||||
@ -875,3 +920,16 @@ packages:
|
|||||||
version: 6.0.0
|
version: 6.0.0
|
||||||
integrity: sha256-IqIYW4Vkevn8sI+6aUwRGvd87tVL36BBeOr0cGAE7t0=
|
integrity: sha256-IqIYW4Vkevn8sI+6aUwRGvd87tVL36BBeOr0cGAE7t0=
|
||||||
dependencies: []
|
dependencies: []
|
||||||
|
variant:
|
||||||
|
type: registry
|
||||||
|
version: 8.0.0
|
||||||
|
integrity: sha256-SR//zQDg2dnbB8ZHslcxieUkCeNlbMToapvmh9onTtw=
|
||||||
|
dependencies:
|
||||||
|
- enums
|
||||||
|
- lists
|
||||||
|
- maybe
|
||||||
|
- partial
|
||||||
|
- prelude
|
||||||
|
- record
|
||||||
|
- tuples
|
||||||
|
- unsafe-coerce
|
||||||
|
@ -13,15 +13,18 @@ package:
|
|||||||
- foreign
|
- foreign
|
||||||
- lists
|
- lists
|
||||||
- maybe
|
- maybe
|
||||||
|
- mmorph
|
||||||
- newtype
|
- newtype
|
||||||
- node-buffer
|
- node-buffer
|
||||||
- precise-datetime
|
- precise-datetime
|
||||||
- prelude
|
- prelude
|
||||||
|
- simple-json
|
||||||
- transformers
|
- transformers
|
||||||
- unsafe-coerce
|
- unsafe-coerce
|
||||||
test:
|
test:
|
||||||
main: Test.Main
|
main: Test.Main
|
||||||
dependencies:
|
dependencies:
|
||||||
|
- foreign-object
|
||||||
- quickcheck
|
- quickcheck
|
||||||
- spec
|
- spec
|
||||||
- spec-quickcheck
|
- spec-quickcheck
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { getTypeParser, setTypeParser } from 'pg-types'
|
import * as Pg from 'pg'
|
||||||
import * as Range from 'postgres-range'
|
import * as Range from 'postgres-range'
|
||||||
|
|
||||||
export const null_ = null
|
export const null_ = null
|
||||||
@ -20,18 +20,18 @@ export const modifyPgTypes = () => {
|
|||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const asString = a => a
|
const asString = a => a
|
||||||
const asStringArray = getTypeParser(oid['text[]'])
|
const asStringArray = Pg.types.getTypeParser(oid['text[]'])
|
||||||
const asStringRange = Range.parse
|
const asStringRange = Range.parse
|
||||||
|
|
||||||
setTypeParser(oid['json'], asString)
|
Pg.types.setTypeParser(oid['json'], asString)
|
||||||
setTypeParser(oid['jsonb'], asString)
|
Pg.types.setTypeParser(oid['jsonb'], asString)
|
||||||
setTypeParser(oid['json[]'], asStringArray)
|
Pg.types.setTypeParser(oid['json[]'], asStringArray)
|
||||||
setTypeParser(oid['jsonb[]'], asStringArray)
|
Pg.types.setTypeParser(oid['jsonb[]'], asStringArray)
|
||||||
|
|
||||||
setTypeParser(oid['timestamp'], asString)
|
Pg.types.setTypeParser(oid['timestamp'], asString)
|
||||||
setTypeParser(oid['timestamptz'], asString)
|
Pg.types.setTypeParser(oid['timestamptz'], asString)
|
||||||
setTypeParser(oid['timestamp[]'], asStringArray)
|
Pg.types.setTypeParser(oid['timestamp[]'], asStringArray)
|
||||||
setTypeParser(oid['timestamptz[]'], asStringArray)
|
Pg.types.setTypeParser(oid['timestamptz[]'], asStringArray)
|
||||||
setTypeParser(oid['tsrange'], asStringRange)
|
Pg.types.setTypeParser(oid['tsrange'], asStringRange)
|
||||||
setTypeParser(oid['tstzrange'], asStringRange)
|
Pg.types.setTypeParser(oid['tstzrange'], asStringRange)
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,14 @@ import Prelude
|
|||||||
|
|
||||||
import Control.Alt ((<|>))
|
import Control.Alt ((<|>))
|
||||||
import Control.Monad.Error.Class (liftEither, liftMaybe)
|
import Control.Monad.Error.Class (liftEither, liftMaybe)
|
||||||
import Control.Monad.Except (Except, ExceptT, except, runExcept, runExceptT, withExceptT)
|
import Control.Monad.Except (ExceptT, runExceptT)
|
||||||
|
import Control.Monad.Morph (hoist)
|
||||||
import Data.Bifunctor (lmap)
|
import Data.Bifunctor (lmap)
|
||||||
import Data.DateTime (DateTime)
|
import Data.DateTime (DateTime)
|
||||||
import Data.Generic.Rep (class Generic)
|
import Data.Generic.Rep (class Generic)
|
||||||
import Data.List.NonEmpty (NonEmptyList)
|
import Data.List.NonEmpty (NonEmptyList)
|
||||||
import Data.Maybe (Maybe(..))
|
import Data.Maybe (Maybe(..))
|
||||||
import Data.Newtype (unwrap, wrap)
|
import Data.Newtype (class Newtype, unwrap, wrap)
|
||||||
import Data.Postgres.Raw (Raw)
|
import Data.Postgres.Raw (Raw)
|
||||||
import Data.Postgres.Raw (unsafeFromForeign, unsafeToForeign) as Raw
|
import Data.Postgres.Raw (unsafeFromForeign, unsafeToForeign) as Raw
|
||||||
import Data.RFC3339String as DateTime.ISO
|
import Data.RFC3339String as DateTime.ISO
|
||||||
@ -18,19 +19,21 @@ import Data.Show.Generic (genericShow)
|
|||||||
import Data.Traversable (traverse)
|
import Data.Traversable (traverse)
|
||||||
import Effect (Effect)
|
import Effect (Effect)
|
||||||
import Effect.Exception (error)
|
import Effect.Exception (error)
|
||||||
import Foreign (ForeignError)
|
import Foreign (ForeignError(..))
|
||||||
import Foreign as F
|
import Foreign as F
|
||||||
import Node.Buffer (Buffer)
|
import Node.Buffer (Buffer)
|
||||||
|
import Simple.JSON (class ReadForeign, class WriteForeign, readJSON', writeJSON)
|
||||||
|
|
||||||
newtype JSON = JSON String
|
newtype JSON a = JSON a
|
||||||
|
|
||||||
|
derive instance Newtype (JSON a) _
|
||||||
|
derive newtype instance WriteForeign a => WriteForeign (JSON a)
|
||||||
|
derive newtype instance ReadForeign a => ReadForeign (JSON a)
|
||||||
|
|
||||||
foreign import null_ :: Raw
|
foreign import null_ :: Raw
|
||||||
|
|
||||||
-- | Important! This effect MUST be evaluated to guarantee
|
-- | This mutates `import('pg').types`, setting deserialization
|
||||||
-- | that (de)serialization will work for timestamp and JSON types.
|
-- | for some types to unmarshal as strings rather than JS values.
|
||||||
-- |
|
|
||||||
-- | This mutates the `pg-types`, overriding the default deserialization
|
|
||||||
-- | behavior for JSON and timestamp types.
|
|
||||||
foreign import modifyPgTypes :: Effect Unit
|
foreign import modifyPgTypes :: Effect Unit
|
||||||
|
|
||||||
-- | The SQL value NULL
|
-- | The SQL value NULL
|
||||||
@ -43,35 +46,12 @@ instance Show Null where
|
|||||||
show = genericShow
|
show = genericShow
|
||||||
|
|
||||||
-- | The serialization & deserialization monad.
|
-- | The serialization & deserialization monad.
|
||||||
type RepT a = ExceptT RepError Effect a
|
type RepT a = ExceptT (NonEmptyList ForeignError) Effect a
|
||||||
|
|
||||||
-- | Errors encounterable while serializing & deserializing.
|
|
||||||
data RepError
|
|
||||||
= RepErrorTypeMismatch { expected :: String, found :: String }
|
|
||||||
| RepErrorInvalid String
|
|
||||||
| RepErrorForeign ForeignError
|
|
||||||
| RepErrorOther String
|
|
||||||
| RepErrorMultiple (NonEmptyList RepError)
|
|
||||||
|
|
||||||
derive instance Generic RepError _
|
|
||||||
derive instance Eq RepError
|
|
||||||
instance Show RepError where
|
|
||||||
show a = genericShow a
|
|
||||||
|
|
||||||
instance Semigroup RepError where
|
|
||||||
append (RepErrorMultiple as) (RepErrorMultiple bs) = RepErrorMultiple (as <> bs)
|
|
||||||
append (RepErrorMultiple as) b = RepErrorMultiple (as <> pure b)
|
|
||||||
append a (RepErrorMultiple bs) = RepErrorMultiple (pure a <> bs)
|
|
||||||
append a b = RepErrorMultiple (pure a <> pure b)
|
|
||||||
|
|
||||||
-- | Flatten to an Effect, rendering any `RepError`s to `String` using `Show`.
|
-- | Flatten to an Effect, rendering any `RepError`s to `String` using `Show`.
|
||||||
smash :: forall a. RepT a -> Effect a
|
smash :: forall a. RepT a -> Effect a
|
||||||
smash = liftEither <=< map (lmap (error <<< show)) <<< runExceptT
|
smash = liftEither <=< map (lmap (error <<< show)) <<< runExceptT
|
||||||
|
|
||||||
-- | Lift an `Except` returned by functions in the `Foreign` module to `RepT`
|
|
||||||
liftForeign :: forall a. Except (NonEmptyList ForeignError) a -> RepT a
|
|
||||||
liftForeign = except <<< runExcept <<< withExceptT (RepErrorMultiple <<< map RepErrorForeign)
|
|
||||||
|
|
||||||
-- | Serialize data of type `a` to a `Raw` SQL value.
|
-- | Serialize data of type `a` to a `Raw` SQL value.
|
||||||
class Serialize a where
|
class Serialize a where
|
||||||
serialize :: a -> RepT Raw
|
serialize :: a -> RepT Raw
|
||||||
@ -95,6 +75,9 @@ instance Serialize Raw where
|
|||||||
instance Serialize Null where
|
instance Serialize Null where
|
||||||
serialize _ = unsafeSerializeCoerce null_
|
serialize _ = unsafeSerializeCoerce null_
|
||||||
|
|
||||||
|
instance WriteForeign a => Serialize (JSON a) where
|
||||||
|
serialize = serialize <<< writeJSON <<< unwrap
|
||||||
|
|
||||||
-- | `bytea`
|
-- | `bytea`
|
||||||
instance Serialize Buffer where
|
instance Serialize Buffer where
|
||||||
serialize = unsafeSerializeCoerce
|
serialize = unsafeSerializeCoerce
|
||||||
@ -127,36 +110,39 @@ instance Serialize a => Serialize (Array a) where
|
|||||||
instance Deserialize Raw where
|
instance Deserialize Raw where
|
||||||
deserialize = pure
|
deserialize = pure
|
||||||
|
|
||||||
|
instance Deserialize Null where
|
||||||
|
deserialize = map (const Null) <<< F.readNullOrUndefined <<< Raw.unsafeToForeign
|
||||||
|
|
||||||
|
instance ReadForeign a => Deserialize (JSON a) where
|
||||||
|
deserialize = map wrap <<< (hoist (pure <<< unwrap) <<< readJSON') <=< deserialize @String
|
||||||
|
|
||||||
-- | `bytea`
|
-- | `bytea`
|
||||||
instance Deserialize Buffer where
|
instance Deserialize Buffer where
|
||||||
deserialize = liftForeign <<< (F.unsafeReadTagged "Buffer") <<< Raw.unsafeToForeign
|
deserialize = (F.unsafeReadTagged "Buffer") <<< Raw.unsafeToForeign
|
||||||
|
|
||||||
instance Deserialize Null where
|
|
||||||
deserialize = map (const Null) <<< liftForeign <<< F.readNullOrUndefined <<< Raw.unsafeToForeign
|
|
||||||
|
|
||||||
instance Deserialize Int where
|
instance Deserialize Int where
|
||||||
deserialize = liftForeign <<< F.readInt <<< Raw.unsafeToForeign
|
deserialize = F.readInt <<< Raw.unsafeToForeign
|
||||||
|
|
||||||
instance Deserialize Boolean where
|
instance Deserialize Boolean where
|
||||||
deserialize = liftForeign <<< F.readBoolean <<< Raw.unsafeToForeign
|
deserialize = F.readBoolean <<< Raw.unsafeToForeign
|
||||||
|
|
||||||
instance Deserialize String where
|
instance Deserialize String where
|
||||||
deserialize = liftForeign <<< F.readString <<< Raw.unsafeToForeign
|
deserialize = F.readString <<< Raw.unsafeToForeign
|
||||||
|
|
||||||
instance Deserialize Number where
|
instance Deserialize Number where
|
||||||
deserialize = liftForeign <<< F.readNumber <<< Raw.unsafeToForeign
|
deserialize = F.readNumber <<< Raw.unsafeToForeign
|
||||||
|
|
||||||
instance Deserialize Char where
|
instance Deserialize Char where
|
||||||
deserialize = liftForeign <<< F.readChar <<< Raw.unsafeToForeign
|
deserialize = F.readChar <<< Raw.unsafeToForeign
|
||||||
|
|
||||||
instance Deserialize DateTime where
|
instance Deserialize DateTime where
|
||||||
deserialize raw = do
|
deserialize raw = do
|
||||||
s :: String <- deserialize raw
|
s :: String <- deserialize raw
|
||||||
let invalid = RepErrorInvalid $ "Not a valid ISO8601 string: `" <> s <> "`"
|
let invalid = pure $ ForeignError $ "Not a valid ISO8601 string: `" <> s <> "`"
|
||||||
liftMaybe invalid $ DateTime.ISO.toDateTime $ wrap s
|
liftMaybe invalid $ DateTime.ISO.toDateTime $ wrap s
|
||||||
|
|
||||||
instance Deserialize a => Deserialize (Array a) where
|
instance Deserialize a => Deserialize (Array a) where
|
||||||
deserialize = traverse (deserialize <<< Raw.unsafeFromForeign) <=< liftForeign <<< F.readArray <<< Raw.unsafeToForeign
|
deserialize = traverse (deserialize <<< Raw.unsafeFromForeign) <=< F.readArray <<< Raw.unsafeToForeign
|
||||||
|
|
||||||
instance Deserialize a => Deserialize (Maybe a) where
|
instance Deserialize a => Deserialize (Maybe a) where
|
||||||
deserialize raw =
|
deserialize raw =
|
||||||
|
@ -8,8 +8,8 @@ import Data.DateTime (DateTime(..))
|
|||||||
import Data.DateTime.Instant as Instant
|
import Data.DateTime.Instant as Instant
|
||||||
import Data.Int as Int
|
import Data.Int as Int
|
||||||
import Data.Maybe (Maybe, fromJust, fromMaybe, maybe)
|
import Data.Maybe (Maybe, fromJust, fromMaybe, maybe)
|
||||||
import Data.Newtype (wrap)
|
import Data.Newtype (unwrap, wrap)
|
||||||
import Data.Postgres (class Rep, Null(..), deserialize, null_, serialize, smash)
|
import Data.Postgres (class Rep, JSON(..), Null(..), deserialize, null_, serialize, smash)
|
||||||
import Data.Postgres.Range as Range
|
import Data.Postgres.Range as Range
|
||||||
import Data.Postgres.Raw (Raw)
|
import Data.Postgres.Raw (Raw)
|
||||||
import Data.Postgres.Raw as Raw
|
import Data.Postgres.Raw as Raw
|
||||||
@ -19,7 +19,9 @@ import Effect.Class (liftEffect)
|
|||||||
import Effect.Console (log)
|
import Effect.Console (log)
|
||||||
import Effect.Unsafe (unsafePerformEffect)
|
import Effect.Unsafe (unsafePerformEffect)
|
||||||
import Foreign (unsafeToForeign)
|
import Foreign (unsafeToForeign)
|
||||||
|
import Foreign.Object as Object
|
||||||
import Partial.Unsafe (unsafePartial)
|
import Partial.Unsafe (unsafePartial)
|
||||||
|
import Simple.JSON (writeImpl, writeJSON)
|
||||||
import Test.QuickCheck (class Arbitrary, (==?))
|
import Test.QuickCheck (class Arbitrary, (==?))
|
||||||
import Test.Spec (Spec, describe, it)
|
import Test.Spec (Spec, describe, it)
|
||||||
import Test.Spec.Assertions (shouldEqual)
|
import Test.Spec.Assertions (shouldEqual)
|
||||||
@ -54,6 +56,21 @@ spec =
|
|||||||
check @(Array String) "Array String" identity asRaw
|
check @(Array String) "Array String" identity asRaw
|
||||||
check @DateTime "DateTime" dateTimeFromArbitrary (asRaw <<< DateTime.ISO.fromDateTime)
|
check @DateTime "DateTime" dateTimeFromArbitrary (asRaw <<< DateTime.ISO.fromDateTime)
|
||||||
|
|
||||||
|
describe "JSON" do
|
||||||
|
describe "Record" do
|
||||||
|
it "deserialize" $
|
||||||
|
quickCheck \(a /\ b /\ c :: Int /\ String /\ Array {"foo" :: String}) -> unsafePerformEffect do
|
||||||
|
let
|
||||||
|
obj = {a, b, c}
|
||||||
|
json = writeJSON obj
|
||||||
|
act :: JSON _ <- smash $ deserialize $ asRaw json
|
||||||
|
pure $ obj ==? unwrap act
|
||||||
|
it "serialize" $
|
||||||
|
quickCheck \(a /\ b /\ c :: Int /\ String /\ Array {"foo" :: String}) -> unsafePerformEffect do
|
||||||
|
let obj = {a, b, c}
|
||||||
|
act <- smash $ serialize $ JSON obj
|
||||||
|
pure $ asRaw (writeJSON obj) ==? act
|
||||||
|
|
||||||
describe "Null" do
|
describe "Null" do
|
||||||
it "serialize" $ liftEffect $ shouldEqual null_ =<< (smash $ serialize Null)
|
it "serialize" $ liftEffect $ shouldEqual null_ =<< (smash $ serialize Null)
|
||||||
it "deserialize" $ liftEffect $ shouldEqual Null =<< (smash $ deserialize null_)
|
it "deserialize" $ liftEffect $ shouldEqual Null =<< (smash $ deserialize null_)
|
||||||
|
Loading…
Reference in New Issue
Block a user