├── .gitignore ├── README.md ├── api └── sites.ts ├── kysely-types.ts ├── package-lock.json ├── package.json ├── tsconfig.json └── vercel.json /.gitignore: -------------------------------------------------------------------------------- 1 | .vercel 2 | .env 3 | .env.* 4 | node_modules 5 | .env*.local 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # neon-vercel-kysely 2 | 3 | This repo demonstrates [kysely](https://github.com/koskimas/kysely) and [kysely-codegen](https://github.com/RobinBlomberg/kysely-codegen) using [Neon's serverless driver](https://www.npmjs.com/package/@neondatabase/serverless) on [Vercel](https://vercel.com/) Edge Functions. 4 | 5 | We implement a simple app that generates a JSON listing of the user's nearest 10 UNESCO World Heritage sites via IP geolocation (data copyright © 1992 – 2022 [UNESCO/World Heritage Centre](https://whc.unesco.org/en/syndication/)). 6 | 7 | 8 | ## How it works 9 | 10 | The kysely package doesn't attempt to import the `pg` package, making it straightforward to use with `@neondatabase/serverless`. 11 | 12 | For kysely-codegen, we generate an ordinary TypeScript `.ts` file that's explicitly included among and imported from the source files (instead of a `.d.ts` declaration file that's tucked away inside `node_modules`). This prevents errors by ensuring the types are included when the Edge Function is built and deployed. The types file is at `./kysely-types.ts`. 13 | 14 | 15 | ## Deploy 16 | 17 | * Ensure the `psql` client is installed. 18 | 19 | * Create a Neon database and make a note of the connection string from the [Neon console](https://console.neon.tech/). 20 | 21 | * Clone this repo, then: 22 | 23 | ```bash 24 | # get dependencies 25 | npm install 26 | npm install -g vercel@latest 27 | 28 | # create DATABASE_URL environment variable, remote and local 29 | npx vercel env add DATABASE_URL # paste in the connection string and select all environments 30 | npx vercel env pull .env.local # now bring it down into ./.env.local for local use 31 | 32 | # create the schema and copy data to DB 33 | (source .env.local \ 34 | && curl -s https://gist.githubusercontent.com/jawj/a8d53ff339707c65128af83b4783f4fe/raw/45dbcc819b00ecb72f80b0cf91e01b3d055662b5/whc-sites-2021.psql \ 35 | | psql $DATABASE_URL) 36 | 37 | # update kysely types from DB 38 | npm run update-kysely-types 39 | 40 | # test 41 | npx vercel dev 42 | 43 | # ... and deploy 44 | npx vercel deploy 45 | ``` 46 | 47 | ## Feedback and support 48 | 49 | Please visit [Neon Community](https://community.neon.tech/) or [Support](https://neon.tech/docs/introduction/support). -------------------------------------------------------------------------------- /api/sites.ts: -------------------------------------------------------------------------------- 1 | import { Pool } from '@neondatabase/serverless'; 2 | import { Kysely, PostgresDialect, sql } from 'kysely'; 3 | import type { DB } from '../kysely-types'; 4 | 5 | export default async (req: Request, ctx: any) => { 6 | const pool = new Pool({ connectionString: process.env.DATABASE_URL }); 7 | const db = new Kysely({ dialect: new PostgresDialect({ pool }) }); 8 | 9 | const longitude = parseFloat(req.headers.get('x-vercel-ip-longitude') ?? '-122.47'); 10 | const latitude = parseFloat(req.headers.get('x-vercel-ip-latitude') ?? '37.81'); 11 | 12 | const distance = sql`location <-> st_makepoint(${longitude}, ${latitude})`; 13 | const link = sql`'https://whc.unesco.org/en/list/' || id_no || '/'`; 14 | 15 | const query = db 16 | .selectFrom('whc_sites_2021') 17 | .select(['id_no', 'name_en', 'category', link.as('link'), distance.as('distance')]) 18 | .orderBy('distance') 19 | .limit(10); 20 | 21 | /* 22 | // uncomment these lines for visibility into the issued SQL + parameters 23 | const querySQL = query.compile(); 24 | console.log(querySQL.sql, querySQL.parameters); 25 | */ 26 | 27 | const sites = await query.execute(); 28 | ctx.waitUntil(pool.end()); 29 | 30 | return new Response(JSON.stringify({ longitude, latitude, sites }, null, 2)); 31 | } 32 | 33 | export const config = { 34 | runtime: 'edge', 35 | regions: ['fra1'], // fra1 = Frankfurt: pick the Vercel region nearest your Neon DB 36 | }; 37 | -------------------------------------------------------------------------------- /kysely-types.ts: -------------------------------------------------------------------------------- 1 | export type Category = "Cultural" | "Mixed" | "Natural"; 2 | 3 | export type CategoryShort = "C" | "C/N" | "N"; 4 | 5 | export interface Employees { 6 | emp_no: number | null; 7 | first_name: string | null; 8 | last_name: string | null; 9 | } 10 | 11 | export interface GeographyColumns { 12 | f_table_catalog: string | null; 13 | f_table_schema: string | null; 14 | f_table_name: string | null; 15 | f_geography_column: string | null; 16 | coord_dimension: number | null; 17 | srid: number | null; 18 | type: string | null; 19 | } 20 | 21 | export interface GeometryColumns { 22 | f_table_catalog: string | null; 23 | f_table_schema: string | null; 24 | f_table_name: string | null; 25 | f_geometry_column: string | null; 26 | coord_dimension: number | null; 27 | srid: number | null; 28 | type: string | null; 29 | } 30 | 31 | export interface Pokemon { 32 | id: number; 33 | name: string; 34 | type: string; 35 | } 36 | 37 | export interface WhcSites2021 { 38 | unique_number: number; 39 | id_no: number; 40 | rev_bis: string | null; 41 | name_en: string; 42 | name_fr: string; 43 | short_description_en: string; 44 | short_description_fr: string; 45 | justification_en: string | null; 46 | justification_fr: string | null; 47 | date_inscribed: number; 48 | secondary_dates: string | null; 49 | danger: number | null; 50 | date_end: number | null; 51 | danger_list: string | null; 52 | longitude: number; 53 | latitude: number; 54 | area_hectares: number | null; 55 | c1: number; 56 | c2: number; 57 | c3: number; 58 | c4: number; 59 | c5: number; 60 | c6: number; 61 | n7: number; 62 | n8: number; 63 | n9: number; 64 | n10: number; 65 | criteria_txt: string; 66 | category: Category; 67 | category_short: CategoryShort; 68 | states_name_en: string; 69 | states_name_fr: string; 70 | region_en: string; 71 | region_fr: string; 72 | iso_code: string | null; 73 | udnp_code: string | null; 74 | transboundary: number; 75 | location: string | null; 76 | } 77 | 78 | export interface DB { 79 | employees: Employees; 80 | geography_columns: GeographyColumns; 81 | geometry_columns: GeometryColumns; 82 | pokemon: Pokemon; 83 | whc_sites_2021: WhcSites2021; 84 | } 85 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "neon-vercel-kysely", 3 | "version": "0.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "neon-vercel-kysely", 9 | "version": "0.1.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@neondatabase/serverless": "^0.4.1", 13 | "kysely": "^0.25.0" 14 | }, 15 | "devDependencies": { 16 | "@types/pg": "^8.6.6", 17 | "env-cmd": "^10.1.0", 18 | "kysely-codegen": "^0.10.0", 19 | "pg": "^8.9.0", 20 | "typescript": "^5.0.4" 21 | } 22 | }, 23 | "node_modules/@neondatabase/serverless": { 24 | "version": "0.4.22", 25 | "resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-0.4.22.tgz", 26 | "integrity": "sha512-eI3XsvedtW9ENul+E4QdVuhC+7f4gKMA76r12lk8YgdceB0ov3Axa9Ca4nvDgvfmmj9EFVsseAxAoOXcf31M4g==", 27 | "dependencies": { 28 | "@types/pg": "8.6.6" 29 | } 30 | }, 31 | "node_modules/@neondatabase/serverless/node_modules/@types/pg": { 32 | "version": "8.6.6", 33 | "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.6.tgz", 34 | "integrity": "sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==", 35 | "dependencies": { 36 | "@types/node": "*", 37 | "pg-protocol": "*", 38 | "pg-types": "^2.2.0" 39 | } 40 | }, 41 | "node_modules/@neondatabase/serverless/node_modules/pg-types": { 42 | "version": "2.2.0", 43 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", 44 | "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", 45 | "dependencies": { 46 | "pg-int8": "1.0.1", 47 | "postgres-array": "~2.0.0", 48 | "postgres-bytea": "~1.0.0", 49 | "postgres-date": "~1.0.4", 50 | "postgres-interval": "^1.1.0" 51 | }, 52 | "engines": { 53 | "node": ">=4" 54 | } 55 | }, 56 | "node_modules/@neondatabase/serverless/node_modules/postgres-array": { 57 | "version": "2.0.0", 58 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", 59 | "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", 60 | "engines": { 61 | "node": ">=4" 62 | } 63 | }, 64 | "node_modules/@neondatabase/serverless/node_modules/postgres-bytea": { 65 | "version": "1.0.0", 66 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", 67 | "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", 68 | "engines": { 69 | "node": ">=0.10.0" 70 | } 71 | }, 72 | "node_modules/@neondatabase/serverless/node_modules/postgres-date": { 73 | "version": "1.0.7", 74 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", 75 | "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", 76 | "engines": { 77 | "node": ">=0.10.0" 78 | } 79 | }, 80 | "node_modules/@neondatabase/serverless/node_modules/postgres-interval": { 81 | "version": "1.2.0", 82 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", 83 | "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", 84 | "dependencies": { 85 | "xtend": "^4.0.0" 86 | }, 87 | "engines": { 88 | "node": ">=0.10.0" 89 | } 90 | }, 91 | "node_modules/@types/node": { 92 | "version": "20.3.2", 93 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", 94 | "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==" 95 | }, 96 | "node_modules/@types/pg": { 97 | "version": "8.10.2", 98 | "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.2.tgz", 99 | "integrity": "sha512-MKFs9P6nJ+LAeHLU3V0cODEOgyThJ3OAnmOlsZsxux6sfQs3HRXR5bBn7xG5DjckEFhTAxsXi7k7cd0pCMxpJw==", 100 | "dev": true, 101 | "dependencies": { 102 | "@types/node": "*", 103 | "pg-protocol": "*", 104 | "pg-types": "^4.0.1" 105 | } 106 | }, 107 | "node_modules/ansi-styles": { 108 | "version": "4.3.0", 109 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 110 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 111 | "dev": true, 112 | "dependencies": { 113 | "color-convert": "^2.0.1" 114 | }, 115 | "engines": { 116 | "node": ">=8" 117 | }, 118 | "funding": { 119 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 120 | } 121 | }, 122 | "node_modules/braces": { 123 | "version": "3.0.2", 124 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 125 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 126 | "dev": true, 127 | "dependencies": { 128 | "fill-range": "^7.0.1" 129 | }, 130 | "engines": { 131 | "node": ">=8" 132 | } 133 | }, 134 | "node_modules/buffer-writer": { 135 | "version": "2.0.0", 136 | "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", 137 | "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", 138 | "dev": true, 139 | "engines": { 140 | "node": ">=4" 141 | } 142 | }, 143 | "node_modules/chalk": { 144 | "version": "4.1.2", 145 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 146 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 147 | "dev": true, 148 | "dependencies": { 149 | "ansi-styles": "^4.1.0", 150 | "supports-color": "^7.1.0" 151 | }, 152 | "engines": { 153 | "node": ">=10" 154 | }, 155 | "funding": { 156 | "url": "https://github.com/chalk/chalk?sponsor=1" 157 | } 158 | }, 159 | "node_modules/color-convert": { 160 | "version": "2.0.1", 161 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 162 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 163 | "dev": true, 164 | "dependencies": { 165 | "color-name": "~1.1.4" 166 | }, 167 | "engines": { 168 | "node": ">=7.0.0" 169 | } 170 | }, 171 | "node_modules/color-name": { 172 | "version": "1.1.4", 173 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 174 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 175 | "dev": true 176 | }, 177 | "node_modules/commander": { 178 | "version": "4.1.1", 179 | "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", 180 | "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", 181 | "dev": true, 182 | "engines": { 183 | "node": ">= 6" 184 | } 185 | }, 186 | "node_modules/cross-spawn": { 187 | "version": "7.0.3", 188 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 189 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 190 | "dev": true, 191 | "dependencies": { 192 | "path-key": "^3.1.0", 193 | "shebang-command": "^2.0.0", 194 | "which": "^2.0.1" 195 | }, 196 | "engines": { 197 | "node": ">= 8" 198 | } 199 | }, 200 | "node_modules/dotenv": { 201 | "version": "16.3.1", 202 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", 203 | "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", 204 | "dev": true, 205 | "engines": { 206 | "node": ">=12" 207 | }, 208 | "funding": { 209 | "url": "https://github.com/motdotla/dotenv?sponsor=1" 210 | } 211 | }, 212 | "node_modules/env-cmd": { 213 | "version": "10.1.0", 214 | "resolved": "https://registry.npmjs.org/env-cmd/-/env-cmd-10.1.0.tgz", 215 | "integrity": "sha512-mMdWTT9XKN7yNth/6N6g2GuKuJTsKMDHlQFUDacb/heQRRWOTIZ42t1rMHnQu4jYxU1ajdTeJM+9eEETlqToMA==", 216 | "dev": true, 217 | "dependencies": { 218 | "commander": "^4.0.0", 219 | "cross-spawn": "^7.0.0" 220 | }, 221 | "bin": { 222 | "env-cmd": "bin/env-cmd.js" 223 | }, 224 | "engines": { 225 | "node": ">=8.0.0" 226 | } 227 | }, 228 | "node_modules/fill-range": { 229 | "version": "7.0.1", 230 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 231 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 232 | "dev": true, 233 | "dependencies": { 234 | "to-regex-range": "^5.0.1" 235 | }, 236 | "engines": { 237 | "node": ">=8" 238 | } 239 | }, 240 | "node_modules/has-flag": { 241 | "version": "4.0.0", 242 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 243 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 244 | "dev": true, 245 | "engines": { 246 | "node": ">=8" 247 | } 248 | }, 249 | "node_modules/is-number": { 250 | "version": "7.0.0", 251 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 252 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 253 | "dev": true, 254 | "engines": { 255 | "node": ">=0.12.0" 256 | } 257 | }, 258 | "node_modules/isexe": { 259 | "version": "2.0.0", 260 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 261 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 262 | "dev": true 263 | }, 264 | "node_modules/kysely": { 265 | "version": "0.25.0", 266 | "resolved": "https://registry.npmjs.org/kysely/-/kysely-0.25.0.tgz", 267 | "integrity": "sha512-srn0efIMu5IoEBk0tBmtGnoUss4uwvxtbFQWG/U2MosfqIace1l43IFP1PmEpHRDp+Z79xIcKEqmHH3dAvQdQA==", 268 | "engines": { 269 | "node": ">=14.0.0" 270 | } 271 | }, 272 | "node_modules/kysely-codegen": { 273 | "version": "0.10.1", 274 | "resolved": "https://registry.npmjs.org/kysely-codegen/-/kysely-codegen-0.10.1.tgz", 275 | "integrity": "sha512-8Bslh952gN5gtucRv4jTZDFD18RBioS6M50zHfe5kwb5iSyEAunU4ZYMdHzkHraa4zxjg5/183XlOryBCXLRIw==", 276 | "dev": true, 277 | "dependencies": { 278 | "chalk": "4.1.2", 279 | "dotenv": "^16.0.3", 280 | "micromatch": "^4.0.5", 281 | "minimist": "^1.2.8" 282 | }, 283 | "bin": { 284 | "kysely-codegen": "dist/bin/index.js" 285 | }, 286 | "peerDependencies": { 287 | "better-sqlite3": ">=7.6.2", 288 | "kysely": ">=0.19.12", 289 | "mysql2": "^2.3.3 || ^3.0.0", 290 | "pg": "^8.8.0" 291 | }, 292 | "peerDependenciesMeta": { 293 | "better-sqlite3": { 294 | "optional": true 295 | }, 296 | "kysely": { 297 | "optional": false 298 | }, 299 | "mysql2": { 300 | "optional": true 301 | }, 302 | "pg": { 303 | "optional": true 304 | } 305 | } 306 | }, 307 | "node_modules/micromatch": { 308 | "version": "4.0.5", 309 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 310 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 311 | "dev": true, 312 | "dependencies": { 313 | "braces": "^3.0.2", 314 | "picomatch": "^2.3.1" 315 | }, 316 | "engines": { 317 | "node": ">=8.6" 318 | } 319 | }, 320 | "node_modules/minimist": { 321 | "version": "1.2.8", 322 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 323 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 324 | "dev": true, 325 | "funding": { 326 | "url": "https://github.com/sponsors/ljharb" 327 | } 328 | }, 329 | "node_modules/obuf": { 330 | "version": "1.1.2", 331 | "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", 332 | "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", 333 | "dev": true 334 | }, 335 | "node_modules/packet-reader": { 336 | "version": "1.0.0", 337 | "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", 338 | "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==", 339 | "dev": true 340 | }, 341 | "node_modules/path-key": { 342 | "version": "3.1.1", 343 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 344 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 345 | "dev": true, 346 | "engines": { 347 | "node": ">=8" 348 | } 349 | }, 350 | "node_modules/pg": { 351 | "version": "8.11.1", 352 | "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.1.tgz", 353 | "integrity": "sha512-utdq2obft07MxaDg0zBJI+l/M3mBRfIpEN3iSemsz0G5F2/VXx+XzqF4oxrbIZXQxt2AZzIUzyVg/YM6xOP/WQ==", 354 | "dev": true, 355 | "dependencies": { 356 | "buffer-writer": "2.0.0", 357 | "packet-reader": "1.0.0", 358 | "pg-connection-string": "^2.6.1", 359 | "pg-pool": "^3.6.1", 360 | "pg-protocol": "^1.6.0", 361 | "pg-types": "^2.1.0", 362 | "pgpass": "1.x" 363 | }, 364 | "engines": { 365 | "node": ">= 8.0.0" 366 | }, 367 | "optionalDependencies": { 368 | "pg-cloudflare": "^1.1.1" 369 | }, 370 | "peerDependencies": { 371 | "pg-native": ">=3.0.1" 372 | }, 373 | "peerDependenciesMeta": { 374 | "pg-native": { 375 | "optional": true 376 | } 377 | } 378 | }, 379 | "node_modules/pg-cloudflare": { 380 | "version": "1.1.1", 381 | "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", 382 | "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", 383 | "dev": true, 384 | "optional": true 385 | }, 386 | "node_modules/pg-connection-string": { 387 | "version": "2.6.1", 388 | "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.1.tgz", 389 | "integrity": "sha512-w6ZzNu6oMmIzEAYVw+RLK0+nqHPt8K3ZnknKi+g48Ak2pr3dtljJW3o+D/n2zzCG07Zoe9VOX3aiKpj+BN0pjg==", 390 | "dev": true 391 | }, 392 | "node_modules/pg-int8": { 393 | "version": "1.0.1", 394 | "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", 395 | "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", 396 | "engines": { 397 | "node": ">=4.0.0" 398 | } 399 | }, 400 | "node_modules/pg-numeric": { 401 | "version": "1.0.2", 402 | "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", 403 | "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", 404 | "dev": true, 405 | "engines": { 406 | "node": ">=4" 407 | } 408 | }, 409 | "node_modules/pg-pool": { 410 | "version": "3.6.1", 411 | "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", 412 | "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", 413 | "dev": true, 414 | "peerDependencies": { 415 | "pg": ">=8.0" 416 | } 417 | }, 418 | "node_modules/pg-protocol": { 419 | "version": "1.6.0", 420 | "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", 421 | "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" 422 | }, 423 | "node_modules/pg-types": { 424 | "version": "4.0.1", 425 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz", 426 | "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", 427 | "dev": true, 428 | "dependencies": { 429 | "pg-int8": "1.0.1", 430 | "pg-numeric": "1.0.2", 431 | "postgres-array": "~3.0.1", 432 | "postgres-bytea": "~3.0.0", 433 | "postgres-date": "~2.0.1", 434 | "postgres-interval": "^3.0.0", 435 | "postgres-range": "^1.1.1" 436 | }, 437 | "engines": { 438 | "node": ">=10" 439 | } 440 | }, 441 | "node_modules/pg/node_modules/pg-types": { 442 | "version": "2.2.0", 443 | "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", 444 | "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", 445 | "dev": true, 446 | "dependencies": { 447 | "pg-int8": "1.0.1", 448 | "postgres-array": "~2.0.0", 449 | "postgres-bytea": "~1.0.0", 450 | "postgres-date": "~1.0.4", 451 | "postgres-interval": "^1.1.0" 452 | }, 453 | "engines": { 454 | "node": ">=4" 455 | } 456 | }, 457 | "node_modules/pg/node_modules/postgres-array": { 458 | "version": "2.0.0", 459 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", 460 | "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", 461 | "dev": true, 462 | "engines": { 463 | "node": ">=4" 464 | } 465 | }, 466 | "node_modules/pg/node_modules/postgres-bytea": { 467 | "version": "1.0.0", 468 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", 469 | "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", 470 | "dev": true, 471 | "engines": { 472 | "node": ">=0.10.0" 473 | } 474 | }, 475 | "node_modules/pg/node_modules/postgres-date": { 476 | "version": "1.0.7", 477 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", 478 | "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", 479 | "dev": true, 480 | "engines": { 481 | "node": ">=0.10.0" 482 | } 483 | }, 484 | "node_modules/pg/node_modules/postgres-interval": { 485 | "version": "1.2.0", 486 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", 487 | "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", 488 | "dev": true, 489 | "dependencies": { 490 | "xtend": "^4.0.0" 491 | }, 492 | "engines": { 493 | "node": ">=0.10.0" 494 | } 495 | }, 496 | "node_modules/pgpass": { 497 | "version": "1.0.5", 498 | "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", 499 | "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", 500 | "dev": true, 501 | "dependencies": { 502 | "split2": "^4.1.0" 503 | } 504 | }, 505 | "node_modules/picomatch": { 506 | "version": "2.3.1", 507 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 508 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 509 | "dev": true, 510 | "engines": { 511 | "node": ">=8.6" 512 | }, 513 | "funding": { 514 | "url": "https://github.com/sponsors/jonschlinkert" 515 | } 516 | }, 517 | "node_modules/postgres-array": { 518 | "version": "3.0.2", 519 | "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", 520 | "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", 521 | "dev": true, 522 | "engines": { 523 | "node": ">=12" 524 | } 525 | }, 526 | "node_modules/postgres-bytea": { 527 | "version": "3.0.0", 528 | "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", 529 | "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", 530 | "dev": true, 531 | "dependencies": { 532 | "obuf": "~1.1.2" 533 | }, 534 | "engines": { 535 | "node": ">= 6" 536 | } 537 | }, 538 | "node_modules/postgres-date": { 539 | "version": "2.0.1", 540 | "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz", 541 | "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", 542 | "dev": true, 543 | "engines": { 544 | "node": ">=12" 545 | } 546 | }, 547 | "node_modules/postgres-interval": { 548 | "version": "3.0.0", 549 | "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", 550 | "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", 551 | "dev": true, 552 | "engines": { 553 | "node": ">=12" 554 | } 555 | }, 556 | "node_modules/postgres-range": { 557 | "version": "1.1.3", 558 | "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz", 559 | "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==", 560 | "dev": true 561 | }, 562 | "node_modules/shebang-command": { 563 | "version": "2.0.0", 564 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 565 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 566 | "dev": true, 567 | "dependencies": { 568 | "shebang-regex": "^3.0.0" 569 | }, 570 | "engines": { 571 | "node": ">=8" 572 | } 573 | }, 574 | "node_modules/shebang-regex": { 575 | "version": "3.0.0", 576 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 577 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 578 | "dev": true, 579 | "engines": { 580 | "node": ">=8" 581 | } 582 | }, 583 | "node_modules/split2": { 584 | "version": "4.2.0", 585 | "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", 586 | "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", 587 | "dev": true, 588 | "engines": { 589 | "node": ">= 10.x" 590 | } 591 | }, 592 | "node_modules/supports-color": { 593 | "version": "7.2.0", 594 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 595 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 596 | "dev": true, 597 | "dependencies": { 598 | "has-flag": "^4.0.0" 599 | }, 600 | "engines": { 601 | "node": ">=8" 602 | } 603 | }, 604 | "node_modules/to-regex-range": { 605 | "version": "5.0.1", 606 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 607 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 608 | "dev": true, 609 | "dependencies": { 610 | "is-number": "^7.0.0" 611 | }, 612 | "engines": { 613 | "node": ">=8.0" 614 | } 615 | }, 616 | "node_modules/typescript": { 617 | "version": "5.1.3", 618 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", 619 | "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", 620 | "dev": true, 621 | "bin": { 622 | "tsc": "bin/tsc", 623 | "tsserver": "bin/tsserver" 624 | }, 625 | "engines": { 626 | "node": ">=14.17" 627 | } 628 | }, 629 | "node_modules/which": { 630 | "version": "2.0.2", 631 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 632 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 633 | "dev": true, 634 | "dependencies": { 635 | "isexe": "^2.0.0" 636 | }, 637 | "bin": { 638 | "node-which": "bin/node-which" 639 | }, 640 | "engines": { 641 | "node": ">= 8" 642 | } 643 | }, 644 | "node_modules/xtend": { 645 | "version": "4.0.2", 646 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 647 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 648 | "engines": { 649 | "node": ">=0.4" 650 | } 651 | } 652 | } 653 | } 654 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "neon-vercel-kysely", 3 | "version": "0.1.0", 4 | "author": "George MacKerron", 5 | "license": "ISC", 6 | "scripts": { 7 | "update-kysely-types": "env-cmd -f .env.local kysely-codegen --out-file ./kysely-types.ts --exclude-pattern spatial_ref_sys" 8 | }, 9 | "dependencies": { 10 | "@neondatabase/serverless": "^0.4.1", 11 | "kysely": "^0.25.0" 12 | }, 13 | "devDependencies": { 14 | "@types/pg": "^8.6.6", 15 | "env-cmd": "^10.1.0", 16 | "kysely-codegen": "^0.10.0", 17 | "pg": "^8.9.0", 18 | "typescript": "^5.0.4" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "redirects": [ 3 | { 4 | "source": "/", 5 | "destination": "/api/sites" 6 | } 7 | ] 8 | } --------------------------------------------------------------------------------