Update docs to astro6 and update JS dependencies.

This commit is contained in:
Sebastian Jeltsch 2026-03-18 20:30:26 +01:00
parent 0da2d46369
commit 61eb0734a9
28 changed files with 2707 additions and 2913 deletions

View file

@ -43,9 +43,12 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- uses: actions/setup-node@v6
with:
node-version: 22
- uses: pnpm/action-setup@v4
with:
version: 9
version: 10
- name: PNPM install
run: pnpm install
@ -89,9 +92,12 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- uses: actions/setup-node@v6
with:
node-version: 22
- uses: pnpm/action-setup@v4
with:
version: 9
version: 10
- name: PNPM install
run: pnpm install
@ -240,9 +246,12 @@ jobs:
run: |
sudo apt-get update && \
sudo apt-get install -y --no-install-recommends curl libssl-dev pkg-config libclang-dev protobuf-compiler libprotobuf-dev zip
- uses: actions/setup-node@v6
with:
node-version: 22
- uses: pnpm/action-setup@v4
with:
version: 9
version: 10
- name: PNPM install
run: pnpm install
- uses: actions-rs/toolchain@v1

View file

@ -42,9 +42,12 @@ jobs:
- name: Install Poetry and Python Dependencies
run: |
pipx install --python python3.13 "poetry==2.1.3" && poetry -C client/python install
- uses: actions/setup-node@v6
with:
node-version: 22
- uses: pnpm/action-setup@v4
with:
version: 9
version: 10
- name: PNPM install
run: |
pnpm i

View file

@ -15,13 +15,13 @@
"trailbase-wasm": "workspace:*"
},
"devDependencies": {
"@bytecodealliance/jco": "^1.17.0",
"@bytecodealliance/jco": "^1.17.2",
"@eslint/js": "^10.0.1",
"@types/node": "^25.2.3",
"eslint": "^10.0.0",
"@types/node": "^25.5.0",
"eslint": "^10.0.3",
"prettier": "^3.8.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"typescript-eslint": "^8.57.1",
"vite": "^7.3.1"
}
}

View file

@ -66,6 +66,8 @@ export default [
varsIgnorePattern: "^_",
},
],
// http://eslint.org/docs/rules/no-unassigned-vars
"no-unassigned-vars": "warn",
},
languageOptions: { globals: globals.browser },
},

View file

@ -13,12 +13,12 @@
"test": "vitest run"
},
"dependencies": {
"@antv/x6": "^3.1.6",
"@antv/x6": "^3.1.7",
"@bufbuild/protobuf": "^2.11.0",
"@codemirror/autocomplete": "^6.20.0",
"@codemirror/autocomplete": "^6.20.1",
"@codemirror/lang-sql": "^6.10.0",
"@codemirror/state": "^6.5.4",
"@codemirror/view": "^6.39.14",
"@codemirror/state": "^6.6.0",
"@codemirror/view": "^6.40.0",
"@corvu/resizable": "^0.2.5",
"@kobalte/core": "^0.13.11",
"@kobalte/tailwindcss": "^0.9.0",
@ -26,10 +26,10 @@
"@nanostores/persistent": "^1.3.3",
"@nanostores/solid": "^1.1.1",
"@panzoom/panzoom": "^4.6.1",
"@solid-primitives/memo": "^1.4.3",
"@solidjs/router": "^0.15.4",
"@tanstack/solid-form": "^1.28.3",
"@tanstack/solid-query": "^5.90.23",
"@solid-primitives/memo": "^1.4.5",
"@solidjs/router": "^0.16.1",
"@tanstack/solid-form": "^1.28.5",
"@tanstack/solid-query": "^5.91.1",
"@tanstack/solid-table": "^8.21.3",
"@tanstack/table-core": "^8.21.3",
"@terraformer/wkt": "^2.2.1",
@ -40,43 +40,43 @@
"geojson": "^0.5.0",
"i18n-iso-countries": "^7.14.0",
"long": "^5.3.2",
"maplibre-gl": "^5.18.0",
"nanostores": "^1.1.0",
"maplibre-gl": "^5.20.2",
"nanostores": "^1.2.0",
"protobufjs": "^8.0.0",
"solid-icons": "^1.2.0",
"solid-js": "^1.9.11",
"tailwind-merge": "^3.4.1",
"tailwind-merge": "^3.5.0",
"trailbase": "file:../client",
"uuid": "^13.0.0"
},
"devDependencies": {
"@eslint/js": "^9.39.2",
"@iconify-json/tabler": "^1.2.26",
"@eslint/js": "^10.0.1",
"@iconify-json/tabler": "^1.2.31",
"@solidjs/testing-library": "^0.8.10",
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.2.0",
"@tailwindcss/vite": "^4.2.2",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/user-event": "^14.6.1",
"@types/geojson": "^7946.0.16",
"@types/terraformer__wkt": "^2.0.3",
"@types/wicg-file-system-access": "^2023.10.7",
"autoprefixer": "^10.4.24",
"eslint": "^9.39.2",
"eslint-plugin-better-tailwindcss": "^4.3.0",
"autoprefixer": "^10.4.27",
"eslint": "^10.0.3",
"eslint-plugin-better-tailwindcss": "^4.3.2",
"eslint-plugin-solid": "^0.14.5",
"globals": "^17.3.0",
"jsdom": "^28.1.0",
"globals": "^17.4.0",
"jsdom": "^29.0.0",
"prettier": "^3.8.1",
"prettier-plugin-tailwindcss": "^0.7.2",
"tailwindcss": "^4.2.0",
"tailwindcss": "^4.2.2",
"tailwindcss-animate": "^1.0.7",
"ts-proto": "^2.11.2",
"ts-proto": "^2.11.5",
"tw-animate-css": "^1.4.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"typescript-eslint": "^8.57.1",
"vite": "^7.3.1",
"vite-plugin-csp-guard": "^3.0.0",
"vite-plugin-solid": "^2.11.10",
"vite-plugin-solid": "^2.11.11",
"vite-tsconfig-paths": "6.1.1",
"vitest": "^3.2.4"
}

