mirror of
https://github.com/immich-app/geoshenanigans.git
synced 2026-09-30 13:23:08 +08:00
feat: serve styles from tileserver (#33)
This commit is contained in:
@@ -9,6 +9,7 @@ on:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- ".github/workflows/tiles-file.yml"
|
||||
- "map-styles/**"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
@@ -16,14 +17,33 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
deploy_tiles:
|
||||
name: Deploy Tiles
|
||||
name: Deploy Tiles & Styles
|
||||
strategy:
|
||||
matrix:
|
||||
bucket_region: [ "wnam", "enam", "weur", "eeur", "apac" ]
|
||||
defaults:
|
||||
run:
|
||||
working-directory: 'map-styles'
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
KEY: ${{ steps.latest_build.outputs.KEY }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: 'map-styles/.nvmrc'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Generate styles
|
||||
run: npm run generate
|
||||
|
||||
- name: Find latest pmtiles build
|
||||
id: latest_build
|
||||
env:
|
||||
@@ -34,6 +54,7 @@ jobs:
|
||||
else
|
||||
build=$FILE_NAME
|
||||
fi
|
||||
export build=${build%.pmtiles}
|
||||
echo "KEY=$build"
|
||||
echo "KEY=$build" >> $GITHUB_OUTPUT
|
||||
|
||||
@@ -53,8 +74,11 @@ jobs:
|
||||
type = http
|
||||
url = https://build.protomaps.com/
|
||||
|
||||
- name: Copy latest styles to R2
|
||||
run: rclone --progress copy ./dist/ r2:/tiles-${{ matrix.bucket_region }}/${{ steps.latest_build.outputs.KEY }}/styles/ --s3-no-check-bucket --s3-chunk-size=64M --multi-thread-streams=50 --checkers=512
|
||||
|
||||
- name: Copy latest tiles to R2
|
||||
run: rclone --progress copyto pmtiles:/${{ steps.latest_build.outputs.KEY }} r2:/tiles-${{ matrix.bucket_region }}/${{ steps.latest_build.outputs.KEY }} --s3-no-check-bucket --s3-chunk-size=64M --multi-thread-streams=50 --checkers=512
|
||||
run: rclone --progress copyto pmtiles:/${{ steps.latest_build.outputs.KEY }}.pmtiles r2:/tiles-${{ matrix.bucket_region }}/${{ steps.latest_build.outputs.KEY }}/tiles.pmtiles --s3-no-check-bucket --s3-chunk-size=64M --multi-thread-streams=50 --checkers=512
|
||||
update_tile_ref:
|
||||
name: Update tile server file reference
|
||||
needs: [deploy_tiles]
|
||||
@@ -74,7 +98,7 @@ jobs:
|
||||
|
||||
- name: Update deployment file name
|
||||
run: |
|
||||
sed -i -E 's/"pmtiles_file_name": "(.*)"/"pmtiles_file_name": "${{ needs.deploy_tiles.outputs.KEY }}"/' deployment/modules/cloudflare/tiles-worker/tiles.tfvars.json
|
||||
sed -i -E 's/"pmtiles_deployment_key": "(.*)"/"pmtiles_deployment_key": "${{ needs.deploy_tiles.outputs.KEY }}"/' deployment/modules/cloudflare/tiles-worker/tiles.tfvars.json
|
||||
|
||||
- name: Push updated tiles.tfvars to repo
|
||||
uses: EndBug/add-and-commit@v9
|
||||
|
||||
@@ -191,7 +191,7 @@ jobs:
|
||||
# Figure out how to extract this from terraform at some point or get it into github vars
|
||||
KV_NAMESPACE_ID: 5a4b82694e8b490db8b8904cdaea4f00
|
||||
BUCKET_KEY: tiles-weur
|
||||
FILE_NAME: ${{ fromJson(env.TILES_JSON).pmtiles_file_name }}
|
||||
DEPLOYMENT_KEY: ${{ fromJson(env.TILES_JSON).pmtiles_deployment_key }}
|
||||
run: npm run kv:warm
|
||||
|
||||
deploy-terragrunt:
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "submodules/basemaps"]
|
||||
path = submodules/basemaps
|
||||
url = https://github.com/protomaps/basemaps.git
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"pmtiles_file_name": "20240812.pmtiles"
|
||||
"pmtiles_deployment_key": "20240812"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
variable "cloudflare_account_id" {}
|
||||
variable "tf_state_postgres_conn_str" {}
|
||||
variable "pmtiles_file_name" {}
|
||||
variable "pmtiles_deployment_key" {}
|
||||
variable "tiles_build_dir" {}
|
||||
variable "vmetrics_api_token" {}
|
||||
variable "env" {}
|
||||
|
||||
@@ -9,8 +9,8 @@ resource "cloudflare_workers_script" "tiles" {
|
||||
module = true
|
||||
|
||||
plain_text_binding {
|
||||
name = "PMTILES_FILE_NAME"
|
||||
text = var.pmtiles_file_name
|
||||
name = "DEPLOYMENT_KEY"
|
||||
text = var.pmtiles_deployment_key
|
||||
}
|
||||
|
||||
plain_text_binding {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
dist
|
||||
node_modules
|
||||
@@ -0,0 +1 @@
|
||||
20.10
|
||||
Generated
+759
@@ -0,0 +1,759 @@
|
||||
{
|
||||
"name": "protomaps-themes-base",
|
||||
"version": "3.1.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "protomaps-themes-base",
|
||||
"version": "3.1.0",
|
||||
"license": "BSD-3-Clause",
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.16.5",
|
||||
"tsx": "^4.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz",
|
||||
"integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz",
|
||||
"integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz",
|
||||
"integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz",
|
||||
"integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz",
|
||||
"integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz",
|
||||
"integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz",
|
||||
"integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz",
|
||||
"integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz",
|
||||
"integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz",
|
||||
"integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz",
|
||||
"integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz",
|
||||
"integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.23.1",
|
||||
"@esbuild/android-arm": "0.23.1",
|
||||
"@esbuild/android-arm64": "0.23.1",
|
||||
"@esbuild/android-x64": "0.23.1",
|
||||
"@esbuild/darwin-arm64": "0.23.1",
|
||||
"@esbuild/darwin-x64": "0.23.1",
|
||||
"@esbuild/freebsd-arm64": "0.23.1",
|
||||
"@esbuild/freebsd-x64": "0.23.1",
|
||||
"@esbuild/linux-arm": "0.23.1",
|
||||
"@esbuild/linux-arm64": "0.23.1",
|
||||
"@esbuild/linux-ia32": "0.23.1",
|
||||
"@esbuild/linux-loong64": "0.23.1",
|
||||
"@esbuild/linux-mips64el": "0.23.1",
|
||||
"@esbuild/linux-ppc64": "0.23.1",
|
||||
"@esbuild/linux-riscv64": "0.23.1",
|
||||
"@esbuild/linux-s390x": "0.23.1",
|
||||
"@esbuild/linux-x64": "0.23.1",
|
||||
"@esbuild/netbsd-x64": "0.23.1",
|
||||
"@esbuild/openbsd-arm64": "0.23.1",
|
||||
"@esbuild/openbsd-x64": "0.23.1",
|
||||
"@esbuild/sunos-x64": "0.23.1",
|
||||
"@esbuild/win32-arm64": "0.23.1",
|
||||
"@esbuild/win32-ia32": "0.23.1",
|
||||
"@esbuild/win32-x64": "0.23.1"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-tsconfig": {
|
||||
"version": "4.8.1",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
|
||||
"integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"resolve-pkg-maps": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-pkg-maps": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/tsx": {
|
||||
"version": "4.19.1",
|
||||
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.1.tgz",
|
||||
"integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "~0.23.0",
|
||||
"get-tsconfig": "^4.7.5"
|
||||
},
|
||||
"bin": {
|
||||
"tsx": "dist/cli.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@esbuild/aix-ppc64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz",
|
||||
"integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/android-arm": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz",
|
||||
"integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/android-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/android-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/darwin-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/darwin-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/freebsd-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/freebsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-arm": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz",
|
||||
"integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-ia32": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz",
|
||||
"integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-loong64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz",
|
||||
"integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-mips64el": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz",
|
||||
"integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-ppc64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz",
|
||||
"integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-riscv64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz",
|
||||
"integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-s390x": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz",
|
||||
"integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/netbsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/openbsd-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/openbsd-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/sunos-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/win32-arm64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz",
|
||||
"integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/win32-ia32": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz",
|
||||
"integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/win32-x64": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz",
|
||||
"integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "20.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz",
|
||||
"integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"esbuild": {
|
||||
"version": "0.23.1",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz",
|
||||
"integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@esbuild/aix-ppc64": "0.23.1",
|
||||
"@esbuild/android-arm": "0.23.1",
|
||||
"@esbuild/android-arm64": "0.23.1",
|
||||
"@esbuild/android-x64": "0.23.1",
|
||||
"@esbuild/darwin-arm64": "0.23.1",
|
||||
"@esbuild/darwin-x64": "0.23.1",
|
||||
"@esbuild/freebsd-arm64": "0.23.1",
|
||||
"@esbuild/freebsd-x64": "0.23.1",
|
||||
"@esbuild/linux-arm": "0.23.1",
|
||||
"@esbuild/linux-arm64": "0.23.1",
|
||||
"@esbuild/linux-ia32": "0.23.1",
|
||||
"@esbuild/linux-loong64": "0.23.1",
|
||||
"@esbuild/linux-mips64el": "0.23.1",
|
||||
"@esbuild/linux-ppc64": "0.23.1",
|
||||
"@esbuild/linux-riscv64": "0.23.1",
|
||||
"@esbuild/linux-s390x": "0.23.1",
|
||||
"@esbuild/linux-x64": "0.23.1",
|
||||
"@esbuild/netbsd-x64": "0.23.1",
|
||||
"@esbuild/openbsd-arm64": "0.23.1",
|
||||
"@esbuild/openbsd-x64": "0.23.1",
|
||||
"@esbuild/sunos-x64": "0.23.1",
|
||||
"@esbuild/win32-arm64": "0.23.1",
|
||||
"@esbuild/win32-ia32": "0.23.1",
|
||||
"@esbuild/win32-x64": "0.23.1"
|
||||
}
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"get-tsconfig": {
|
||||
"version": "4.8.1",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
|
||||
"integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"resolve-pkg-maps": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"resolve-pkg-maps": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||
"dev": true
|
||||
},
|
||||
"tsx": {
|
||||
"version": "4.19.1",
|
||||
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.1.tgz",
|
||||
"integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esbuild": "~0.23.0",
|
||||
"fsevents": "~2.3.3",
|
||||
"get-tsconfig": "^4.7.5"
|
||||
}
|
||||
},
|
||||
"undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "immich-map-styles",
|
||||
"description": "Generate immich style variations from the protomaps styles",
|
||||
"main": "index.ts",
|
||||
"scripts": {
|
||||
"generate": "tsx src/index.ts"
|
||||
},
|
||||
"author": "The Protomaps Authors",
|
||||
"license": "BSD-3-Clause",
|
||||
"homepage": "https://github.com/protomaps/basemaps",
|
||||
"devDependencies": {
|
||||
"tsx": "^4.7.2",
|
||||
"@types/node": "^20.16.5"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": 9,
|
||||
"name": "Immich Map",
|
||||
"id": "immich-map",
|
||||
"sources": {
|
||||
"tiles": {
|
||||
"type": "vector",
|
||||
"url": "https://tiles.immich.cloud/v1.json"
|
||||
}
|
||||
},
|
||||
"sprite": "https://static.immich.cloud/tiles/sprites/v1/light",
|
||||
"glyphs": "https://static.immich.cloud/tiles/fonts/{fontstack}/{range}.pbf"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import themes, { ImmichTheme } from './themes';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { layersWithCustomTheme } from '../../submodules/basemaps/styles/src';
|
||||
|
||||
const generateLayers = (themeName: string) => {
|
||||
const sourceName = 'protomaps'
|
||||
const theme = themes[themeName];
|
||||
const layers = layersWithCustomTheme(sourceName, theme);
|
||||
const style = {
|
||||
version: 8,
|
||||
"name": "Immich Map",
|
||||
"id": `immich-map-${themeName}`,
|
||||
sources: {
|
||||
[sourceName]: {
|
||||
type: "vector",
|
||||
url: 'https://tiles.immich.cloud/v1.json',
|
||||
},
|
||||
},
|
||||
layers: layers,
|
||||
sprite: `https://static.immich.cloud/tiles/sprites/v1/${theme.iconStyle}`,
|
||||
glyphs: "https://static.immich.cloud/tiles/fonts/{fontstack}/{range}.pbf",
|
||||
};
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
const dist = path.resolve(__dirname, '../dist');
|
||||
if (!fs.existsSync(dist)) {
|
||||
fs.mkdirSync(dist);
|
||||
}
|
||||
|
||||
for (const theme of Object.keys(themes)) {
|
||||
fs.writeFileSync(path.resolve(dist, `${theme}.json`), JSON.stringify(generateLayers(theme), null, 2));
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { BLACK, LIGHT, Theme } from '../../submodules/basemaps/styles/src/themes';
|
||||
|
||||
export interface ImmichTheme extends Theme {
|
||||
iconStyle: 'dark' | 'light';
|
||||
}
|
||||
|
||||
export const IMMICH_LIGHT: ImmichTheme = {
|
||||
iconStyle: 'light',
|
||||
...LIGHT,
|
||||
water: 'rgba(148, 209, 236, 0.66)'
|
||||
};
|
||||
|
||||
export const IMMICH_DARK: ImmichTheme = {
|
||||
iconStyle: 'dark',
|
||||
...BLACK,
|
||||
};
|
||||
|
||||
const themes: Record<string, ImmichTheme> = {
|
||||
light: IMMICH_LIGHT,
|
||||
dark: IMMICH_DARK,
|
||||
};
|
||||
|
||||
export default themes;
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"lib": ["es2020", "dom"],
|
||||
"strict": true,
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
},
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
},
|
||||
"include": ["src/*.ts"]
|
||||
}
|
||||
Submodule
+1
Submodule submodules/basemaps added at 217103cf64
Vendored
+2
-2
@@ -1,5 +1,5 @@
|
||||
interface WorkerEnv extends Omit<Env, 'ENVIRONMENT' | 'PMTILES_FILE_NAME'> {
|
||||
interface WorkerEnv extends Omit<Env, 'ENVIRONMENT' | 'DEPLOYMENT_KEY'> {
|
||||
ENVIRONMENT: string;
|
||||
PMTILES_FILE_NAME: string;
|
||||
DEPLOYMENT_KEY: string;
|
||||
VMETRICS_API_TOKEN: string;
|
||||
}
|
||||
|
||||
+35
-6
@@ -17,13 +17,20 @@ declare global {
|
||||
}
|
||||
/* eslint-enable no-var */
|
||||
|
||||
const URL_MATCHER = /^\/v(?<VERSION>[0-9]+)((?=)|(?<JSON>\.json)|\/(?<Z>\d+)\/(?<X>\d+)\/(?<Y>\d+).mvt)$/;
|
||||
const URL_MATCHER =
|
||||
/^\/v(?<VERSION>[0-9]+)((?=)|\/style\/(?<STYLE>\w+)(?:\.json)?|(?<JSON>\.json)|\/(?<Z>\d+)\/(?<X>\d+)\/(?<Y>\d+).mvt)$/;
|
||||
|
||||
type PMTilesParams = {
|
||||
requestType: 'tile' | 'json' | undefined;
|
||||
requestType: 'tile' | 'json' | 'style' | undefined;
|
||||
url: URL;
|
||||
};
|
||||
|
||||
type PMTilesStyleParams = PMTilesParams & {
|
||||
requestType: 'style';
|
||||
version: string;
|
||||
style: string;
|
||||
};
|
||||
|
||||
type PMTilesTileParams = PMTilesParams & {
|
||||
requestType: 'tile';
|
||||
version: string;
|
||||
@@ -38,7 +45,7 @@ type PMTilesJsonParams = PMTilesParams & {
|
||||
};
|
||||
|
||||
enum Header {
|
||||
PMTILES_FILE_IDENTIFIER = 'PMTiles-File-Identifier',
|
||||
PMTILES_DEPLOYMENT_KEY = 'PMTiles-Deployment-Key',
|
||||
CACHE_CONTROL = 'Cache-Control',
|
||||
ACCESS_CONTROL_ALLOW_ORIGIN = 'Access-Control-Allow-Origin',
|
||||
VARY = 'Vary',
|
||||
@@ -51,11 +58,14 @@ export function parseUrl(request: Request): PMTilesParams {
|
||||
const url = new URL(request.url);
|
||||
const matches = URL_MATCHER.exec(url.pathname);
|
||||
const version = matches?.groups?.VERSION;
|
||||
const style = matches?.groups?.STYLE;
|
||||
const z = matches?.groups?.Z;
|
||||
const x = matches?.groups?.X;
|
||||
const y = matches?.groups?.Y;
|
||||
if (version && z && x && y) {
|
||||
return { requestType: 'tile', version, z, x, y, url } as PMTilesTileParams;
|
||||
} else if (style) {
|
||||
return { requestType: 'style', style, url } as PMTilesStyleParams;
|
||||
} else if (version) {
|
||||
return { requestType: 'json', version, url } as PMTilesJsonParams;
|
||||
}
|
||||
@@ -94,6 +104,16 @@ async function handleRequest(
|
||||
return cacheResponse(new Response(JSON.stringify(tileJson), { headers: respHeaders, status: 200 }));
|
||||
}
|
||||
|
||||
async function handleStyleRequest(respHeaders: Headers) {
|
||||
const { style } = pmTilesParams as PMTilesStyleParams;
|
||||
const styleJson = await storageRepository.getAsStream('styles/' + style + '.json');
|
||||
if (!styleJson) {
|
||||
return cacheResponse(new Response('Style not found', { status: 404 }));
|
||||
}
|
||||
respHeaders.set(Header.CONTENT_TYPE, 'application/json');
|
||||
return cacheResponse(new Response(styleJson, { headers: respHeaders, status: 200 }));
|
||||
}
|
||||
|
||||
if (request.method.toUpperCase() !== 'GET') {
|
||||
return new Response(undefined, { status: 405 });
|
||||
}
|
||||
@@ -102,7 +122,7 @@ async function handleRequest(
|
||||
const cached = await metrics.monitorAsyncFunction({ name: 'match_request_from_cdn' }, (url) => cache.match(url))(
|
||||
request.url,
|
||||
);
|
||||
if (cached && cached.headers.get(Header.PMTILES_FILE_IDENTIFIER) === env.PMTILES_FILE_NAME) {
|
||||
if (cached && cached.headers.get(Header.PMTILES_DEPLOYMENT_KEY) === env.DEPLOYMENT_KEY) {
|
||||
const cacheHeaders = new Headers(cached.headers);
|
||||
const encodeBody = cacheHeaders.has('content-encoding') ? 'manual' : 'automatic';
|
||||
return new Response(cached.body, {
|
||||
@@ -132,7 +152,7 @@ async function handleRequest(
|
||||
Object.entries(bucketMap).filter(([key]) => buckets.includes(key as R2BucketRegion)),
|
||||
);
|
||||
|
||||
const storageRepository = new R2StorageRepository(filteredBucketMap, env.PMTILES_FILE_NAME, metrics);
|
||||
const storageRepository = new R2StorageRepository(filteredBucketMap, env.DEPLOYMENT_KEY, metrics);
|
||||
const pmTilesService = await metrics.monitorAsyncFunction({ name: 'pmtiles_init' }, PMTilesService.init)(
|
||||
storageRepository,
|
||||
memCacheRepository,
|
||||
@@ -144,7 +164,7 @@ async function handleRequest(
|
||||
respHeaders.set(Header.CACHE_CONTROL, `public, max-age=${60 * 60 * 24 * 31}`);
|
||||
respHeaders.set(Header.ACCESS_CONTROL_ALLOW_ORIGIN, '*');
|
||||
respHeaders.set(Header.VARY, 'Origin');
|
||||
respHeaders.set(Header.PMTILES_FILE_IDENTIFIER, env.PMTILES_FILE_NAME);
|
||||
respHeaders.set(Header.PMTILES_DEPLOYMENT_KEY, env.DEPLOYMENT_KEY);
|
||||
|
||||
const pmTilesParams = parseUrl(request);
|
||||
|
||||
@@ -164,6 +184,15 @@ async function handleRequest(
|
||||
handleJsonRequest,
|
||||
)(respHeaders);
|
||||
}
|
||||
|
||||
if (pmTilesParams.requestType === 'style') {
|
||||
const { style } = pmTilesParams as PMTilesStyleParams;
|
||||
console.log('style');
|
||||
return await metrics.monitorAsyncFunction(
|
||||
{ name: 'style_request', tags: { style } },
|
||||
handleStyleRequest,
|
||||
)(respHeaders);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return new Response('Internal Server Error', { status: 500 });
|
||||
|
||||
@@ -11,9 +11,11 @@ export interface IMemCacheRepository {
|
||||
}
|
||||
|
||||
export interface IStorageRepository {
|
||||
get(range: { length: number; offset: number }): Promise<ArrayBuffer>;
|
||||
getAsStream(range: { length: number; offset: number }): Promise<ReadableStream>;
|
||||
getFileName(): string;
|
||||
getRange(range: { length: number; offset: number }): Promise<ArrayBuffer>;
|
||||
getRangeAsStream(range: { length: number; offset: number }): Promise<ReadableStream>;
|
||||
get(key: string): Promise<ArrayBuffer>;
|
||||
getAsStream(key: string): Promise<ReadableStream>;
|
||||
getDeploymentKey(): string;
|
||||
}
|
||||
|
||||
export interface IDeferredRepository {
|
||||
|
||||
+10
-7
@@ -43,7 +43,7 @@ export function decompress(buf: ArrayBuffer, compression: Compression): ArrayBuf
|
||||
}
|
||||
|
||||
const getDirectory = async (length: number, offset: number, source: IStorageRepository, header: Header) => {
|
||||
const resp = await source.get({ offset, length });
|
||||
const resp = await source.getRange({ offset, length });
|
||||
const data = decompress(resp, header.internalCompression);
|
||||
const entries = deserializeIndex(await new Response(data).arrayBuffer());
|
||||
if (entries.length === 0) {
|
||||
@@ -62,7 +62,7 @@ const handler = async () => {
|
||||
CLOUDFLARE_ACCOUNT_ID,
|
||||
KV_NAMESPACE_ID,
|
||||
BUCKET_KEY,
|
||||
FILE_NAME,
|
||||
DEPLOYMENT_KEY,
|
||||
} = process.env;
|
||||
if (
|
||||
!S3_ACCESS_KEY ||
|
||||
@@ -72,7 +72,7 @@ const handler = async () => {
|
||||
!CLOUDFLARE_ACCOUNT_ID ||
|
||||
!KV_NAMESPACE_ID ||
|
||||
!BUCKET_KEY ||
|
||||
!FILE_NAME
|
||||
!DEPLOYMENT_KEY
|
||||
) {
|
||||
throw new Error('Missing environment variables');
|
||||
}
|
||||
@@ -87,7 +87,7 @@ const handler = async () => {
|
||||
},
|
||||
});
|
||||
|
||||
const storageRepository = new S3StorageRepository(client, BUCKET_KEY, FILE_NAME);
|
||||
const storageRepository = new S3StorageRepository(client, BUCKET_KEY, DEPLOYMENT_KEY);
|
||||
const memCacheRepository = new MemCacheRepository(new Map());
|
||||
const kvRepository = new FakeKVRepository();
|
||||
const metricsRepository = new FakeMetricsRepository();
|
||||
@@ -99,7 +99,7 @@ const handler = async () => {
|
||||
);
|
||||
|
||||
console.log('Checking if already warmed');
|
||||
const kvCheckKey = encodeURIComponent(`${FILE_NAME}|kv-warmed`);
|
||||
const kvCheckKey = encodeURIComponent(`${DEPLOYMENT_KEY}|kv-warmed`);
|
||||
console.log(kvCheckKey);
|
||||
console.log(
|
||||
'url',
|
||||
@@ -189,7 +189,7 @@ const handler = async () => {
|
||||
header,
|
||||
);
|
||||
const stream = DirectoryStream.fromDirectory(directory);
|
||||
const cacheKey = getDirectoryCacheKey(FILE_NAME, {
|
||||
const cacheKey = getDirectoryCacheKey(DEPLOYMENT_KEY, {
|
||||
offset: entry.offset + header.leafDirectoryOffset,
|
||||
length: entry.length,
|
||||
});
|
||||
@@ -237,4 +237,7 @@ process.on('uncaughtException', (e) => {
|
||||
|
||||
handler()
|
||||
.then(() => console.log('Done'))
|
||||
.catch((e) => console.error(e));
|
||||
.catch((e) => {
|
||||
console.error('Error', e);
|
||||
throw e;
|
||||
});
|
||||
|
||||
@@ -122,14 +122,14 @@ export class PMTilesService {
|
||||
metrics: IMetricsRepository,
|
||||
): Promise<PMTilesService> {
|
||||
const p = new PMTilesService(source, memCache, kvCache, metrics);
|
||||
const headerCacheKey = getHeaderCacheKey(source.getFileName());
|
||||
const headerCacheKey = getHeaderCacheKey(source.getDeploymentKey());
|
||||
if (memCache.get(headerCacheKey)) {
|
||||
return p;
|
||||
}
|
||||
const [header, root] = await p.getHeaderAndRootFromSource();
|
||||
memCache.set(headerCacheKey, header);
|
||||
memCache.set(
|
||||
getDirectoryCacheKey(source.getFileName(), {
|
||||
getDirectoryCacheKey(source.getDeploymentKey(), {
|
||||
offset: header.rootDirectoryOffset,
|
||||
length: header.rootDirectoryLength,
|
||||
}),
|
||||
@@ -139,7 +139,7 @@ export class PMTilesService {
|
||||
}
|
||||
|
||||
private getHeader(): Header {
|
||||
const key = getHeaderCacheKey(this.source.getFileName());
|
||||
const key = getHeaderCacheKey(this.source.getDeploymentKey());
|
||||
const memCached = this.memCache.get<Header>(key);
|
||||
if (!memCached) {
|
||||
throw new Error('Header not found in cache');
|
||||
@@ -148,7 +148,7 @@ export class PMTilesService {
|
||||
}
|
||||
|
||||
private getRootDirectory(header: Header): Directory {
|
||||
const key = getDirectoryCacheKey(this.source.getFileName(), {
|
||||
const key = getDirectoryCacheKey(this.source.getDeploymentKey(), {
|
||||
offset: header.rootDirectoryOffset,
|
||||
length: header.rootDirectoryLength,
|
||||
});
|
||||
@@ -160,7 +160,7 @@ export class PMTilesService {
|
||||
}
|
||||
|
||||
async getHeaderAndRootFromSource(): Promise<[Header, Directory]> {
|
||||
const resp = await this.source.get({ offset: 0, length: 16384 });
|
||||
const resp = await this.source.getRange({ offset: 0, length: 16384 });
|
||||
const v = new DataView(resp);
|
||||
if (v.getUint16(0, true) !== 0x4d50) {
|
||||
throw new Error('Wrong magic number for PMTiles archive');
|
||||
@@ -181,7 +181,7 @@ export class PMTilesService {
|
||||
}
|
||||
|
||||
private async getDirectory(offset: number, length: number): Promise<DirectoryStream> {
|
||||
const cacheKey = getDirectoryCacheKey(this.source.getFileName(), { offset, length });
|
||||
const cacheKey = getDirectoryCacheKey(this.source.getDeploymentKey(), { offset, length });
|
||||
console.log(cacheKey);
|
||||
const kvValueStream = await this.kvCache.getAsStream(cacheKey);
|
||||
if (kvValueStream) {
|
||||
@@ -227,7 +227,7 @@ export class PMTilesService {
|
||||
)(tileId);
|
||||
}
|
||||
const tile = await this.metrics.monitorAsyncFunction({ name: 'get_tile' }, (offset, length) =>
|
||||
this.source.getAsStream({ offset, length }),
|
||||
this.source.getRangeAsStream({ offset, length }),
|
||||
)(header.tileDataOffset + offset, length);
|
||||
return tile;
|
||||
}
|
||||
@@ -235,7 +235,7 @@ export class PMTilesService {
|
||||
private async getMetadata(): Promise<Metadata> {
|
||||
const header = this.getHeader();
|
||||
|
||||
const resp = await this.source.get({
|
||||
const resp = await this.source.getRange({
|
||||
offset: header.jsonMetadataOffset,
|
||||
length: header.jsonMetadataLength,
|
||||
});
|
||||
|
||||
@@ -269,5 +269,5 @@ export function getHeaderCacheKey(archiveName: string): string {
|
||||
}
|
||||
|
||||
export function getDirectoryCacheKey(fileName: string, range: { offset: number; length: number }): string {
|
||||
return `${fileName}|prodv1|${range.offset}|${range.length}`;
|
||||
return `${fileName}|${range.offset}|${range.length}`;
|
||||
}
|
||||
|
||||
+44
-22
@@ -42,42 +42,53 @@ export class MemCacheRepository implements IMemCacheRepository {
|
||||
export class R2StorageRepository implements IStorageRepository {
|
||||
constructor(
|
||||
private buckets: { [key: string]: R2Bucket },
|
||||
private fileName: string,
|
||||
private deploymentKey: string,
|
||||
private metrics: IMetricsRepository,
|
||||
) {}
|
||||
|
||||
getFileName(): string {
|
||||
return this.fileName;
|
||||
getDeploymentKey(): string {
|
||||
return this.deploymentKey;
|
||||
}
|
||||
|
||||
private async getR2Object(range: { offset: number; length: number }) {
|
||||
private async getR2Object(args: { key?: string; range?: { offset: number; length: number } }) {
|
||||
const { key, range } = args;
|
||||
const fileName = key ?? 'tiles.pmtiles';
|
||||
const filePath = `${this.deploymentKey}/${fileName}`;
|
||||
const metric = Metric.create('r2_storage_get');
|
||||
const { offset, length } = range;
|
||||
const { key: bucketKey, resp } = await Promise.race(
|
||||
Object.entries(this.buckets).map(async ([key, bucket]) => {
|
||||
const resp = await bucket.get(this.fileName, {
|
||||
range: { offset, length },
|
||||
const resp = await bucket.get(filePath, {
|
||||
range,
|
||||
});
|
||||
return { key, resp };
|
||||
}),
|
||||
);
|
||||
metric.durationField(`${bucketKey}_duration`);
|
||||
metric.addTag('bucket_key', bucketKey);
|
||||
metric.addTag('file_name', fileName);
|
||||
metric.intField('count', 1);
|
||||
this.metrics.push(metric);
|
||||
|
||||
if (!resp) {
|
||||
throw new Error('Archive not found');
|
||||
throw new Error(`Key not found ${filePath}`);
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
async get(range: { offset: number; length: number }): Promise<ArrayBuffer> {
|
||||
return (await this.getR2Object(range)).arrayBuffer();
|
||||
async getRange(range: { offset: number; length: number }): Promise<ArrayBuffer> {
|
||||
return (await this.getR2Object({ range })).arrayBuffer();
|
||||
}
|
||||
|
||||
async getAsStream(range: { offset: number; length: number }): Promise<ReadableStream> {
|
||||
return (await this.getR2Object(range)).body;
|
||||
async getRangeAsStream(range: { offset: number; length: number }): Promise<ReadableStream> {
|
||||
return (await this.getR2Object({ range })).body;
|
||||
}
|
||||
|
||||
async get(key: string): Promise<ArrayBuffer> {
|
||||
return (await this.getR2Object({ key })).arrayBuffer();
|
||||
}
|
||||
|
||||
async getAsStream(key: string): Promise<ReadableStream> {
|
||||
return (await this.getR2Object({ key })).body;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,14 +96,15 @@ export class S3StorageRepository implements IStorageRepository {
|
||||
constructor(
|
||||
private client: S3Client,
|
||||
private bucketKey: string,
|
||||
private fileName: string,
|
||||
private deploymentKey: string,
|
||||
) {}
|
||||
|
||||
private async getS3Object(range: { offset: number; length: number }) {
|
||||
private async getS3Object(args: { key?: string; range?: { offset: number; length: number } }) {
|
||||
const { range } = args;
|
||||
const command = new GetObjectCommand({
|
||||
Bucket: this.bucketKey,
|
||||
Key: this.fileName,
|
||||
Range: `bytes=${range.offset}-${range.offset + range.length - 1}`,
|
||||
Key: this.deploymentKey + '/' + (args.key ?? 'tiles.pmtiles'),
|
||||
Range: range ? `bytes=${range.offset}-${range.offset + range.length - 1}` : undefined,
|
||||
});
|
||||
const response = await this.client.send(command);
|
||||
const data = response.Body;
|
||||
@@ -102,18 +114,28 @@ export class S3StorageRepository implements IStorageRepository {
|
||||
return data;
|
||||
}
|
||||
|
||||
async get(range: { length: number; offset: number }): Promise<ArrayBuffer> {
|
||||
const data = await this.getS3Object(range);
|
||||
async getRange(range: { length: number; offset: number }): Promise<ArrayBuffer> {
|
||||
const data = await this.getS3Object({ range });
|
||||
return (await data.transformToByteArray()).buffer;
|
||||
}
|
||||
|
||||
async getAsStream(range: { length: number; offset: number }): Promise<ReadableStream> {
|
||||
const data = await this.getS3Object(range);
|
||||
async getRangeAsStream(range: { length: number; offset: number }): Promise<ReadableStream> {
|
||||
const data = await this.getS3Object({ range });
|
||||
return data.transformToWebStream();
|
||||
}
|
||||
|
||||
getFileName(): string {
|
||||
return this.fileName;
|
||||
async get(key: string): Promise<ArrayBuffer> {
|
||||
const data = await this.getS3Object({ key });
|
||||
return (await data.transformToByteArray()).buffer;
|
||||
}
|
||||
|
||||
async getAsStream(key: string): Promise<ReadableStream> {
|
||||
const data = await this.getS3Object({ key });
|
||||
return data.transformToWebStream();
|
||||
}
|
||||
|
||||
getDeploymentKey(): string {
|
||||
return this.deploymentKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -10,20 +10,27 @@ describe('integration tests', () => {
|
||||
describe('success - zoom1', () => {
|
||||
beforeAll(async () => {
|
||||
const buckets = [env.BUCKET_WEUR, env.BUCKET_WNAM, env.BUCKET_EEUR, env.BUCKET_APAC, env.BUCKET_ENAM];
|
||||
const files = ['tiles.pmtiles', 'styles/dark.json', 'styles/light.json'];
|
||||
for (const bucket of buckets) {
|
||||
const file = await fetch(`http://localhost:${inject('port')}/zoom1.pmtiles`);
|
||||
if (!file.body) {
|
||||
throw new Error('File body is undefined');
|
||||
for (const fileName of files) {
|
||||
const file = await fetch(`http://localhost:${inject('port')}/${fileName}`);
|
||||
if (!file.body) {
|
||||
throw new Error('File body is undefined');
|
||||
}
|
||||
const body = file.body as ReadableStream;
|
||||
await bucket.put(`${env.DEPLOYMENT_KEY}/${fileName}`, body);
|
||||
console.log('File uploaded');
|
||||
}
|
||||
const body = file.body as ReadableStream;
|
||||
await bucket.put(env.PMTILES_FILE_NAME, body);
|
||||
console.log('File uploaded');
|
||||
}
|
||||
}, 30000);
|
||||
it('responds with correct json file', async () => {
|
||||
const response = await SELF.fetch('https://example.com/v1');
|
||||
await expect(JSON.stringify(await response.json(), null, 2)).toMatchFileSnapshot('./__snapshots__/v1.json');
|
||||
});
|
||||
it('response with correct style', async () => {
|
||||
const response = await SELF.fetch('https://example.com/v1/style/dark');
|
||||
await expect(JSON.stringify(await response.json(), null, 2)).toMatchFileSnapshot('./assets/styles/dark.json');
|
||||
});
|
||||
it('responds with correct tile', async () => {
|
||||
const response = await SELF.fetch('https://example.com/v1/0/0/0.mvt');
|
||||
expect(response.status).toBe(200);
|
||||
@@ -73,6 +80,21 @@ describe('parseUrl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it.each`
|
||||
url | style | version
|
||||
${'http://example.com/v1/style/dark'} | ${'dark'} | ${'1'}
|
||||
${'http://example.com/v2/style/light'} | ${'light'} | ${'2'}
|
||||
${'http://example.com/v2/style/dark.json'} | ${'dark'} | ${'2'}
|
||||
${'http://example.com/v1/style/light.json'} | ${'light'} | ${'1'}
|
||||
`('style endpoint $url returns style $style', ({ url, style }) => {
|
||||
const result = parseUrl(new Request(url));
|
||||
expect(result).toStrictEqual({
|
||||
requestType: 'style',
|
||||
style,
|
||||
url: new URL(url),
|
||||
});
|
||||
});
|
||||
|
||||
it.each`
|
||||
url | version | z | x | y
|
||||
${'http://example.com/v1/0/0/0.mvt'} | ${'1'} | ${'0'} | ${'0'} | ${'0'}
|
||||
|
||||
Vendored
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
interface Env {
|
||||
KV: KVNamespace;
|
||||
PMTILES_FILE_NAME: "v1.pmtiles";
|
||||
DEPLOYMENT_KEY: "20240812";
|
||||
ENVIRONMENT: "prod";
|
||||
BUCKET_WNAM: R2Bucket;
|
||||
BUCKET_ENAM: R2Bucket;
|
||||
|
||||
+1
-1
@@ -40,5 +40,5 @@ preview_bucket_name = "tiles-apac"
|
||||
|
||||
# Define environment variables for your Workers script
|
||||
[vars]
|
||||
PMTILES_FILE_NAME = "v1.pmtiles"
|
||||
DEPLOYMENT_KEY = "20240812"
|
||||
ENVIRONMENT = "production"
|
||||
|
||||
Reference in New Issue
Block a user