snapshot of https://github.com/tldraw/tldraw.git (main, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
This commit is contained in:
2
apps/analytics-worker/.gitignore
vendored
Normal file
2
apps/analytics-worker/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
build
|
||||
.wrangler
|
||||
28
apps/analytics-worker/package.json
Normal file
28
apps/analytics-worker/package.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "@tldraw/analytics-worker",
|
||||
"description": "tldraw infinite canvas SDK (analytics worker).",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"author": {
|
||||
"name": "tldraw GB Ltd.",
|
||||
"email": "hello@tldraw.com"
|
||||
},
|
||||
"main": "./src/worker.ts",
|
||||
"/* GOTCHA */": "files will include ./dist and index.d.ts by default, add any others you want to include in here",
|
||||
"files": [],
|
||||
"scripts": {
|
||||
"dev": "yarn run -T tsx ../../internal/scripts/workers/dev.ts",
|
||||
"test-ci": "yarn run -T vitest run --passWithNoTests",
|
||||
"test": "yarn run -T vitest --passWithNoTests",
|
||||
"test-coverage": "yarn run -T vitest run --coverage --passWithNoTests",
|
||||
"check-bundle-size": "yarn run -T tsx ../../internal/scripts/check-worker-bundle.ts --entry src/worker.ts --size-limit-bytes 350000",
|
||||
"lint": "yarn run -T tsx ../../internal/scripts/lint.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20260302.0",
|
||||
"esbuild": "^0.28.0",
|
||||
"lazyrepo": "0.0.0-alpha.27",
|
||||
"typescript": "^7.0.2",
|
||||
"wrangler": "^4.75.0"
|
||||
}
|
||||
}
|
||||
117
apps/analytics-worker/src/worker.ts
Normal file
117
apps/analytics-worker/src/worker.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
/// <reference no-default-lib="true"/>
|
||||
/// <reference types="@cloudflare/workers-types" />
|
||||
|
||||
/**
|
||||
* Simple CloudFlare worker that returns whether the user requires cookie consent
|
||||
* based on their geographic location (via CF-IPCountry header)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Validates if an origin is allowed to make cross-origin requests.
|
||||
* Returns the origin if allowed, or undefined if blocked.
|
||||
*/
|
||||
function isAllowedOrigin(origin: string | null): string | undefined {
|
||||
if (!origin) return undefined
|
||||
if (origin === 'http://localhost:3000') return origin
|
||||
if (origin === 'http://localhost:3001') return origin
|
||||
if (origin === 'http://localhost:5420') return origin
|
||||
if (origin === 'https://meet.google.com') return origin
|
||||
if (origin === 'https://tldraw.dev') return origin
|
||||
if (origin.endsWith('.tldraw.com')) return origin
|
||||
if (origin.endsWith('.tldraw.dev')) return origin
|
||||
if (origin.endsWith('.tldraw.club')) return origin
|
||||
if (origin.endsWith('.tldraw.xyz')) return origin
|
||||
if (origin.endsWith('.tldraw.workers.dev')) return origin
|
||||
if (origin.endsWith('-tldraw.vercel.app')) return origin
|
||||
return undefined
|
||||
}
|
||||
|
||||
const EXPLICIT_CONSENT_COUNTRIES = [
|
||||
// EU Member States (GDPR)
|
||||
'AT',
|
||||
'BE',
|
||||
'BG',
|
||||
'HR',
|
||||
'CY',
|
||||
'CZ',
|
||||
'DK',
|
||||
'EE',
|
||||
'FI',
|
||||
'FR',
|
||||
'DE',
|
||||
'GR',
|
||||
'HU',
|
||||
'IE',
|
||||
'IT',
|
||||
'LV',
|
||||
'LT',
|
||||
'LU',
|
||||
'MT',
|
||||
'NL',
|
||||
'PL',
|
||||
'PT',
|
||||
'RO',
|
||||
'SK',
|
||||
'SI',
|
||||
'ES',
|
||||
'SE',
|
||||
// EEA/EFTA (GDPR)
|
||||
'IS',
|
||||
'LI',
|
||||
'NO',
|
||||
// Post-Brexit UK (UK PECR)
|
||||
'GB',
|
||||
// Switzerland (FADP)
|
||||
'CH',
|
||||
// Brazil (LGPD)
|
||||
'BR',
|
||||
]
|
||||
|
||||
export default {
|
||||
async fetch(request: Request): Promise<Response> {
|
||||
const origin = request.headers.get('origin')
|
||||
const allowedOrigin = isAllowedOrigin(origin)
|
||||
|
||||
// Handle CORS preflight
|
||||
if (request.method === 'OPTIONS') {
|
||||
const headers: Record<string, string> = {
|
||||
'Access-Control-Allow-Methods': 'GET, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type',
|
||||
'Access-Control-Max-Age': '86400',
|
||||
}
|
||||
if (allowedOrigin) {
|
||||
headers['Access-Control-Allow-Origin'] = allowedOrigin
|
||||
}
|
||||
return new Response(null, { headers })
|
||||
}
|
||||
|
||||
// Only allow GET requests
|
||||
if (request.method !== 'GET') {
|
||||
return new Response('Method not allowed', { status: 405 })
|
||||
}
|
||||
|
||||
// Get country code from CloudFlare header
|
||||
const countryCode = request.headers.get('CF-IPCountry')
|
||||
|
||||
// Check if consent is required
|
||||
// Default to requiring consent if country is unknown
|
||||
const requiresConsent = !countryCode || EXPLICIT_CONSENT_COUNTRIES.includes(countryCode)
|
||||
|
||||
// Return response with CORS headers
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'public, max-age=3600', // Cache for 1 hour
|
||||
}
|
||||
if (allowedOrigin) {
|
||||
headers['Access-Control-Allow-Origin'] = allowedOrigin
|
||||
}
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
requires_consent: requiresConsent,
|
||||
country_code: countryCode,
|
||||
}),
|
||||
{ headers }
|
||||
)
|
||||
},
|
||||
}
|
||||
7
apps/analytics-worker/tsconfig.json
Normal file
7
apps/analytics-worker/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../internal/config/tsconfig.base.json",
|
||||
"include": ["src", "scripts"],
|
||||
"exclude": ["node_modules", "dist", ".tsbuild*"],
|
||||
"compilerOptions": { "noEmit": true, "emitDeclarationOnly": false },
|
||||
"references": []
|
||||
}
|
||||
15
apps/analytics-worker/vitest.config.ts
Normal file
15
apps/analytics-worker/vitest.config.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/// <reference types="vitest" />
|
||||
import { mergeConfig } from 'vitest/config'
|
||||
import baseConfig from '../../internal/config/vitest/node-preset'
|
||||
|
||||
// bemo-worker is a Node.js/Cloudflare Worker environment
|
||||
export default mergeConfig(baseConfig, {
|
||||
test: {
|
||||
// Use node environment instead of jsdom for worker apps
|
||||
environment: 'node',
|
||||
// Module name mapping for path aliases
|
||||
alias: {
|
||||
'^~(.*)$': './src/$1',
|
||||
},
|
||||
},
|
||||
})
|
||||
44
apps/analytics-worker/wrangler.toml
Normal file
44
apps/analytics-worker/wrangler.toml
Normal file
@@ -0,0 +1,44 @@
|
||||
main = "src/worker.ts"
|
||||
compatibility_date = "2024-06-20"
|
||||
upload_source_maps = true
|
||||
|
||||
#################### Environment names ####################
|
||||
|
||||
# Dev environment
|
||||
[env.dev]
|
||||
name = "tldraw-consent-dev"
|
||||
|
||||
# Staging environment
|
||||
[env.staging]
|
||||
name = "tldraw-consent-staging"
|
||||
|
||||
# Staging environment
|
||||
[env.preview]
|
||||
name = "tldraw-consent-preview"
|
||||
|
||||
# Production environment
|
||||
[env.production]
|
||||
name = "tldraw-consent"
|
||||
|
||||
#################### Routes ####################
|
||||
# in production, we use a custom domain. others get a default *.tldraw.workers.dev domain
|
||||
[[env.production.routes]]
|
||||
pattern = 'consent.tldraw.xyz'
|
||||
custom_domain = true
|
||||
zone_name = 'tldraw.xyz'
|
||||
|
||||
#################### Version metadata ####################
|
||||
[version_metadata]
|
||||
binding = "CF_VERSION_METADATA"
|
||||
|
||||
[env.dev.version_metadata]
|
||||
binding = "CF_VERSION_METADATA"
|
||||
|
||||
[env.preview.version_metadata]
|
||||
binding = "CF_VERSION_METADATA"
|
||||
|
||||
[env.staging.version_metadata]
|
||||
binding = "CF_VERSION_METADATA"
|
||||
|
||||
[env.production.version_metadata]
|
||||
binding = "CF_VERSION_METADATA"
|
||||
Reference in New Issue
Block a user