View file

@ -36,19 +36,19 @@
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"eslint": "^10.0.0",
"globals": "^17.3.0",
"eslint": "^10.0.3",
"globals": "^17.4.0",
"http-status": "^2.1.0",
"jsdom": "^28.1.0",
"jsdom": "^29.0.0",
"nano-spawn": "^2.0.0",
"oauth2-mock-server": "^8.2.1",
"oauth2-mock-server": "^8.2.2",
"otplib": "^13.3.0",
"prettier": "^3.8.1",
"tinybench": "^6.0.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"typescript-eslint": "^8.57.1",
"vite-node": "^5.3.0",
"vitest": "^4.0.18"
"vitest": "^4.1.0"
},
"dependencies": {
"@types/geojson": "^7946.0.16",

View file

@ -63,6 +63,8 @@ export default [
varsIgnorePattern: "^_",
},
],
// http://eslint.org/docs/rules/no-unassigned-vars
"no-unassigned-vars": "warn",
// Collides with astro, we'd have to configure the solid plugin to ignore astro files.
"solid/no-unknown-namespaces": "off",
// Prettier prefers explicit closing.

View file

@ -12,39 +12,39 @@
"format": "prettier -w ."
},
"dependencies": {
"@astrojs/check": "^0.9.6",
"@astrojs/solid-js": "^5.1.3",
"@astrojs/check": "^0.9.8",
"@astrojs/solid-js": "^6.0.1",
"@kobalte/core": "^0.13.11",
"@nanostores/solid": "^1.1.1",
"astro": "^5.17.3",
"astro": "^6.0.6",
"astro-icon": "^1.1.5",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"nanostores": "^1.1.0",
"nanostores": "^1.2.0",
"solid-icons": "^1.2.0",
"solid-js": "^1.9.11",
"tailwind-merge": "^3.4.1",
"tailwind-merge": "^3.5.0",
"tailwindcss-animate": "^1.0.7",
"trailbase": "file:../../assets/js/client"
},
"devDependencies": {
"@eslint/js": "^9.39.2",
"@iconify-json/tabler": "^1.2.26",
"@eslint/js": "^10.0.1",
"@iconify-json/tabler": "^1.2.31",
"@kobalte/tailwindcss": "^0.9.0",
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.2.0",
"eslint": "^9.39.2",
"@tailwindcss/vite": "^4.2.2",
"eslint": "^10.0.3",
"eslint-plugin-astro": "^1.6.0",
"eslint-plugin-better-tailwindcss": "^4.3.0",
"eslint-plugin-better-tailwindcss": "^4.3.2",
"eslint-plugin-solid": "^0.14.5",
"globals": "^17.3.0",
"globals": "^17.4.0",
"prettier": "^3.8.1",
"prettier-plugin-astro": "^0.14.1",
"prettier-plugin-tailwindcss": "^0.7.2",
"sharp": "^0.34.5",
"tailwindcss": "^4.2.0",
"tailwindcss": "^4.2.2",
"tw-animate-css": "^1.4.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0"
"typescript-eslint": "^8.57.1"
}
}

