├── .env.development.example ├── .env.test.example ├── .gitignore ├── .vscode └── settings.json ├── README.md ├── bun.lockb ├── db ├── db.ts └── seeders │ └── mock-users.seeder.ts ├── index.ts ├── package.json ├── src ├── controllers │ └── user.controller.ts ├── index.ts ├── models │ └── user.model.ts ├── routes │ └── users.ts └── tests │ ├── mocks │ └── user.factory.ts │ ├── models │ └── user.model.spec.ts │ └── setup.ts └── tsconfig.json /.env.development.example: -------------------------------------------------------------------------------- 1 | DB_FILE_PATH=REPLACE_ME -------------------------------------------------------------------------------- /.env.test.example: -------------------------------------------------------------------------------- 1 | DB_FILE_PATH=REPLACE_ME -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Caches 14 | 15 | .cache 16 | 17 | # Diagnostic reports (https://nodejs.org/api/report.html) 18 | 19 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 20 | 21 | # Runtime data 22 | 23 | pids 24 | _.pid 25 | _.seed 26 | *.pid.lock 27 | 28 | # Directory for instrumented libs generated by jscoverage/JSCover 29 | 30 | lib-cov 31 | 32 | # Coverage directory used by tools like istanbul 33 | 34 | coverage 35 | *.lcov 36 | 37 | # nyc test coverage 38 | 39 | .nyc_output 40 | 41 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 42 | 43 | .grunt 44 | 45 | # Bower dependency directory (https://bower.io/) 46 | 47 | bower_components 48 | 49 | # node-waf configuration 50 | 51 | .lock-wscript 52 | 53 | # Compiled binary addons (https://nodejs.org/api/addons.html) 54 | 55 | build/Release 56 | 57 | # Dependency directories 58 | 59 | node_modules/ 60 | jspm_packages/ 61 | 62 | # Snowpack dependency directory (https://snowpack.dev/) 63 | 64 | web_modules/ 65 | 66 | # TypeScript cache 67 | 68 | *.tsbuildinfo 69 | 70 | # Optional npm cache directory 71 | 72 | .npm 73 | 74 | # Optional eslint cache 75 | 76 | .eslintcache 77 | 78 | # Optional stylelint cache 79 | 80 | .stylelintcache 81 | 82 | # Microbundle cache 83 | 84 | .rpt2_cache/ 85 | .rts2_cache_cjs/ 86 | .rts2_cache_es/ 87 | .rts2_cache_umd/ 88 | 89 | # Optional REPL history 90 | 91 | .node_repl_history 92 | 93 | # Output of 'npm pack' 94 | 95 | *.tgz 96 | 97 | # Yarn Integrity file 98 | 99 | .yarn-integrity 100 | 101 | # dotenv environment variable files 102 | 103 | .env 104 | .env.development 105 | .env.development.local 106 | .env.test 107 | .env.test.local 108 | .env.production.local 109 | .env.local 110 | 111 | # parcel-bundler cache (https://parceljs.org/) 112 | 113 | .parcel-cache 114 | 115 | # Next.js build output 116 | 117 | .next 118 | out 119 | 120 | # Nuxt.js build / generate output 121 | 122 | .nuxt 123 | dist 124 | 125 | # Gatsby files 126 | 127 | # Comment in the public line in if your project uses Gatsby and not Next.js 128 | 129 | # https://nextjs.org/blog/next-9-1#public-directory-support 130 | 131 | # public 132 | 133 | # vuepress build output 134 | 135 | .vuepress/dist 136 | 137 | # vuepress v2.x temp and cache directory 138 | 139 | .temp 140 | 141 | # Docusaurus cache and generated files 142 | 143 | .docusaurus 144 | 145 | # Serverless directories 146 | 147 | .serverless/ 148 | 149 | # FuseBox cache 150 | 151 | .fusebox/ 152 | 153 | # DynamoDB Local files 154 | 155 | .dynamodb/ 156 | 157 | # TernJS port file 158 | 159 | .tern-port 160 | 161 | # Stores VSCode versions used for testing VSCode extensions 162 | 163 | .vscode-test 164 | 165 | # yarn v2 166 | 167 | .yarn/cache 168 | .yarn/unplugged 169 | .yarn/build-state.yml 170 | .yarn/install-state.gz 171 | .pnp.* 172 | 173 | # IntelliJ based IDEs 174 | .idea 175 | 176 | # Finder (MacOS) folder config 177 | .DS_Store 178 | 179 | # SQLite DB local file 180 | db/*.db 181 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.ignoreWords": [ 3 | "Elysia" 4 | ] 5 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CRUD REST API using Bun, Elysia, SQLite and TypeScript 2 | > CRUD REST API using Bun, Elysia, SQLite and TypeScript 🚀. It also includes tests and seeders. 3 | 4 | ## Installation 5 | 1. Run `bun i` to install all the required dependencies 6 | 7 | ## How to run 8 | Please, follow these steps to ensure the app successfully runs. 9 | 1. Copy the `.env.development.example` file into the root of the project and name it `.env.development`. Once you have done this, replace the value for the environment variable `DB_FILE_PATH` with the path to your SQLite database file. Please note that the path is expected to be relative to the root of the project directory. 10 | 2. Run the following command `bun run server` to start the API server locally. 11 | 12 | There are other commands which could be helpful in the development process: 13 | - Run `bun run server:dev` to run the functions locally and watch for file changes (hot reloading). 14 | - Run `bun run test` to run all the tests with Bun's test runner and get the current code coverage. 15 | 16 | ### Database 17 | - Run `bun run db:seed` to run the seeders and populate your database with initial data. 18 | 19 | ## Project Structure 20 | ### `src` 21 | 22 | #### `controllers` 23 | It has all controllers files that the API needs to handle the communication between the routers and the database. It plays the role of the Elysia.handlers 24 | 25 | #### `models` 26 | It contains all the necessary methods to communicate with the data source for each model object identity on this project. 27 | 28 | #### `tests` 29 | All the unit tests for this project are located here. 30 | 31 | ### `db/seeders` 32 | It has the seeders needed to populate the database with the initial mock data for the project. -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brianr482/bun-sqlite-api/5e4d132447525cd9c8ba8dccf502dd9d9d83a4a1/bun.lockb -------------------------------------------------------------------------------- /db/db.ts: -------------------------------------------------------------------------------- 1 | import Database from 'bun:sqlite'; 2 | 3 | const db: Database = new Database(Bun.env.DB_FILE_PATH); 4 | 5 | db.query(`CREATE TABLE IF NOT EXISTS "user" ( 6 | id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 7 | name TEXT NOT NULL, 8 | email TEXT NOT NULL UNIQUE, 9 | phone TEXT, 10 | bio TEXT, 11 | address TEXT NOT NULL 12 | )`).run(); 13 | db.query('CREATE UNIQUE INDEX IF NOT EXISTS user_id_IDX ON "user" (id)').run(); 14 | 15 | export default db; 16 | -------------------------------------------------------------------------------- /db/seeders/mock-users.seeder.ts: -------------------------------------------------------------------------------- 1 | import { faker } from '@faker-js/faker'; 2 | import db from '../db'; 3 | import { CreateUserDB } from '../../src/models/user.model'; 4 | 5 | const FAKE_USERS_AMOUNT: number = 100; 6 | 7 | /** 8 | * Populate the user db table with mock users. 9 | */ 10 | const mockUsers = () => { 11 | const mockUserFn = (): CreateUserDB => ({ 12 | $name: faker.person.fullName(), 13 | $email: faker.internet.email(), 14 | $address: faker.location.streetAddress(), 15 | $phone: faker.phone.number(), 16 | $bio: faker.person.bio(), 17 | }); 18 | 19 | const mockUsersToCreate: CreateUserDB[] = new Array(FAKE_USERS_AMOUNT) 20 | .fill(null) 21 | .map(mockUserFn); 22 | 23 | const query = db.prepare( 24 | `INSERT INTO user (name, email, address, phone, bio) VALUES ($name, $email, $address, $phone, $bio)`, 25 | ); 26 | 27 | const transactionFn: CallableFunction = db.transaction((usersToInsert: any[]) => { 28 | usersToInsert.forEach((userToInsert: any) => query.run(userToInsert)); 29 | 30 | return usersToInsert.length; 31 | }) 32 | 33 | const insertedRecords: number = transactionFn(mockUsersToCreate); 34 | 35 | console.log(`✅ Database successfully seeded with ${insertedRecords} fake users.`); 36 | }; 37 | 38 | // Clear table beforehand 39 | db.query('DELETE FROM user').run(); 40 | 41 | // Seed the user table 42 | mockUsers(); 43 | 44 | process.exit(); -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | console.log("Hello via Bun!"); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bun-sqlite-api", 3 | "version": "1.0.50", 4 | "scripts": { 5 | "server": "bun run src/index.ts", 6 | "server:dev": "bun run --hot src/index.ts", 7 | "db:seed": "bun run ./db/seeders/mock-users.seeder.ts", 8 | "test": "bun test --coverage --preload ./src/tests/setup.ts" 9 | }, 10 | "dependencies": { 11 | "@faker-js/faker": "^8.3.1", 12 | "elysia": "^0.7.29" 13 | }, 14 | "devDependencies": { 15 | "bun-types": "^1.0.14" 16 | }, 17 | "module": "src/index.js" 18 | } -------------------------------------------------------------------------------- /src/controllers/user.controller.ts: -------------------------------------------------------------------------------- 1 | 2 | import { CreateUserData, UpdateUserData, User } from '../models/user.model'; 3 | 4 | export class UserController { 5 | public static getAllUsers(): User[] { 6 | return User.getAll(); 7 | } 8 | 9 | public static deleteUserById(userId: number): void { 10 | return User.deleteById(userId); 11 | } 12 | 13 | public static getUserById(userId: number): User | null | never { 14 | return User.getById(userId); 15 | } 16 | 17 | public static updateUserById(userId: number, body: UpdateUserData): User | null | never { 18 | return User.updateById(userId, body); 19 | } 20 | 21 | public static create(body: CreateUserData): User | null | never { 22 | return User.create(body); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from 'elysia'; 2 | import { usersRoutes } from './routes/users'; 3 | 4 | const app = new Elysia() 5 | .group('/api/v1', app => app 6 | .use(usersRoutes)) 7 | .listen(3000); 8 | 9 | console.log(`🚀 Sever is running at ${app.server?.hostname}:${app.server?.port}`); 10 | -------------------------------------------------------------------------------- /src/models/user.model.ts: -------------------------------------------------------------------------------- 1 | import { InternalServerError, NotFoundError } from 'elysia'; 2 | import db from '../../db/db'; 3 | 4 | export interface User { 5 | id: number; 6 | name: String; 7 | email: String; 8 | address: String; 9 | phone?: String; 10 | bio?: String; 11 | } 12 | 13 | export interface CreateUserDB { 14 | $name: String; 15 | $email: String; 16 | $address: String; 17 | $phone?: String; 18 | $bio?: String; 19 | } 20 | 21 | export interface CreateUserData { 22 | name: String; 23 | email: String; 24 | address: String; 25 | phone?: String; 26 | bio?: String; 27 | } 28 | 29 | export interface UpdateUserDB { 30 | $name?: String; 31 | $address?: String; 32 | $phone?: String; 33 | $bio?: String; 34 | } 35 | 36 | export interface UpdateUserData { 37 | name?: String; 38 | address?: String; 39 | phone?: String; 40 | bio?: String; 41 | } 42 | 43 | export class User { 44 | public static getAll(): User[] { 45 | return db.query('SELECT * FROM user ORDER BY id ASC').all(null); 46 | } 47 | 48 | public static getById(userId: number): User | never { 49 | const result: User | null = db.query('SELECT * FROM user WHERE id = ?').get(userId); 50 | if (!result) { 51 | throw new NotFoundError(`User does not exist`); 52 | } 53 | 54 | return result; 55 | } 56 | 57 | public static deleteById(userId: number): void | never { 58 | this.getById(userId); 59 | 60 | const result: User | null = db.query('DELETE FROM user WHERE id = ? RETURNING *') 61 | .get(userId); 62 | 63 | if (!result) { 64 | throw new InternalServerError('User was not deleted successfully.') 65 | } 66 | 67 | return; 68 | } 69 | 70 | public static updateById(userId: number, updateData: UpdateUserData): User | null | never { 71 | const user: User = this.getById(userId); 72 | const updateObj: UpdateUserDB & { $id: number } = { 73 | $name: updateData.name ?? user.name, 74 | $address: updateData.address ?? user.address, 75 | $phone: updateData.phone ?? user.phone, 76 | $bio: updateData.bio ?? user.bio, 77 | $id: userId, 78 | }; 79 | 80 | const result: User | null = db.query>(`UPDATE user 81 | SET name = $name, address = $address, bio = $bio, phone = $phone 82 | WHERE id = $id 83 | RETURNING *` 84 | ).get(updateObj as unknown as Record); 85 | 86 | if (!result) { 87 | throw new InternalServerError('User was not updated successfully.'); 88 | } 89 | 90 | return result; 91 | } 92 | 93 | public static create(createData: CreateUserData): User | null | never { 94 | const createObj: CreateUserDB = { 95 | $name: createData.name, 96 | $email: createData.email, 97 | $address: createData.address, 98 | $phone: createData.phone, 99 | $bio: createData.bio, 100 | }; 101 | 102 | const result: User | null = db.query>(`INSERT INTO user 103 | (name, email, address, phone, bio) 104 | VALUES ($name, $email, $address, $phone, $bio) 105 | RETURNING *` 106 | ).get(createObj as unknown as Record); 107 | 108 | if (!result) { 109 | throw new InternalServerError('User was not created successfully.'); 110 | } 111 | 112 | return result; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/routes/users.ts: -------------------------------------------------------------------------------- 1 | import Elysia, { t } from 'elysia'; 2 | import { UserController } from '../controllers/user.controller'; 3 | 4 | export const usersRoutes = new Elysia() 5 | .group('/users', app => app 6 | .post( 7 | '/', 8 | ( { body }) => UserController.create(body), 9 | { 10 | body: t.Object({ 11 | name: t.String(), 12 | email: t.String(), 13 | address: t.String(), 14 | phone: t.Optional(t.String()), 15 | bio: t.Optional(t.String()), 16 | }) 17 | }, 18 | ) 19 | .get('/', UserController.getAllUsers) 20 | .delete( 21 | '/:id', 22 | ( { params: { id } }) => UserController.deleteUserById(id), 23 | { params: t.Object({ id: t.Numeric() }) }, 24 | ) 25 | .get( 26 | '/:id', 27 | ( { params: { id } }) => UserController.getUserById(id), 28 | { params: t.Object({ id: t.Numeric() }) }, 29 | ) 30 | .put( 31 | '/:id', 32 | ( { params: { id }, body }) => UserController.updateUserById(id, body), 33 | { 34 | params: t.Object({ id: t.Numeric() }), 35 | body: t.Object({ 36 | name: t.Optional(t.String()), 37 | address: t.Optional(t.String()), 38 | phone: t.Optional(t.String()), 39 | bio: t.Optional(t.String()), 40 | }) 41 | }, 42 | ) 43 | ); -------------------------------------------------------------------------------- /src/tests/mocks/user.factory.ts: -------------------------------------------------------------------------------- 1 | import { faker } from "@faker-js/faker"; 2 | import { CreateUserData, User } from "../../models/user.model"; 3 | import db from "../../../db/db"; 4 | 5 | export class UserFactory { 6 | public static mockUser(mockWith: Partial = {}): CreateUserData { 7 | return { 8 | name: faker.person.fullName(), 9 | email: faker.internet.email(), 10 | address: faker.location.streetAddress(), 11 | phone: faker.phone.number(), 12 | bio: faker.person.bio(), 13 | ...mockWith, 14 | } 15 | }; 16 | 17 | public static create(mockWith: Partial = {}): User { 18 | const userData: CreateUserData = Object.fromEntries( 19 | Object.entries(this.mockUser(mockWith)).map(([key, value]) => ([`$${key}`, value])) 20 | ) as CreateUserData; 21 | 22 | const result: User | null = db.query>(`INSERT INTO user 23 | (name, email, address, phone, bio) 24 | VALUES ($name, $email, $address, $phone, $bio) 25 | RETURNING *` 26 | ).get(userData as unknown as Record); 27 | 28 | if (!result) { 29 | throw new Error('Mock User was not created successfully.'); 30 | } 31 | 32 | return result; 33 | } 34 | } -------------------------------------------------------------------------------- /src/tests/models/user.model.spec.ts: -------------------------------------------------------------------------------- 1 | import { NotFoundError } from "elysia"; 2 | import { describe, expect, it } from "bun:test"; 3 | import { UserFactory } from "../mocks/user.factory"; 4 | import { CreateUserData, UpdateUserData, User } from "../../models/user.model"; 5 | import db from "../../../db/db"; 6 | 7 | describe('UserModel', () => { 8 | describe('#getAll', () => { 9 | it('should return all users sorted by ID', () => { 10 | const mockUserA: User = UserFactory.create(); 11 | const mockUserB: User = UserFactory.create(); 12 | 13 | expect(User.getAll()).toEqual([ 14 | { 15 | id: expect.anything() as any, 16 | name: mockUserA.name, 17 | email: mockUserA.email, 18 | address: mockUserA.address, 19 | phone: mockUserA.phone, 20 | bio: mockUserA.bio, 21 | }, 22 | { 23 | id: expect.anything() as any, 24 | name: mockUserB.name, 25 | email: mockUserB.email, 26 | address: mockUserB.address, 27 | phone: mockUserB.phone, 28 | bio: mockUserB.bio, 29 | }, 30 | ]); 31 | }); 32 | }); 33 | 34 | describe('#getById', () => { 35 | it('should return the user\'s record whose id matches the given id', () => { 36 | const mockUserA: User = UserFactory.create(); 37 | 38 | expect(User.getById(mockUserA.id)).toEqual({ 39 | id: expect.anything() as any, 40 | name: mockUserA.name, 41 | email: mockUserA.email, 42 | address: mockUserA.address, 43 | phone: mockUserA.phone, 44 | bio: mockUserA.bio, 45 | }); 46 | }); 47 | 48 | it('should return an error if no user\'s records match the given id', () => { 49 | expect(() => User.getById(-1)).toThrow(new NotFoundError('User does not exist')); 50 | }); 51 | }); 52 | 53 | describe('#deleteById', () => { 54 | it('should delete the user\'s record whose id matches the given id', () => { 55 | const mockUser: User = UserFactory.create(); 56 | 57 | User.deleteById(mockUser.id); 58 | 59 | const userRecord: User | null = db.query('SELECT * FROM user WHERE id = ?') 60 | .get(mockUser.id); 61 | 62 | expect(userRecord).toBeNull(); 63 | }); 64 | 65 | it('should return an error if no user\'s records match the given id of user to be deleted', () => { 66 | expect(() => User.deleteById(-1)).toThrow(new NotFoundError('User does not exist')); 67 | }); 68 | }); 69 | 70 | describe('#updateById', () => { 71 | it('should update the user\'s record whose id matches the given id with the given data', () => { 72 | const mockUser: User = UserFactory.create(); 73 | 74 | const updateData: UpdateUserData = { name: 'updated name' }; 75 | User.updateById(mockUser.id, updateData); 76 | 77 | const userRecord: User = db.query('SELECT * FROM user WHERE id = ?') 78 | .get(mockUser.id) as User; 79 | 80 | expect(userRecord.name).toEqual(updateData.name as string); 81 | }); 82 | 83 | it('should return an error if no user\'s records match the given id of user to be updated', () => { 84 | expect(() => User.updateById(-1, {})).toThrow(new NotFoundError('User does not exist')); 85 | }); 86 | }); 87 | 88 | describe('#create', () => { 89 | it('should create the a new user record', () => { 90 | const mockUserData: CreateUserData = UserFactory.mockUser(); 91 | 92 | const userResult: User = User.create(mockUserData) as User; 93 | 94 | const userRecord: User = db.query('SELECT * FROM user WHERE id = ?') 95 | .get(userResult.id) as User; 96 | 97 | expect(userRecord).toEqual({ 98 | id: expect.anything() as any, 99 | name: mockUserData.name, 100 | email: mockUserData.email, 101 | address: mockUserData.address, 102 | phone: mockUserData.phone, 103 | bio: mockUserData.bio, 104 | }); 105 | }); 106 | }); 107 | }); -------------------------------------------------------------------------------- /src/tests/setup.ts: -------------------------------------------------------------------------------- 1 | import { afterAll, beforeEach } from "bun:test"; 2 | import { unlinkSync } from "node:fs"; 3 | import db from "../../db/db"; 4 | 5 | beforeEach(() => { 6 | db.query('DELETE FROM user').run(); 7 | }); 8 | 9 | afterAll(() => { 10 | unlinkSync(Bun.env.DB_FILE_PATH as string); 11 | }); -------------------------------------------------------------------------------- /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": "ES2021", /* 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 TC39 stage 2 draft 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": "ES2022", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | "moduleResolution": "node", /* 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": ["bun-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 | // "resolveJsonModule": true, /* Enable importing .json files. */ 39 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 40 | 41 | /* JavaScript Support */ 42 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 43 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 44 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 45 | 46 | /* Emit */ 47 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 48 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 49 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 50 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 51 | // "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. */ 52 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 53 | // "removeComments": true, /* Disable emitting comments. */ 54 | // "noEmit": true, /* Disable emitting files from a compilation. */ 55 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 56 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 57 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 58 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 59 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 60 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 61 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 62 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 63 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 64 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 65 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 66 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 67 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 68 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 69 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 70 | 71 | /* Interop Constraints */ 72 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 73 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 74 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 75 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 76 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 77 | 78 | /* Type Checking */ 79 | "strict": true, /* Enable all strict type-checking options. */ 80 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 81 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 82 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 83 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 84 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 85 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 86 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 87 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 88 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 89 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 90 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 91 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 92 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 93 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 94 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 95 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 96 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 97 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 98 | 99 | /* Completeness */ 100 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 101 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 102 | } 103 | } 104 | --------------------------------------------------------------------------------