From 578a0948218bd15cc09b266af6040513d519f7a4 Mon Sep 17 00:00:00 2001 From: theia Date: Mon, 27 Jan 2025 21:32:13 -0500 Subject: [PATCH] tests are longer, no other error, loosened loginevent type --- package-lock.json | 366 +++++++++---------- package.json | 2 +- src/2-types.ts | 19 +- src/3-errors.ts | 8 - tests/src/crud.ts | 816 +++++++++++++++++++++--------------------- tests/src/discover.ts | 2 +- 6 files changed, 614 insertions(+), 599 deletions(-) diff --git a/package-lock.json b/package-lock.json index 83f7fab..a3107cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@graffiti-garden/api", - "version": "0.1.8", + "version": "0.1.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@graffiti-garden/api", - "version": "0.1.8", + "version": "0.1.9", "license": "GPL-3.0-or-later", "dependencies": { "@types/json-schema": "^7.0.15", @@ -514,17 +514,10 @@ "node": ">= 8.0.0" } }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.31.0.tgz", - "integrity": "sha512-9NrR4033uCbUBRgvLcBrJofa2KY9DzxL2UKZ1/4xA/mnTNyhZCWBuD8X3tPm1n4KxcgaraOYgrFKSgwjASfmlA==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.0.tgz", + "integrity": "sha512-G2fUQQANtBPsNwiVFg4zKiPQyjVKZCUdQUol53R8E71J7AsheRMV/Yv/nB8giOcOVqP7//eB5xPqieBYZe9bGg==", "cpu": [ "arm" ], @@ -536,9 +529,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.31.0.tgz", - "integrity": "sha512-iBbODqT86YBFHajxxF8ebj2hwKm1k8PTBQSojSt3d1FFt1gN+xf4CowE47iN0vOSdnd+5ierMHBbu/rHc7nq5g==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.32.0.tgz", + "integrity": "sha512-qhFwQ+ljoymC+j5lXRv8DlaJYY/+8vyvYmVx074zrLsu5ZGWYsJNLjPPVJJjhZQpyAKUGPydOq9hRLLNvh1s3A==", "cpu": [ "arm64" ], @@ -550,9 +543,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.31.0.tgz", - "integrity": "sha512-WHIZfXgVBX30SWuTMhlHPXTyN20AXrLH4TEeH/D0Bolvx9PjgZnn4H677PlSGvU6MKNsjCQJYczkpvBbrBnG6g==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.0.tgz", + "integrity": "sha512-44n/X3lAlWsEY6vF8CzgCx+LQaoqWGN7TzUfbJDiTIOjJm4+L2Yq+r5a8ytQRGyPqgJDs3Rgyo8eVL7n9iW6AQ==", "cpu": [ "arm64" ], @@ -564,9 +557,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.31.0.tgz", - "integrity": "sha512-hrWL7uQacTEF8gdrQAqcDy9xllQ0w0zuL1wk1HV8wKGSGbKPVjVUv/DEwT2+Asabf8Dh/As+IvfdU+H8hhzrQQ==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.32.0.tgz", + "integrity": "sha512-F9ct0+ZX5Np6+ZDztxiGCIvlCaW87HBdHcozUfsHnj1WCUTBUubAoanhHUfnUHZABlElyRikI0mgcw/qdEm2VQ==", "cpu": [ "x64" ], @@ -578,9 +571,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.31.0.tgz", - "integrity": "sha512-S2oCsZ4hJviG1QjPY1h6sVJLBI6ekBeAEssYKad1soRFv3SocsQCzX6cwnk6fID6UQQACTjeIMB+hyYrFacRew==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.32.0.tgz", + "integrity": "sha512-JpsGxLBB2EFXBsTLHfkZDsXSpSmKD3VxXCgBQtlPcuAqB8TlqtLcbeMhxXQkCDv1avgwNjF8uEIbq5p+Cee0PA==", "cpu": [ "arm64" ], @@ -592,9 +585,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.31.0.tgz", - "integrity": "sha512-pCANqpynRS4Jirn4IKZH4tnm2+2CqCNLKD7gAdEjzdLGbH1iO0zouHz4mxqg0uEMpO030ejJ0aA6e1PJo2xrPA==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.32.0.tgz", + "integrity": "sha512-wegiyBT6rawdpvnD9lmbOpx5Sph+yVZKHbhnSP9MqUEDX08G4UzMU+D87jrazGE7lRSyTRs6NEYHtzfkJ3FjjQ==", "cpu": [ "x64" ], @@ -606,9 +599,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.31.0.tgz", - "integrity": "sha512-0O8ViX+QcBd3ZmGlcFTnYXZKGbFu09EhgD27tgTdGnkcYXLat4KIsBBQeKLR2xZDCXdIBAlWLkiXE1+rJpCxFw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.32.0.tgz", + "integrity": "sha512-3pA7xecItbgOs1A5H58dDvOUEboG5UfpTq3WzAdF54acBbUM+olDJAPkgj1GRJ4ZqE12DZ9/hNS2QZk166v92A==", "cpu": [ "arm" ], @@ -620,9 +613,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.31.0.tgz", - "integrity": "sha512-w5IzG0wTVv7B0/SwDnMYmbr2uERQp999q8FMkKG1I+j8hpPX2BYFjWe69xbhbP6J9h2gId/7ogesl9hwblFwwg==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.32.0.tgz", + "integrity": "sha512-Y7XUZEVISGyge51QbYyYAEHwpGgmRrAxQXO3siyYo2kmaj72USSG8LtlQQgAtlGfxYiOwu+2BdbPjzEpcOpRmQ==", "cpu": [ "arm" ], @@ -634,9 +627,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.31.0.tgz", - "integrity": "sha512-JyFFshbN5xwy6fulZ8B/8qOqENRmDdEkcIMF0Zz+RsfamEW+Zabl5jAb0IozP/8UKnJ7g2FtZZPEUIAlUSX8cA==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.32.0.tgz", + "integrity": "sha512-r7/OTF5MqeBrZo5omPXcTnjvv1GsrdH8a8RerARvDFiDwFpDVDnJyByYM/nX+mvks8XXsgPUxkwe/ltaX2VH7w==", "cpu": [ "arm64" ], @@ -648,9 +641,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.31.0.tgz", - "integrity": "sha512-kpQXQ0UPFeMPmPYksiBL9WS/BDiQEjRGMfklVIsA0Sng347H8W2iexch+IEwaR7OVSKtr2ZFxggt11zVIlZ25g==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.32.0.tgz", + "integrity": "sha512-HJbifC9vex9NqnlodV2BHVFNuzKL5OnsV2dvTw6e1dpZKkNjPG6WUq+nhEYV6Hv2Bv++BXkwcyoGlXnPrjAKXw==", "cpu": [ "arm64" ], @@ -662,9 +655,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.31.0.tgz", - "integrity": "sha512-pMlxLjt60iQTzt9iBb3jZphFIl55a70wexvo8p+vVFK+7ifTRookdoXX3bOsRdmfD+OKnMozKO6XM4zR0sHRrQ==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.32.0.tgz", + "integrity": "sha512-VAEzZTD63YglFlWwRj3taofmkV1V3xhebDXffon7msNz4b14xKsz7utO6F8F4cqt8K/ktTl9rm88yryvDpsfOw==", "cpu": [ "loong64" ], @@ -676,9 +669,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.31.0.tgz", - "integrity": "sha512-D7TXT7I/uKEuWiRkEFbed1UUYZwcJDU4vZQdPTcepK7ecPhzKOYk4Er2YR4uHKme4qDeIh6N3XrLfpuM7vzRWQ==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.32.0.tgz", + "integrity": "sha512-Sts5DST1jXAc9YH/iik1C9QRsLcCoOScf3dfbY5i4kH9RJpKxiTBXqm7qU5O6zTXBTEZry69bGszr3SMgYmMcQ==", "cpu": [ "ppc64" ], @@ -690,9 +683,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.31.0.tgz", - "integrity": "sha512-wal2Tc8O5lMBtoePLBYRKj2CImUCJ4UNGJlLwspx7QApYny7K1cUYlzQ/4IGQBLmm+y0RS7dwc3TDO/pmcneTw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.32.0.tgz", + "integrity": "sha512-qhlXeV9AqxIyY9/R1h1hBD6eMvQCO34ZmdYvry/K+/MBs6d1nRFLm6BOiITLVI+nFAAB9kUB6sdJRKyVHXnqZw==", "cpu": [ "riscv64" ], @@ -704,9 +697,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.31.0.tgz", - "integrity": "sha512-O1o5EUI0+RRMkK9wiTVpk2tyzXdXefHtRTIjBbmFREmNMy7pFeYXCFGbhKFwISA3UOExlo5GGUuuj3oMKdK6JQ==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.32.0.tgz", + "integrity": "sha512-8ZGN7ExnV0qjXa155Rsfi6H8M4iBBwNLBM9lcVS+4NcSzOFaNqmt7djlox8pN1lWrRPMRRQ8NeDlozIGx3Omsw==", "cpu": [ "s390x" ], @@ -718,9 +711,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.31.0.tgz", - "integrity": "sha512-zSoHl356vKnNxwOWnLd60ixHNPRBglxpv2g7q0Cd3Pmr561gf0HiAcUBRL3S1vPqRC17Zo2CX/9cPkqTIiai1g==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.32.0.tgz", + "integrity": "sha512-VDzNHtLLI5s7xd/VubyS10mq6TxvZBp+4NRWoW+Hi3tgV05RtVm4qK99+dClwTN1McA6PHwob6DEJ6PlXbY83A==", "cpu": [ "x64" ], @@ -732,9 +725,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.31.0.tgz", - "integrity": "sha512-ypB/HMtcSGhKUQNiFwqgdclWNRrAYDH8iMYH4etw/ZlGwiTVxBz2tDrGRrPlfZu6QjXwtd+C3Zib5pFqID97ZA==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.32.0.tgz", + "integrity": "sha512-qcb9qYDlkxz9DxJo7SDhWxTWV1gFuwznjbTiov289pASxlfGbaOD54mgbs9+z94VwrXtKTu+2RqwlSTbiOqxGg==", "cpu": [ "x64" ], @@ -746,9 +739,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.31.0.tgz", - "integrity": "sha512-JuhN2xdI/m8Hr+aVO3vspO7OQfUFO6bKLIRTAy0U15vmWjnZDLrEgCZ2s6+scAYaQVpYSh9tZtRijApw9IXyMw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.32.0.tgz", + "integrity": "sha512-pFDdotFDMXW2AXVbfdUEfidPAk/OtwE/Hd4eYMTNVVaCQ6Yl8et0meDaKNL63L44Haxv4UExpv9ydSf3aSayDg==", "cpu": [ "arm64" ], @@ -760,9 +753,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.31.0.tgz", - "integrity": "sha512-U1xZZXYkvdf5MIWmftU8wrM5PPXzyaY1nGCI4KI4BFfoZxHamsIe+BtnPLIvvPykvQWlVbqUXdLa4aJUuilwLQ==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.32.0.tgz", + "integrity": "sha512-/TG7WfrCAjeRNDvI4+0AAMoHxea/USWhAzf9PVDFHbcqrQ7hMMKp4jZIy4VEjk72AAfN5k4TiSMRXRKf/0akSw==", "cpu": [ "ia32" ], @@ -774,9 +767,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.31.0.tgz", - "integrity": "sha512-ul8rnCsUumNln5YWwz0ted2ZHFhzhRRnkpBZ+YRuHoRAlUji9KChpOUOndY7uykrPEPXVbHLlsdo6v5yXo/TXw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.32.0.tgz", + "integrity": "sha512-5hqO5S3PTEO2E5VjCePxv40gIgyS2KvO7E7/vvC/NbIW4SIRamkMr1hqj+5Y67fbBWv/bQLB6KelBQmXlyCjWA==", "cpu": [ "x64" ], @@ -788,58 +781,78 @@ ] }, "node_modules/@shikijs/core": { - "version": "1.24.3", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.24.3.tgz", - "integrity": "sha512-VRcf4GYUIkxIchGM9DrapRcxtgojg4IWKUtX5EtW+4PJiGzF2xQqZSv27PJt+WLc18KT3CNLpNWow9JYV5n+Rg==", + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.29.1.tgz", + "integrity": "sha512-Mo1gGGkuOYjDu5H8YwzmOuly9vNr8KDVkqj9xiKhhhFS8jisAtDSEWB9hzqRHLVQgFdA310e8XRJcW4tYhRB2A==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/engine-javascript": "1.24.3", - "@shikijs/engine-oniguruma": "1.24.3", - "@shikijs/types": "1.24.3", - "@shikijs/vscode-textmate": "^9.3.1", + "@shikijs/engine-javascript": "1.29.1", + "@shikijs/engine-oniguruma": "1.29.1", + "@shikijs/types": "1.29.1", + "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "node_modules/@shikijs/engine-javascript": { - "version": "1.24.3", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.24.3.tgz", - "integrity": "sha512-De8tNLvYjeK6V0Gb47jIH2M+OKkw+lWnSV1j3HVDFMlNIglmVcTMG2fASc29W0zuFbfEEwKjO8Fe4KYSO6Ce3w==", + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.29.1.tgz", + "integrity": "sha512-Hpi8k9x77rCQ7F/7zxIOUruNkNidMyBnP5qAGbLFqg4kRrg1HZhkB8btib5EXbQWTtLb5gBHOdBwshk20njD7Q==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "1.24.3", - "@shikijs/vscode-textmate": "^9.3.1", - "oniguruma-to-es": "0.8.0" + "@shikijs/types": "1.29.1", + "@shikijs/vscode-textmate": "^10.0.1", + "oniguruma-to-es": "^2.2.0" } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "1.24.3", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.24.3.tgz", - "integrity": "sha512-iNnx950gs/5Nk+zrp1LuF+S+L7SKEhn8k9eXgFYPGhVshKppsYwRmW8tpmAMvILIMSDfrgqZ0w+3xWVQB//1Xw==", + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.29.1.tgz", + "integrity": "sha512-gSt2WhLNgEeLstcweQOSp+C+MhOpTsgdNXRqr3zP6M+BUBZ8Md9OU2BYwUYsALBxHza7hwaIWtFHjQ/aOOychw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "1.29.1", + "@shikijs/vscode-textmate": "^10.0.1" + } + }, + "node_modules/@shikijs/langs": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-1.29.1.tgz", + "integrity": "sha512-iERn4HlyuT044/FgrvLOaZgKVKf3PozjKjyV/RZ5GnlyYEAZFcgwHGkYboeBv2IybQG1KVS/e7VGgiAU4JY2Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "1.29.1" + } + }, + "node_modules/@shikijs/themes": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-1.29.1.tgz", + "integrity": "sha512-lb11zf72Vc9uxkl+aec2oW1HVTHJ2LtgZgumb4Rr6By3y/96VmlU44bkxEb8WBWH3RUtbqAJEN0jljD9cF7H7g==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/types": "1.24.3", - "@shikijs/vscode-textmate": "^9.3.1" + "@shikijs/types": "1.29.1" } }, "node_modules/@shikijs/types": { - "version": "1.24.3", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.24.3.tgz", - "integrity": "sha512-FPMrJ69MNxhRtldRk69CghvaGlbbN3pKRuvko0zvbfa2dXp4pAngByToqS5OY5jvN8D7LKR4RJE8UvzlCOuViw==", + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.29.1.tgz", + "integrity": "sha512-aBqAuhYRp5vSir3Pc9+QPu9WESBOjUo03ao0IHLC4TyTioSsp/SkbAZSrIH4ghYYC1T1KTEpRSBa83bas4RnPA==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/vscode-textmate": "^9.3.1", + "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "node_modules/@shikijs/vscode-textmate": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.1.tgz", - "integrity": "sha512-79QfK1393x9Ho60QFyLti+QfdJzRQCVLFb97kOIV7Eo9vQU/roINgk7m24uv0a7AUvN//RDH36FLjjK48v0s9g==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.1.tgz", + "integrity": "sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==", "dev": true, "license": "MIT" }, @@ -876,18 +889,6 @@ "@types/unist": "*" } }, - "node_modules/@types/node": { - "version": "22.10.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz", - "integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "undici-types": "~6.20.0" - } - }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -896,9 +897,9 @@ "license": "MIT" }, "node_modules/@ungap/structured-clone": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", - "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "dev": true, "license": "ISC" }, @@ -945,6 +946,16 @@ } } }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/@vitest/pretty-format": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", @@ -1253,9 +1264,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "dev": true, "license": "MIT" }, @@ -1299,14 +1310,11 @@ } }, "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } + "license": "MIT" }, "node_modules/expect-type": { "version": "1.1.0", @@ -1331,9 +1339,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz", - "integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", "funding": [ { "type": "github", @@ -1740,15 +1748,15 @@ } }, "node_modules/oniguruma-to-es": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-0.8.0.tgz", - "integrity": "sha512-rY+/a6b+uCgoYIL9itjY0x99UUDHXmGaw7Jjk5ZvM/3cxDJifyxFr/Zm4tTmF6Tre18gAakJo7AzhKUeMNLgHA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-2.3.0.tgz", + "integrity": "sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex-xs": "^1.0.0", - "regex": "^5.0.2", - "regex-recursion": "^5.0.0" + "regex": "^5.1.1", + "regex-recursion": "^5.1.1" } }, "node_modules/p-limit": { @@ -1851,9 +1859,9 @@ } }, "node_modules/postcss": { - "version": "8.4.49", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", - "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "dev": true, "funding": [ { @@ -1871,7 +1879,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", + "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -1911,9 +1919,9 @@ } }, "node_modules/regex": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/regex/-/regex-5.0.2.tgz", - "integrity": "sha512-/pczGbKIQgfTMRV0XjABvc5RzLqQmwqxLHdQao2RTXPk+pmTXB2P0IaUHYdYyk412YLwUIkaeMd5T+RzVgTqnQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/regex/-/regex-5.1.1.tgz", + "integrity": "sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw==", "dev": true, "license": "MIT", "dependencies": { @@ -1921,12 +1929,13 @@ } }, "node_modules/regex-recursion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-5.0.0.tgz", - "integrity": "sha512-UwyOqeobrCCqTXPcsSqH4gDhOjD5cI/b8kjngWgSZbxYh5yVjAwTjO5+hAuPRNiuR70+5RlWSs+U9PVcVcW9Lw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-5.1.1.tgz", + "integrity": "sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==", "dev": true, "license": "MIT", "dependencies": { + "regex": "^5.1.1", "regex-utilities": "^2.3.0" } }, @@ -1947,9 +1956,9 @@ } }, "node_modules/rollup": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.31.0.tgz", - "integrity": "sha512-9cCE8P4rZLx9+PjoyqHLs31V9a9Vpvfo4qNcs6JCiGWYhw2gijSetFbH6SSy1whnkgcefnUwr8sad7tgqsGvnw==", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.32.0.tgz", + "integrity": "sha512-JmrhfQR31Q4AuNBjjAX4s+a/Pu/Q8Q9iwjWBsjRH1q52SPFE2NqRMK6fUZKKnvKO6id+h7JIRf0oYsph53eATg==", "dev": true, "license": "MIT", "dependencies": { @@ -1963,25 +1972,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.31.0", - "@rollup/rollup-android-arm64": "4.31.0", - "@rollup/rollup-darwin-arm64": "4.31.0", - "@rollup/rollup-darwin-x64": "4.31.0", - "@rollup/rollup-freebsd-arm64": "4.31.0", - "@rollup/rollup-freebsd-x64": "4.31.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.31.0", - "@rollup/rollup-linux-arm-musleabihf": "4.31.0", - "@rollup/rollup-linux-arm64-gnu": "4.31.0", - "@rollup/rollup-linux-arm64-musl": "4.31.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.31.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.31.0", - "@rollup/rollup-linux-riscv64-gnu": "4.31.0", - "@rollup/rollup-linux-s390x-gnu": "4.31.0", - "@rollup/rollup-linux-x64-gnu": "4.31.0", - "@rollup/rollup-linux-x64-musl": "4.31.0", - "@rollup/rollup-win32-arm64-msvc": "4.31.0", - "@rollup/rollup-win32-ia32-msvc": "4.31.0", - "@rollup/rollup-win32-x64-msvc": "4.31.0", + "@rollup/rollup-android-arm-eabi": "4.32.0", + "@rollup/rollup-android-arm64": "4.32.0", + "@rollup/rollup-darwin-arm64": "4.32.0", + "@rollup/rollup-darwin-x64": "4.32.0", + "@rollup/rollup-freebsd-arm64": "4.32.0", + "@rollup/rollup-freebsd-x64": "4.32.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.32.0", + "@rollup/rollup-linux-arm-musleabihf": "4.32.0", + "@rollup/rollup-linux-arm64-gnu": "4.32.0", + "@rollup/rollup-linux-arm64-musl": "4.32.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.32.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.32.0", + "@rollup/rollup-linux-riscv64-gnu": "4.32.0", + "@rollup/rollup-linux-s390x-gnu": "4.32.0", + "@rollup/rollup-linux-x64-gnu": "4.32.0", + "@rollup/rollup-linux-x64-musl": "4.32.0", + "@rollup/rollup-win32-arm64-msvc": "4.32.0", + "@rollup/rollup-win32-ia32-msvc": "4.32.0", + "@rollup/rollup-win32-x64-msvc": "4.32.0", "fsevents": "~2.3.2" } }, @@ -2048,17 +2057,19 @@ } }, "node_modules/shiki": { - "version": "1.24.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.24.3.tgz", - "integrity": "sha512-eMeX/ehE2IDKVs71kB4zVcDHjutNcOtm+yIRuR4sA6ThBbdFI0DffGJiyoKCodj0xRGxIoWC3pk/Anmm5mzHmA==", + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.29.1.tgz", + "integrity": "sha512-TghWKV9pJTd/N+IgAIVJtr0qZkB7FfFCUrrEJc0aRmZupo3D1OCVRknQWVRVA7AX/M0Ld7QfoAruPzr3CnUJuw==", "dev": true, "license": "MIT", "dependencies": { - "@shikijs/core": "1.24.3", - "@shikijs/engine-javascript": "1.24.3", - "@shikijs/engine-oniguruma": "1.24.3", - "@shikijs/types": "1.24.3", - "@shikijs/vscode-textmate": "^9.3.1", + "@shikijs/core": "1.29.1", + "@shikijs/engine-javascript": "1.29.1", + "@shikijs/engine-oniguruma": "1.29.1", + "@shikijs/langs": "1.29.1", + "@shikijs/themes": "1.29.1", + "@shikijs/types": "1.29.1", + "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, @@ -2174,9 +2185,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", - "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", "dev": true, "license": "MIT" }, @@ -2273,15 +2284,6 @@ "dev": true, "license": "MIT" }, - "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", @@ -2396,9 +2398,9 @@ } }, "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", "dev": true, "license": "MIT", "dependencies": { @@ -2562,9 +2564,9 @@ } }, "node_modules/yaml": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", - "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, "license": "ISC", "bin": { diff --git a/package.json b/package.json index 2ced166..216a624 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@graffiti-garden/api", - "version": "0.1.8", + "version": "0.1.9", "description": "The heart of Graffiti", "types": "./dist/src/index.d.ts", "module": "./dist/index.js", diff --git a/src/2-types.ts b/src/2-types.ts index 475da4a..79450ff 100644 --- a/src/2-types.ts +++ b/src/2-types.ts @@ -297,8 +297,17 @@ export type GraffitiLoginEvent = CustomEvent< * or when their session times out or otherwise becomes invalid. * The event name to listen for is `logout`. */ -export type GraffitiLogoutEvent = CustomEvent<{ - actor: string; - state?: string; - error?: Error; -}>; +export type GraffitiLogoutEvent = CustomEvent< + { + state?: string; + } & ( + | { + error: Error; + actor?: string; + } + | { + error?: undefined; + actor: string; + } + ) +>; diff --git a/src/3-errors.ts b/src/3-errors.ts index 12f64d6..b399523 100644 --- a/src/3-errors.ts +++ b/src/3-errors.ts @@ -61,11 +61,3 @@ export class GraffitiErrorInvalidUri extends Error { Object.setPrototypeOf(this, GraffitiErrorInvalidUri.prototype); } } - -export class GraffitiErrorOther extends Error { - constructor(message?: string) { - super(message); - this.name = "GraffitiErrorOther"; - Object.setPrototypeOf(this, GraffitiErrorOther.prototype); - } -} diff --git a/tests/src/crud.ts b/tests/src/crud.ts index 7372c16..f218672 100644 --- a/tests/src/crud.ts +++ b/tests/src/crud.ts @@ -19,446 +19,458 @@ export const graffitiCRUDTests = ( useSession1: () => GraffitiSession, useSession2: () => GraffitiSession, ) => { - describe("CRUD", () => { - it("put, get, delete", async () => { - const graffiti = useGraffiti(); - const session = useSession1(); - const value = { - something: "hello, world~ c:", - }; - const channels = [randomString(), randomString()]; - - // Put the object - const previous = await graffiti.put({ value, channels }, session); - expect(previous.value).toEqual({}); - expect(previous.channels).toEqual([]); - expect(previous.allowed).toBeUndefined(); - expect(previous.actor).toEqual(session.actor); - - // Get it back - const gotten = await graffiti.get(previous, {}); - expect(gotten.value).toEqual(value); - expect(gotten.channels).toEqual([]); - expect(gotten.allowed).toBeUndefined(); - expect(gotten.name).toEqual(previous.name); - expect(gotten.actor).toEqual(previous.actor); - expect(gotten.source).toEqual(previous.source); - expect(gotten.lastModified).toEqual(previous.lastModified); - - // Replace it - const newValue = { - something: "goodbye, world~ :c", - }; - const beforeReplaced = await graffiti.put( - { ...previous, value: newValue, channels: [] }, - session, - ); - expect(beforeReplaced.value).toEqual(value); - expect(beforeReplaced.tombstone).toEqual(true); - expect(beforeReplaced.name).toEqual(previous.name); - expect(beforeReplaced.actor).toEqual(previous.actor); - expect(beforeReplaced.source).toEqual(previous.source); - expect(beforeReplaced.lastModified).toBeGreaterThanOrEqual( - gotten.lastModified, - ); - - // Get it again - const afterReplaced = await graffiti.get(previous, {}); - expect(afterReplaced.value).toEqual(newValue); - expect(afterReplaced.lastModified).toEqual(beforeReplaced.lastModified); - expect(afterReplaced.tombstone).toEqual(false); - - // Delete it - const beforeDeleted = await graffiti.delete(afterReplaced, session); - expect(beforeDeleted.tombstone).toEqual(true); - expect(beforeDeleted.value).toEqual(newValue); - expect(beforeDeleted.lastModified).toBeGreaterThanOrEqual( - beforeReplaced.lastModified, - ); - - // Try to get it and fail - await expect(graffiti.get(afterReplaced, {})).rejects.toThrow( - GraffitiErrorNotFound, - ); - }); - - it("put, get, delete with wrong actor", async () => { - const graffiti = useGraffiti(); - const session1 = useSession1(); - const session2 = useSession2(); - - await expect( - graffiti.put( - { value: {}, channels: [], actor: session2.actor }, - session1, - ), - ).rejects.toThrow(GraffitiErrorForbidden); + describe( + "CRUD", + { + timeout: 20000, + }, + () => { + it("put, get, delete", async () => { + const graffiti = useGraffiti(); + const session = useSession1(); + const value = { + something: "hello, world~ c:", + }; + const channels = [randomString(), randomString()]; + + // Put the object + const previous = await graffiti.put({ value, channels }, session); + expect(previous.value).toEqual({}); + expect(previous.channels).toEqual([]); + expect(previous.allowed).toBeUndefined(); + expect(previous.actor).toEqual(session.actor); + + // Get it back + const gotten = await graffiti.get(previous, {}); + expect(gotten.value).toEqual(value); + expect(gotten.channels).toEqual([]); + expect(gotten.allowed).toBeUndefined(); + expect(gotten.name).toEqual(previous.name); + expect(gotten.actor).toEqual(previous.actor); + expect(gotten.source).toEqual(previous.source); + expect(gotten.lastModified).toEqual(previous.lastModified); + + // Replace it + const newValue = { + something: "goodbye, world~ :c", + }; + const beforeReplaced = await graffiti.put( + { ...previous, value: newValue, channels: [] }, + session, + ); + expect(beforeReplaced.value).toEqual(value); + expect(beforeReplaced.tombstone).toEqual(true); + expect(beforeReplaced.name).toEqual(previous.name); + expect(beforeReplaced.actor).toEqual(previous.actor); + expect(beforeReplaced.source).toEqual(previous.source); + expect(beforeReplaced.lastModified).toBeGreaterThanOrEqual( + gotten.lastModified, + ); - const putted = await graffiti.put({ value: {}, channels: [] }, session2); + // Get it again + const afterReplaced = await graffiti.get(previous, {}); + expect(afterReplaced.value).toEqual(newValue); + expect(afterReplaced.lastModified).toEqual(beforeReplaced.lastModified); + expect(afterReplaced.tombstone).toEqual(false); + + // Delete it + const beforeDeleted = await graffiti.delete(afterReplaced, session); + expect(beforeDeleted.tombstone).toEqual(true); + expect(beforeDeleted.value).toEqual(newValue); + expect(beforeDeleted.lastModified).toBeGreaterThanOrEqual( + beforeReplaced.lastModified, + ); - await expect(graffiti.delete(putted, session1)).rejects.toThrow( - GraffitiErrorForbidden, - ); + // Try to get it and fail + await expect(graffiti.get(afterReplaced, {})).rejects.toThrow( + GraffitiErrorNotFound, + ); + }); - await expect(graffiti.patch({}, putted, session1)).rejects.toThrow( - GraffitiErrorForbidden, - ); - }); + it("put, get, delete with wrong actor", async () => { + const graffiti = useGraffiti(); + const session1 = useSession1(); + const session2 = useSession2(); + + await expect( + graffiti.put( + { value: {}, channels: [], actor: session2.actor }, + session1, + ), + ).rejects.toThrow(GraffitiErrorForbidden); + + const putted = await graffiti.put( + { value: {}, channels: [] }, + session2, + ); - it("put and get with schema", async () => { - const graffiti = useGraffiti(); - const session = useSession1(); + await expect(graffiti.delete(putted, session1)).rejects.toThrow( + GraffitiErrorForbidden, + ); - const schema = { - properties: { - value: { - properties: { - something: { - type: "string", - }, - another: { - type: "integer", - }, - }, - }, - }, - } as const; - - const goodValue = { - something: "hello", - another: 42, - } as const; - - const putted = await graffiti.put( - { - value: goodValue, - channels: [], - }, - session, - ); - - const gotten = await graffiti.get(putted, schema); - expect(gotten.value.something).toEqual(goodValue.something); - expect(gotten.value.another).toEqual(goodValue.another); - }); - - it("put and get with invalid schema", async () => { - const graffiti = useGraffiti(); - const session = useSession1(); - - const putted = await graffiti.put({ value: {}, channels: [] }, session); - await expect( - graffiti.get(putted, { - properties: { - value: { - //@ts-ignore - type: "asdf", - }, - }, - }), - ).rejects.toThrow(GraffitiErrorInvalidSchema); - }); - - it("put and get with wrong schema", async () => { - const graffiti = useGraffiti(); - const session = useSession1(); - - const putted = await graffiti.put( - { - value: { - hello: "world", - }, - channels: [], - }, - session, - ); + await expect(graffiti.patch({}, putted, session1)).rejects.toThrow( + GraffitiErrorForbidden, + ); + }); - await expect( - graffiti.get(putted, { + it("put and get with schema", async () => { + const graffiti = useGraffiti(); + const session = useSession1(); + + const schema = { properties: { value: { properties: { - hello: { - type: "number", + something: { + type: "string", + }, + another: { + type: "integer", }, }, }, }, - }), - ).rejects.toThrow(GraffitiErrorSchemaMismatch); - }); - - it("put and get with empty access control", async () => { - const graffiti = useGraffiti(); - const session1 = useSession1(); - const session2 = useSession2(); - - const value = { - um: "hi", - }; - const allowed = [randomString()]; - const channels = [randomString()]; - const putted = await graffiti.put({ value, allowed, channels }, session1); - - // Get it with authenticated session - const gotten = await graffiti.get(putted, {}, session1); - expect(gotten.value).toEqual(value); - expect(gotten.allowed).toEqual(allowed); - expect(gotten.channels).toEqual(channels); - - // But not without session - await expect(graffiti.get(putted, {})).rejects.toThrow(); - - // Or the wrong session - await expect(graffiti.get(putted, {}, session2)).rejects.toThrow(); - }); - - it("put and get with specific access control", async () => { - const graffiti = useGraffiti(); - const session1 = useSession1(); - const session2 = useSession2(); - - const value = { - um: "hi", - }; - const allowed = [randomString(), session2.actor, randomString()]; - const channels = [randomString()]; - const putted = await graffiti.put( - { - value, - allowed, - channels, - }, - session1, - ); - - // Get it with authenticated session - const gotten = await graffiti.get(putted, {}, session1); - expect(gotten.value).toEqual(value); - expect(gotten.allowed).toEqual(allowed); - expect(gotten.channels).toEqual(channels); - - // But not without session - await expect(graffiti.get(putted, {})).rejects.toThrow(); - - const gotten2 = await graffiti.get(putted, {}, session2); - expect(gotten2.value).toEqual(value); - // They should only see that is is private to them - expect(gotten2.allowed).toEqual([session2.actor]); - // And not see any channels - expect(gotten2.channels).toEqual([]); - }); - - it("patch value", async () => { - const graffiti = useGraffiti(); - const session = useSession1(); - - const value = { - something: "hello, world~ c:", - }; - const putted = await graffiti.put({ value, channels: [] }, session); - - const patch: GraffitiPatch = { - value: [ - { op: "replace", path: "/something", value: "goodbye, world~ :c" }, - ], - }; - const beforePatched = await graffiti.patch(patch, putted, session); - expect(beforePatched.value).toEqual(value); - expect(beforePatched.tombstone).toBe(true); - - const gotten = await graffiti.get(putted, {}); - expect(gotten.value).toEqual({ - something: "goodbye, world~ :c", + } as const; + + const goodValue = { + something: "hello", + another: 42, + } as const; + + const putted = await graffiti.put( + { + value: goodValue, + channels: [], + }, + session, + ); + + const gotten = await graffiti.get(putted, schema); + expect(gotten.value.something).toEqual(goodValue.something); + expect(gotten.value.another).toEqual(goodValue.another); }); - expect(beforePatched.lastModified).toBe(gotten.lastModified); - await graffiti.delete(putted, session); - }); + it("put and get with invalid schema", async () => { + const graffiti = useGraffiti(); + const session = useSession1(); + + const putted = await graffiti.put({ value: {}, channels: [] }, session); + await expect( + graffiti.get(putted, { + properties: { + value: { + //@ts-ignore + type: "asdf", + }, + }, + }), + ).rejects.toThrow(GraffitiErrorInvalidSchema); + }); - it("deep patch", async () => { - const graffiti = useGraffiti(); - const session = useSession1(); + it("put and get with wrong schema", async () => { + const graffiti = useGraffiti(); + const session = useSession1(); - const value = { - something: { - another: { - somethingElse: "hello", - }, - }, - }; - const putted = await graffiti.put( - { value: value, channels: [] }, - session, - ); - - const beforePatch = await graffiti.patch( - { - value: [ - { - op: "replace", - path: "/something/another/somethingElse", - value: "goodbye", + const putted = await graffiti.put( + { + value: { + hello: "world", }, - ], - }, - putted, - session, - ); - const gotten = await graffiti.get(putted, {}); - - expect(beforePatch.value).toEqual(value); - expect(gotten.value).toEqual({ - something: { - another: { - somethingElse: "goodbye", + channels: [], }, - }, + session, + ); + + await expect( + graffiti.get(putted, { + properties: { + value: { + properties: { + hello: { + type: "number", + }, + }, + }, + }, + }), + ).rejects.toThrow(GraffitiErrorSchemaMismatch); }); - }); - - it("patch channels", async () => { - const graffiti = useGraffiti(); - const session = useSession1(); - - const channelsBefore = [randomString()]; - const channelsAfter = [randomString()]; - - const putted = await graffiti.put( - { value: {}, channels: channelsBefore }, - session, - ); - - const patch: GraffitiPatch = { - channels: [{ op: "replace", path: "/0", value: channelsAfter[0] }], - }; - const patched = await graffiti.patch(patch, putted, session); - expect(patched.channels).toEqual(channelsBefore); - const gotten = await graffiti.get(putted, {}, session); - expect(gotten.channels).toEqual(channelsAfter); - await graffiti.delete(putted, session); - }); - - it("patch 'increment' with test", async () => { - const graffiti = useGraffiti(); - const session = useSession1(); - - const putted = await graffiti.put( - { - value: { - counter: 1, + + it("put and get with empty access control", async () => { + const graffiti = useGraffiti(); + const session1 = useSession1(); + const session2 = useSession2(); + + const value = { + um: "hi", + }; + const allowed = [randomString()]; + const channels = [randomString()]; + const putted = await graffiti.put( + { value, allowed, channels }, + session1, + ); + + // Get it with authenticated session + const gotten = await graffiti.get(putted, {}, session1); + expect(gotten.value).toEqual(value); + expect(gotten.allowed).toEqual(allowed); + expect(gotten.channels).toEqual(channels); + + // But not without session + await expect(graffiti.get(putted, {})).rejects.toThrow(); + + // Or the wrong session + await expect(graffiti.get(putted, {}, session2)).rejects.toThrow(); + }); + + it("put and get with specific access control", async () => { + const graffiti = useGraffiti(); + const session1 = useSession1(); + const session2 = useSession2(); + + const value = { + um: "hi", + }; + const allowed = [randomString(), session2.actor, randomString()]; + const channels = [randomString()]; + const putted = await graffiti.put( + { + value, + allowed, + channels, }, - channels: [], - }, - session, - ); + session1, + ); + + // Get it with authenticated session + const gotten = await graffiti.get(putted, {}, session1); + expect(gotten.value).toEqual(value); + expect(gotten.allowed).toEqual(allowed); + expect(gotten.channels).toEqual(channels); + + // But not without session + await expect(graffiti.get(putted, {})).rejects.toThrow(); + + const gotten2 = await graffiti.get(putted, {}, session2); + expect(gotten2.value).toEqual(value); + // They should only see that is is private to them + expect(gotten2.allowed).toEqual([session2.actor]); + // And not see any channels + expect(gotten2.channels).toEqual([]); + }); + + it("patch value", async () => { + const graffiti = useGraffiti(); + const session = useSession1(); - const previous = await graffiti.patch( - { + const value = { + something: "hello, world~ c:", + }; + const putted = await graffiti.put({ value, channels: [] }, session); + + const patch: GraffitiPatch = { value: [ - { op: "test", path: "/counter", value: 1 }, - { op: "replace", path: "/counter", value: 2 }, + { op: "replace", path: "/something", value: "goodbye, world~ :c" }, ], - }, - putted, - session, - ); - expect(previous.value).toEqual({ counter: 1 }); - const result = await graffiti.get(previous, { - properties: { - value: { - properties: { - counter: { - type: "integer", - }, + }; + const beforePatched = await graffiti.patch(patch, putted, session); + expect(beforePatched.value).toEqual(value); + expect(beforePatched.tombstone).toBe(true); + + const gotten = await graffiti.get(putted, {}); + expect(gotten.value).toEqual({ + something: "goodbye, world~ :c", + }); + expect(beforePatched.lastModified).toBe(gotten.lastModified); + + await graffiti.delete(putted, session); + }); + + it("deep patch", async () => { + const graffiti = useGraffiti(); + const session = useSession1(); + + const value = { + something: { + another: { + somethingElse: "hello", }, }, - }, - }); - expect(result.value.counter).toEqual(2); + }; + const putted = await graffiti.put( + { value: value, channels: [] }, + session, + ); - await expect( - graffiti.patch( + const beforePatch = await graffiti.patch( { value: [ - { op: "test", path: "/counter", value: 1 }, - { op: "replace", path: "/counter", value: 3 }, + { + op: "replace", + path: "/something/another/somethingElse", + value: "goodbye", + }, ], }, putted, session, - ), - ).rejects.toThrow(GraffitiErrorPatchTestFailed); - }); - - it("invalid patch", async () => { - const graffiti = useGraffiti(); - const session = useSession1(); - const object = randomPutObject(); - const putted = await graffiti.put(object, session); - - await expect( - graffiti.patch( + ); + const gotten = await graffiti.get(putted, {}); + + expect(beforePatch.value).toEqual(value); + expect(gotten.value).toEqual({ + something: { + another: { + somethingElse: "goodbye", + }, + }, + }); + }); + + it("patch channels", async () => { + const graffiti = useGraffiti(); + const session = useSession1(); + + const channelsBefore = [randomString()]; + const channelsAfter = [randomString()]; + + const putted = await graffiti.put( + { value: {}, channels: channelsBefore }, + session, + ); + + const patch: GraffitiPatch = { + channels: [{ op: "replace", path: "/0", value: channelsAfter[0] }], + }; + const patched = await graffiti.patch(patch, putted, session); + expect(patched.channels).toEqual(channelsBefore); + const gotten = await graffiti.get(putted, {}, session); + expect(gotten.channels).toEqual(channelsAfter); + await graffiti.delete(putted, session); + }); + + it("patch 'increment' with test", async () => { + const graffiti = useGraffiti(); + const session = useSession1(); + + const putted = await graffiti.put( + { + value: { + counter: 1, + }, + channels: [], + }, + session, + ); + + const previous = await graffiti.patch( { value: [ - { op: "add", path: "/root", value: [] }, - { op: "add", path: "/root/2", value: 2 }, // out of bounds + { op: "test", path: "/counter", value: 1 }, + { op: "replace", path: "/counter", value: 2 }, ], }, putted, session, - ), - ).rejects.toThrow(GraffitiErrorPatchError); - }); - - it("patch channels to be wrong", async () => { - const graffiti = useGraffiti(); - const session = useSession1(); - const object = randomPutObject(); - object.allowed = [randomString()]; - const putted = await graffiti.put(object, session); - - const patches: GraffitiPatch[] = [ - { - channels: [{ op: "replace", path: "", value: null }], - }, - { - channels: [{ op: "replace", path: "", value: {} }], - }, - { - channels: [{ op: "replace", path: "", value: ["hello", ["hi"]] }], - }, - { - channels: [{ op: "add", path: "/0", value: 1 }], - }, - { - value: [{ op: "replace", path: "", value: "not an object" }], - }, - { - value: [{ op: "replace", path: "", value: null }], - }, - { - value: [{ op: "replace", path: "", value: [] }], - }, - { - allowed: [{ op: "replace", path: "", value: {} }], - }, - { - allowed: [{ op: "replace", path: "", value: ["hello", ["hi"]] }], - }, - ]; - - for (const patch of patches) { - await expect(graffiti.patch(patch, putted, session)).rejects.toThrow( - GraffitiErrorPatchError, ); - } - - const gotten = await graffiti.get(putted, {}, session); - expect(gotten.value).toEqual(object.value); - expect(gotten.channels).toEqual(object.channels); - expect(gotten.allowed).toEqual(object.allowed); - expect(gotten.lastModified).toEqual(putted.lastModified); - }); - }); + expect(previous.value).toEqual({ counter: 1 }); + const result = await graffiti.get(previous, { + properties: { + value: { + properties: { + counter: { + type: "integer", + }, + }, + }, + }, + }); + expect(result.value.counter).toEqual(2); + + await expect( + graffiti.patch( + { + value: [ + { op: "test", path: "/counter", value: 1 }, + { op: "replace", path: "/counter", value: 3 }, + ], + }, + putted, + session, + ), + ).rejects.toThrow(GraffitiErrorPatchTestFailed); + }); + + it("invalid patch", async () => { + const graffiti = useGraffiti(); + const session = useSession1(); + const object = randomPutObject(); + const putted = await graffiti.put(object, session); + + await expect( + graffiti.patch( + { + value: [ + { op: "add", path: "/root", value: [] }, + { op: "add", path: "/root/2", value: 2 }, // out of bounds + ], + }, + putted, + session, + ), + ).rejects.toThrow(GraffitiErrorPatchError); + }); + + it("patch channels to be wrong", async () => { + const graffiti = useGraffiti(); + const session = useSession1(); + const object = randomPutObject(); + object.allowed = [randomString()]; + const putted = await graffiti.put(object, session); + + const patches: GraffitiPatch[] = [ + { + channels: [{ op: "replace", path: "", value: null }], + }, + { + channels: [{ op: "replace", path: "", value: {} }], + }, + { + channels: [{ op: "replace", path: "", value: ["hello", ["hi"]] }], + }, + { + channels: [{ op: "add", path: "/0", value: 1 }], + }, + { + value: [{ op: "replace", path: "", value: "not an object" }], + }, + { + value: [{ op: "replace", path: "", value: null }], + }, + { + value: [{ op: "replace", path: "", value: [] }], + }, + { + allowed: [{ op: "replace", path: "", value: {} }], + }, + { + allowed: [{ op: "replace", path: "", value: ["hello", ["hi"]] }], + }, + ]; + + for (const patch of patches) { + await expect(graffiti.patch(patch, putted, session)).rejects.toThrow( + GraffitiErrorPatchError, + ); + } + + const gotten = await graffiti.get(putted, {}, session); + expect(gotten.value).toEqual(object.value); + expect(gotten.channels).toEqual(object.channels); + expect(gotten.allowed).toEqual(object.allowed); + expect(gotten.lastModified).toEqual(putted.lastModified); + }); + }, + ); }; diff --git a/tests/src/discover.ts b/tests/src/discover.ts index 4c2f2fe..4c6a389 100644 --- a/tests/src/discover.ts +++ b/tests/src/discover.ts @@ -11,7 +11,7 @@ export const graffitiDiscoverTests = ( useSession1: () => GraffitiSession, useSession2: () => GraffitiSession, ) => { - describe("discover", () => { + describe("discover", { timeout: 20000 }, () => { it("discover nothing", async () => { const graffiti = useGraffiti(); const iterator = graffiti.discover([], {});