View file

@ -79,6 +79,8 @@ export default [
varsIgnorePattern: "^_",
},
],
// http://eslint.org/docs/rules/no-unassigned-vars
"no-unassigned-vars": "warn",
// Collides with astro, we'd have to configure the solid plugin to ignore astro files.
"solid/no-unknown-namespaces": "off",
// Needed for astro.config.ts @ts-ignore in because @ts-expect-error doesn't work reliably across envs.

View file

@ -9,12 +9,12 @@
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@types/node": "^25.2.3",
"eslint": "^10.0.0",
"@types/node": "^25.5.0",
"eslint": "^10.0.3",
"prettier": "^3.8.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"vitest": "^4.0.18"
"typescript-eslint": "^8.57.1",
"vitest": "^4.1.0"
},
"dependencies": {
"trailbase": "workspace:*"

View file

@ -15,15 +15,15 @@
"trailbase-wasm": "workspace:*"
},
"devDependencies": {
"@bytecodealliance/jco": "^1.17.0",
"@bytecodealliance/jco": "^1.17.2",
"@eslint/js": "^10.0.1",
"@types/node": "^25.2.3",
"@types/node": "^25.5.0",
"commander": "^14.0.3",
"eslint": "^10.0.0",
"eslint": "^10.0.3",
"nano-spawn": "^2.0.0",
"prettier": "^3.8.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"typescript-eslint": "^8.57.1",
"vite": "^7.3.1"
}
}

View file

@ -48,7 +48,10 @@
"operationId": "change_email_confirm_handler",
"responses": {
"200": {
"description": "Success."
"description": "Success, when redirect_uri is not present."
},
"303": {
"description": "Success, when redirect_uri is present."
}
}
}
@ -58,6 +61,26 @@
"tags": ["auth"],
"summary": "Request an email change.",
"operationId": "change_email_request_handler",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"description": "Success (and error if err_redirect_uri not present) redirect target for non-JSON requests.",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "err_redirect_uri",
"in": "query",
"description": "Error redirect target for non-JSON requests.",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"requestBody": {
"content": {
"application/json": {
@ -70,7 +93,19 @@
},
"responses": {
"200": {
"description": "Success."
"description": "Success, when redirect_uri is not present and JSON input"
},
"303": {
"description": "Success, when redirect_uri is present or HTML form input"
},
"400": {
"description": "Bad request."
},
"403": {
"description": "User conflict."
},
"429": {
"description": "Too many attempts."
}
}
}
@ -84,6 +119,16 @@
{
"name": "redirect_uri",
"in": "query",
"description": "Success (and error if err_redirect_uri not present) redirect target for non-JSON requests.",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "err_redirect_uri",
"in": "query",
"description": "Error redirect target for non-JSON requests.",
"required": false,
"schema": {
"type": ["string", "null"]
@ -102,7 +147,10 @@
},
"responses": {
"200": {
"description": "Success."
"description": "Success, when redirect_uri not present."
},
"303": {
"description": "Success, when redirect_uri present."
}
}
}
@ -134,13 +182,28 @@
}
},
{
"name": "response_type",
"name": "mfa_redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "response_type",
"in": "query",
"required": false,
"schema": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/ResponseType"
}
]
}
},
{
"name": "pkce_code_challenge",
"in": "query",
@ -160,6 +223,92 @@
},
"required": true
},
"responses": {
"200": {
"description": "Auth, refresh & CSRF tokens.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginResponse"
}
}
}
},
"303": {
"description": "Form Fail OR Auth, refresh & CSRF tokens via cookies."
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden, when login succeeded but MFA is needed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MfaTokenResponse"
}
}
}
}
}
}
},
"/api/auth/v1/login_mfa": {
"post": {
"tags": ["auth"],
"summary": "Log in users by email and password.",
"operationId": "login_mfa_handler",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "mfa_redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "response_type",
"in": "query",
"required": false,
"schema": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/ResponseType"
}
]
}
},
{
"name": "pkce_code_challenge",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginMfaRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Auth & refresh tokens.",
@ -290,13 +439,28 @@
}
},
{
"name": "response_type",
"name": "mfa_redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "response_type",
"in": "query",
"required": false,
"schema": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/ResponseType"
}
]
}
},
{
"name": "pkce_code_challenge",
"in": "query",
@ -321,6 +485,106 @@
}
}
},
"/api/auth/v1/otp/login": {
"post": {
"tags": ["auth"],
"operationId": "login_otp_handler",
"parameters": [
{
"name": "email",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "code",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
},
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginOtpRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Auth tokens for JSONl logins.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginResponse"
}
}
}
},
"303": {
"description": "For form logins."
},
"400": {
"description": "Bad request"
}
}
}
},
"/api/auth/v1/otp/request": {
"post": {
"tags": ["auth"],
"operationId": "request_otp_handler",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RequestOtpRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "OTP sent or user not found, when redirect_uri not present."
},
"303": {
"description": "OTP sent or user not found, when redirect_uri present."
},
"400": {
"description": "Bad request"
},
"429": {
"description": "Too many attempts"
}
}
}
},
"/api/auth/v1/refresh": {
"post": {
"tags": ["auth"],
@ -356,6 +620,16 @@
"tags": ["auth"],
"summary": "Registers a new user with email and password.",
"operationId": "register_user_handler",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"requestBody": {
"content": {
"application/json": {
@ -368,10 +642,7 @@
},
"responses": {
"303": {
"description": "Success, new user registered, or user already exists."
},
"307": {
"description": "Temporary redirect: invalid password."
"description": "Form fail OR success, new user registered, or user already exists."
},
"424": {
"description": "Failed to send verification Email."
@ -384,6 +655,16 @@
"tags": ["auth"],
"summary": "Request a password reset.",
"operationId": "reset_password_request_handler",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"requestBody": {
"content": {
"application/json": {
@ -395,8 +676,11 @@
"required": true
},
"responses": {
"200": {
"description": "Success or user not found, when redirect_uri not present."
},
"303": {
"description": "Success or user not found."
"description": "Success or user not found, when redirect_uri present"
},
"400": {
"description": "Malformed email address."
@ -409,6 +693,16 @@
"tags": ["auth"],
"summary": "Endpoint for setting a new password after the user has requested a reset and provided a\nreplacement password.",
"operationId": "reset_password_update_handler",
"parameters": [
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"requestBody": {
"content": {
"application/json": {
@ -481,14 +775,79 @@
}
}
},
"/api/auth/v1/totp/confirm": {
"post": {
"tags": ["auth"],
"summary": "Verify the current user's TOTP",
"operationId": "register_totp_confirm_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ConfirmRegisterTotpRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "TOTP verified"
}
}
}
},
"/api/auth/v1/totp/register": {
"get": {
"tags": ["auth"],
"summary": "Sign-up user for TOTP second factor.",
"operationId": "register_totp_request_handler",
"responses": {
"200": {
"description": "TOTP secret and QR code URI.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RegisterTotpResponse"
}
}
}
}
}
}
},
"/api/auth/v1/totp/unregister": {
"post": {
"tags": ["auth"],
"operationId": "unregister_totp_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DisableTotpRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "TOTP disabled successfully."
}
}
}
},
"/api/auth/v1/verify_email/confirm/:email_verification_code": {
"get": {
"tags": ["auth"],
"summary": "Request a new email to verify email address.",
"operationId": "verify_email_handler",
"responses": {
"200": {
"description": "Email verified, when redirect_uri not present"
},
"303": {
"description": "Email verified."
"description": "Email verified, when redirect_uri present"
},
"400": {
"description": "Bad request: invalid redirect_uri."
@ -504,19 +863,30 @@
"tags": ["auth"],
"summary": "Request a new email to verify email address.",
"operationId": "request_email_verification_handler",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EmailVerificationRequest"
}
"parameters": [
{
"name": "email",
"in": "query",
"required": true,
"schema": {
"type": "string"
}
},
"required": true
},
{
"name": "redirect_uri",
"in": "query",
"required": false,
"schema": {
"type": ["string", "null"]
}
}
],
"responses": {
"200": {
"description": "Email verification sent or user not found, when redirect_uri not present."
},
"303": {
"description": "Email verification sent or user not found."
"description": "Email verification sent or user not found, when redirect_uri present."
},
"400": {
"description": "Malformed email address."
@ -787,11 +1157,20 @@
"csrf_token": {
"type": "string"
},
"err_redirect_uri": {
"type": ["string", "null"],
"description": "Error redirect target for non-JSON requests."
},
"new_email": {
"type": "string"
},
"old_email": {
"type": ["string", "null"]
"type": ["string", "null"],
"description": "Old email address. Only required in form mode."
},
"redirect_uri": {
"type": ["string", "null"],
"description": "Success (and error if err_redirect_uri not present) redirect target for non-JSON requests."
}
}
},
@ -799,6 +1178,10 @@
"type": "object",
"required": ["old_password", "new_password", "new_password_repeat"],
"properties": {
"err_redirect_uri": {
"type": ["string", "null"],
"description": "Error redirect target for non-JSON requests."
},
"new_password": {
"type": "string"
},
@ -807,6 +1190,10 @@
},
"old_password": {
"type": "string"
},
"redirect_uri": {
"type": ["string", "null"],
"description": "Success (and error if err_redirect_uri not present) redirect target for non-JSON requests."
}
}
},
@ -832,6 +1219,18 @@
}
}
},
"ConfirmRegisterTotpRequest": {
"type": "object",
"required": ["totp_url", "totp"],
"properties": {
"totp": {
"type": "string"
},
"totp_url": {
"type": "string"
}
}
},
"CreateRecordResponse": {
"type": "object",
"required": ["ids"],
@ -845,15 +1244,60 @@
}
}
},
"EmailVerificationRequest": {
"DisableTotpRequest": {
"type": "object",
"required": ["email"],
"required": ["totp"],
"properties": {
"email": {
"totp": {
"type": "string"
}
}
},
"LoginMfaRequest": {
"type": "object",
"required": ["mfa_token"],
"properties": {
"mfa_redirect_uri": {
"type": ["string", "null"]
},
"mfa_token": {
"type": "string"
},
"pkce_code_challenge": {
"type": ["string", "null"]
},
"redirect_uri": {
"type": ["string", "null"]
},
"response_type": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/ResponseType"
}
]
},
"totp": {
"type": ["string", "null"]
}
}
},
"LoginOtpRequest": {
"type": "object",
"properties": {
"code": {
"type": ["string", "null"]
},
"email": {
"type": ["string", "null"]
},
"redirect_uri": {
"type": ["string", "null"]
}
}
},
"LoginRequest": {
"type": "object",
"required": ["email", "password"],
@ -861,6 +1305,9 @@
"email": {
"type": "string"
},
"mfa_redirect_uri": {
"type": ["string", "null"]
},
"password": {
"type": "string"
},
@ -871,7 +1318,14 @@
"type": ["string", "null"]
},
"response_type": {
"type": ["string", "null"]
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/ResponseType"
}
]
}
}
},
@ -913,6 +1367,15 @@
}
}
},
"MfaTokenResponse": {
"type": "object",
"required": ["mfa_token"],
"properties": {
"mfa_token": {
"type": "string"
}
}
},
"RefreshRequest": {
"type": "object",
"required": ["refresh_token"],
@ -934,6 +1397,18 @@
}
}
},
"RegisterTotpResponse": {
"type": "object",
"required": ["totp_url"],
"properties": {
"png": {
"type": ["string", "null"]
},
"totp_url": {
"type": "string"
}
}
},
"RegisterUserRequest": {
"type": "object",
"required": ["email", "password", "password_repeat"],
@ -946,6 +1421,21 @@
},
"password_repeat": {
"type": "string"
},
"redirect_uri": {
"type": ["string", "null"]
}
}
},
"RequestOtpRequest": {
"type": "object",
"required": ["email"],
"properties": {
"email": {
"type": "string"
},
"redirect_uri": {
"type": ["string", "null"]
}
}
},
@ -955,12 +1445,15 @@
"properties": {
"email": {
"type": "string"
},
"redirect_uri": {
"type": ["string", "null"]
}
}
},
"ResetPasswordUpdateRequest": {
"type": "object",
"required": ["password", "password_repeat", "password_reset_code"],
"required": ["password", "password_repeat", "password_reset_token"],
"properties": {
"password": {
"type": "string"
@ -968,7 +1461,7 @@
"password_repeat": {
"type": "string"
},
"password_reset_code": {
"password_reset_token": {
"type": "string"
},
"redirect_uri": {
@ -976,6 +1469,11 @@
}
}
},
"ResponseType": {
"type": "string",
"description": "https://www.rfc-editor.org/rfc/rfc6749#section-3.1.1",
"enum": ["token", "code"]
},
"TokenResponse": {
"type": "object",
"required": ["auth_token", "refresh_token", "csrf_token"],

View file

@ -12,13 +12,13 @@
"format": "prettier -w ."
},
"dependencies": {
"@astrojs/check": "^0.9.6",
"@astrojs/rss": "^4.0.15",
"@astrojs/starlight": "^0.37.6",
"@astrojs/starlight-tailwind": "^4.0.2",
"@iconify-json/tabler": "^1.2.26",
"@tailwindcss/vite": "^4.2.0",
"astro": "^5.17.3",
"@astrojs/check": "^0.9.8",
"@astrojs/rss": "^4.0.17",
"@astrojs/starlight": "^0.38.1",
"@astrojs/starlight-tailwind": "^5.0.0",
"@iconify-json/tabler": "^1.2.31",
"@tailwindcss/vite": "^4.2.2",
"astro": "^6.0.6",
"astro-icon": "^1.1.5",
"chart.js": "^4.5.1",
"chartjs-chart-error-bars": "^4.4.5",
@ -26,25 +26,25 @@
"clsx": "^2.1.1",
"sharp": "^0.34.5",
"solid-js": "^1.9.11",
"starlight-links-validator": "^0.19.2",
"starlight-openapi": "^0.22.0",
"tailwind-merge": "^3.4.1",
"tailwindcss": "^4.2.0",
"starlight-links-validator": "^0.20.1",
"starlight-openapi": "^0.24.0",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.2.2",
"typescript": "^5.9.3"
},
"devDependencies": {
"@astrojs/sitemap": "^3.7.0",
"@astrojs/solid-js": "^5.1.3",
"@eslint/js": "^9.39.2",
"@astrojs/sitemap": "^3.7.1",
"@astrojs/solid-js": "^6.0.1",
"@eslint/js": "^10.0.1",
"astro-robots-txt": "^1.0.0",
"eslint": "^9.39.2",
"eslint": "^10.0.3",
"eslint-plugin-astro": "^1.6.0",
"eslint-plugin-better-tailwindcss": "^4.3.0",
"eslint-plugin-better-tailwindcss": "^4.3.2",
"eslint-plugin-solid": "^0.14.5",
"globals": "^17.3.0",
"globals": "^17.4.0",
"prettier": "^3.8.1",
"prettier-plugin-astro": "^0.14.1",
"prettier-plugin-tailwindcss": "^0.7.2",
"typescript-eslint": "^8.56.0"
"typescript-eslint": "^8.57.1"
}
}

View file

@ -30,7 +30,7 @@ const isOdd = num % 2;
]}
>
<div>
<a href={"/blog/" + postData.slug}>
<a href={"/blog/" + postData.id}>
{
postData?.data?.image && (
<Image
@ -49,7 +49,7 @@ const isOdd = num % 2;
</div>
<div>
<a href={"/blog/" + postData.slug}>
<a href={"/blog/" + postData.id}>
<h2>{postData.data.title}</h2>
</a>

View file

@ -1,10 +1,15 @@
import { defineCollection, reference, z } from "astro:content";
import { defineCollection, reference } from "astro:content";
import { z } from "astro/zod";
import { docsSchema } from "@astrojs/starlight/schema";
import { glob } from "astro/loaders";
const docsCollection = defineCollection({ schema: docsSchema() });
const docsCollection = defineCollection({
loader: glob({ pattern: "**/[^_]*.{md,mdx}", base: "./src/content/docs" }),
schema: docsSchema(),
});
const blogCollection = defineCollection({
type: "content",
loader: glob({ pattern: "**/[^_]*.{md,mdx}", base: "./src/data/blog" }),
schema: ({ image }) =>
z.object({
title: z.string(),

View file

@ -1,5 +1,5 @@
---
import { getCollection, getEntry } from "astro:content";
import { getCollection, getEntry, render } from "astro:content";
// import { Image } from "astro:assets";
import Base from "@/layouts/Base.astro";
@ -11,17 +11,17 @@ export async function getStaticPaths() {
const blogEntries = await getCollection("blog");
return blogEntries.map((entry) => ({
params: { slug: entry.slug },
params: { slug: entry.id },
props: { entry },
}));
}
const { entry } = Astro.props;
const { Content } = await entry.render();
const { Content } = await render(entry);
const author = await getEntry(entry.data.author);
const avgWordsPerMinute = 220;
const readMinutes = entry.body.split(" ").length / avgWordsPerMinute;
const readMinutes = (entry.body ?? "").split(" ").length / avgWordsPerMinute;
const proseStyle: string[] = [
"prose",

View file

@ -15,7 +15,7 @@ export async function GET(_context: APIContext) {
title: post.data.title,
pubDate: post.data.pubDate,
description: post.data.intro,
link: `/blog/${post.slug}/`,
link: `/blog/${post.id}/`,
})),
customData: `<language>en-us</language>`,
});

View file

@ -13,32 +13,32 @@
"types": "make --always-make types"
},
"dependencies": {
"@iconify-json/tabler": "^1.2.26",
"@iconify-json/tabler": "^1.2.31",
"@nanostores/persistent": "^1.3.3",
"@nanostores/solid": "^1.1.1",
"astro": "^5.17.3",
"astro": "^6.0.6",
"astro-icon": "^1.1.5",
"nanostores": "^1.1.0",
"nanostores": "^1.2.0",
"solid-icons": "^1.2.0",
"solid-js": "^1.9.11",
"trailbase": "^0.9.0"
"trailbase": "^0.10.0"
},
"devDependencies": {
"@astrojs/solid-js": "^5.1.3",
"@astrojs/solid-js": "^6.0.1",
"@eslint/js": "^10.0.1",
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.2.0",
"@tailwindcss/vite": "^4.2.2",
"@types/dateformat": "^5.0.3",
"eslint": "^10.0.0",
"eslint": "^10.0.3",
"eslint-plugin-astro": "^1.6.0",
"eslint-plugin-better-tailwindcss": "^4.3.0",
"eslint-plugin-better-tailwindcss": "^4.3.2",
"eslint-plugin-solid": "^0.14.5",
"globals": "^17.3.0",
"globals": "^17.4.0",
"prettier": "^3.8.1",
"prettier-plugin-astro": "^0.14.1",
"quicktype": "^23.2.6",
"sharp": "^0.34.5",
"tailwindcss": "^4.2.0",
"typescript-eslint": "^8.56.0"
"tailwindcss": "^4.2.2",
"typescript-eslint": "^8.57.1"
}
}

View file

@ -16,13 +16,13 @@
"trailbase-wasm": "workspace:*"
},
"devDependencies": {
"@bytecodealliance/jco": "^1.17.0",
"@bytecodealliance/jco": "^1.17.2",
"@eslint/js": "^10.0.1",
"@types/node": "^25.2.3",
"eslint": "^10.0.0",
"@types/node": "^25.5.0",
"eslint": "^10.0.3",
"prettier": "^3.8.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"typescript-eslint": "^8.57.1",
"vite": "^7.3.1"
}
}

View file

@ -18,14 +18,14 @@
"@eslint/js": "^10.0.1",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.4",
"eslint": "^10.0.0",
"@vitejs/plugin-react": "^5.2.0",
"eslint": "^10.0.3",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.5.0",
"globals": "^17.3.0",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.4.0",
"prettier": "^3.8.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"typescript-eslint": "^8.57.1",
"vite": "^7.3.1"
}
}

View file

@ -16,13 +16,13 @@
"trailbase-wasm": "workspace:*"
},
"devDependencies": {
"@bytecodealliance/jco": "^1.17.0",
"@bytecodealliance/jco": "^1.17.2",
"@eslint/js": "^10.0.1",
"@types/node": "^25.2.3",
"eslint": "^10.0.0",
"@types/node": "^25.5.0",
"eslint": "^10.0.3",
"prettier": "^3.8.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"typescript-eslint": "^8.57.1",
"vite": "^7.3.1"
}
}

View file

@ -13,22 +13,22 @@
},
"dependencies": {
"solid-js": "^1.9.11",
"trailbase": "^0.9.0"
"trailbase": "^0.10.0"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@tailwindcss/vite": "^4.2.0",
"@tailwindcss/vite": "^4.2.2",
"@types/express": "^5.0.6",
"@types/node": "^25.2.3",
"@types/node": "^25.5.0",
"compression": "^1.8.1",
"eslint": "^10.0.0",
"eslint": "^10.0.3",
"express": "^5.2.1",
"globals": "^17.3.0",
"globals": "^17.4.0",
"prettier": "^3.8.1",
"sirv": "^3.0.2",
"tailwindcss": "^4.2.0",
"typescript-eslint": "^8.56.0",
"tailwindcss": "^4.2.2",
"typescript-eslint": "^8.57.1",
"vite": "^7.3.1",
"vite-plugin-solid": "^2.11.10"
"vite-plugin-solid": "^2.11.11"
}
}

View file

@ -12,16 +12,16 @@
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@types/node": "^25.2.3",
"eslint": "^10.0.0",
"@types/node": "^25.5.0",
"eslint": "^10.0.3",
"prettier": "^3.8.1",
"quicktype": "^23.2.6",
"ts-node": "^10.9.2",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0"
"typescript-eslint": "^8.57.1"
},
"dependencies": {
"csv-parse": "^5.6.0",
"trailbase": "^0.9.0"
"trailbase": "^0.10.0"
}
}

View file

@ -12,30 +12,30 @@
"preview": "vite preview"
},
"dependencies": {
"@tanstack/db": "^0.5.27",
"@tanstack/query-core": "^5.90.20",
"@tanstack/query-db-collection": "^1.0.24",
"@tanstack/react-db": "^0.1.71",
"@tanstack/trailbase-db-collection": "^0.1.71",
"@tanstack/db": "^0.5.33",
"@tanstack/query-core": "^5.91.0",
"@tanstack/query-db-collection": "^1.0.30",
"@tanstack/react-db": "^0.1.77",
"@tanstack/trailbase-db-collection": "^0.1.77",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"tailwindcss": "^4.2.0",
"tailwindcss": "^4.2.2",
"trailbase": "^0.8.0"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@tailwindcss/vite": "^4.2.0",
"@tailwindcss/vite": "^4.2.2",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.4",
"eslint": "^10.0.0",
"@vitejs/plugin-react": "^5.2.0",
"eslint": "^10.0.3",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.5.0",
"globals": "^17.3.0",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.4.0",
"prettier": "^3.8.1",
"prettier-plugin-tailwindcss": "^0.7.2",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"typescript-eslint": "^8.57.1",
"vite": "^7.3.1"
}
}

View file

@ -15,11 +15,11 @@
"trailbase-wasm": "workspace:*"
},
"devDependencies": {
"@bytecodealliance/jco": "^1.17.0",
"@bytecodealliance/jco": "^1.17.2",
"@eslint/js": "^10.0.1",
"commander": "^14.0.3",
"eslint": "^10.0.0",
"globals": "^17.3.0",
"eslint": "^10.0.3",
"globals": "^17.4.0",
"nano-spawn": "^2.0.0",
"prettier": "^3.8.1",
"vite": "^7.3.1"

View file

@ -15,15 +15,15 @@
"trailbase-wasm": "workspace:*"
},
"devDependencies": {
"@bytecodealliance/jco": "^1.17.0",
"@bytecodealliance/jco": "^1.17.2",
"@eslint/js": "^10.0.1",
"@types/node": "^25.2.3",
"@types/node": "^25.5.0",
"commander": "^14.0.3",
"eslint": "^10.0.0",
"eslint": "^10.0.3",
"nano-spawn": "^2.0.0",
"prettier": "^3.8.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"typescript-eslint": "^8.57.1",
"vite": "^7.3.1"
}
}

View file

@ -79,14 +79,14 @@
"test": "vitest run"
},
"devDependencies": {
"@bytecodealliance/jco": "^1.17.0",
"@bytecodealliance/jco": "^1.17.2",
"@eslint/js": "^10.0.1",
"eslint": "^10.0.0",
"eslint": "^10.0.3",
"prettier": "^3.8.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0",
"typescript-eslint": "^8.57.1",
"vite": "^7.3.1",
"vite-plugin-dts": "^4.5.4",
"vitest": "^4.0.18"
"vitest": "^4.1.0"
}
}

File diff suppressed because it is too large Load diff