├── apps
├── api
│ ├── .env.example
│ ├── src
│ │ ├── types.ts
│ │ ├── routes
│ │ │ ├── health.ts
│ │ │ ├── example.ts
│ │ │ ├── health.test.ts
│ │ │ ├── index.ts
│ │ │ ├── trpc.ts
│ │ │ └── context.ts
│ │ ├── utils
│ │ │ └── testCaller.ts
│ │ ├── app.ts
│ │ ├── config
│ │ │ ├── env.ts
│ │ │ └── config.ts
│ │ └── server.ts
│ ├── .eslintrc.js
│ ├── package.json
│ └── tsconfig.json
└── web
│ ├── .eslintignore
│ ├── .env.example
│ ├── tsconfig.spec.json
│ ├── components
│ ├── HelloWorld.tsx
│ └── HelloWorld.test.tsx
│ ├── cypress
│ ├── e2e
│ │ └── home.spec.ts
│ ├── fixtures
│ │ └── example.json
│ └── support
│ │ ├── e2e.ts
│ │ └── commands.ts
│ ├── next-env.d.ts
│ ├── pages
│ ├── _app.tsx
│ └── index.tsx
│ ├── tsconfig.json
│ ├── jest.setup.js
│ ├── cypress.config.ts
│ ├── next.config.js
│ ├── .eslintrc.js
│ ├── jest.config.js
│ ├── README.md
│ ├── package.json
│ └── utils
│ └── trpc.ts
├── packages
├── schema
│ ├── index.ts
│ ├── example.ts
│ ├── package.json
│ └── tsconfig.json
├── ui
│ ├── .eslintignore
│ ├── jest.setup.ts
│ ├── index.tsx
│ ├── components
│ │ ├── Button.tsx
│ │ └── Button.test.tsx
│ ├── tsconfig.json
│ ├── .eslintrc.js
│ ├── jest.config.ts
│ └── package.json
├── tsconfig
│ ├── README.md
│ ├── package.json
│ ├── react-library.json
│ ├── base.json
│ └── nextjs.json
├── eslint-config-custom-server
│ ├── index.js
│ └── package.json
└── eslint-config-custom
│ ├── index.js
│ └── package.json
├── pnpm-workspace.yaml
├── .vscode
└── settings.json
├── .eslintrc.js
├── .gitignore
├── turbo.json
├── package.json
├── .github
├── dependabot.yml
└── workflows
│ └── build-test-lint.yml
├── LICENSE
└── README.md
/apps/api/.env.example:
--------------------------------------------------------------------------------
1 | PORT=5000
--------------------------------------------------------------------------------
/packages/schema/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./example";
--------------------------------------------------------------------------------
/packages/ui/.eslintignore:
--------------------------------------------------------------------------------
1 | jest.config.ts
2 | jest.setup.ts
--------------------------------------------------------------------------------
/apps/api/src/types.ts:
--------------------------------------------------------------------------------
1 | export type { AppRouter } from "./routes";
2 |
--------------------------------------------------------------------------------
/packages/ui/jest.setup.ts:
--------------------------------------------------------------------------------
1 | import "@testing-library/jest-dom";
2 |
--------------------------------------------------------------------------------
/apps/web/.eslintignore:
--------------------------------------------------------------------------------
1 | next.config.js
2 | jest.config.js
3 | jest.setup.js
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - "apps/*"
3 | - "packages/*"
4 |
--------------------------------------------------------------------------------
/apps/web/.env.example:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_API_URL=http://localhost:5000
2 | NODE_ENV=development
--------------------------------------------------------------------------------
/packages/ui/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | export * from "./components/Button";
3 |
--------------------------------------------------------------------------------
/apps/web/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": ["**/*.spec.ts"]
4 | }
5 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "eslint.workingDirectories": ["./apps/api", "./apps/web", "./packages/ui"]
3 | }
4 |
--------------------------------------------------------------------------------
/apps/web/components/HelloWorld.tsx:
--------------------------------------------------------------------------------
1 | export const HelloWorld = () => {
2 | return
Hello World
;
3 | };
4 |
--------------------------------------------------------------------------------
/packages/schema/example.ts:
--------------------------------------------------------------------------------
1 | import z from "zod";
2 |
3 | export const testSchema = z.object({
4 | test: z.string(),
5 | });
6 |
--------------------------------------------------------------------------------
/packages/tsconfig/README.md:
--------------------------------------------------------------------------------
1 | # `tsconfig`
2 |
3 | These are base shared `tsconfig.json`s from which all other `tsconfig.json`'s inherit from.
4 |
--------------------------------------------------------------------------------
/packages/ui/components/Button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | export const Button = () => {
3 | return ;
4 | };
5 |
--------------------------------------------------------------------------------
/packages/ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tsconfig/react-library.json",
3 | "include": ["."],
4 | "exclude": ["dist", "build", "node_modules"]
5 | }
6 |
--------------------------------------------------------------------------------
/packages/eslint-config-custom-server/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ["eslint:recommended", "turbo"],
3 | env: {
4 | node: true,
5 | es6: true,
6 | },
7 | };
8 |
--------------------------------------------------------------------------------
/apps/web/cypress/e2e/home.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, it, cy } from "local-cypress";
2 |
3 | describe("Home", () => {
4 | it("Opens homepage", () => {
5 | cy.visit("/");
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/apps/web/cypress/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io",
4 | "body": "Fixtures are a great way to mock data for responses to routes"
5 | }
6 |
--------------------------------------------------------------------------------
/packages/eslint-config-custom/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ["next", "turbo", "prettier"],
3 | rules: {
4 | "@next/next/no-html-link-for-pages": "off",
5 | "react/jsx-key": "off",
6 | },
7 | };
8 |
--------------------------------------------------------------------------------
/packages/tsconfig/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tsconfig",
3 | "version": "0.0.0",
4 | "private": true,
5 | "files": [
6 | "base.json",
7 | "nextjs.json",
8 | "react-library.json"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/web/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/apps/api/src/routes/health.ts:
--------------------------------------------------------------------------------
1 | import { publicProcedure, router } from "./trpc";
2 |
3 | export const healthRouter = router({
4 | health: publicProcedure.query(({ ctx }) => {
5 | return {
6 | health: "ok",
7 | };
8 | }),
9 | });
10 |
--------------------------------------------------------------------------------
/apps/web/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import type { AppType } from "next/app";
2 | import { trpc } from "../utils/trpc";
3 |
4 | const MyApp: AppType = ({ Component, pageProps }) => {
5 | return ;
6 | };
7 | export default trpc.withTRPC(MyApp);
8 |
--------------------------------------------------------------------------------
/apps/api/src/utils/testCaller.ts:
--------------------------------------------------------------------------------
1 | import { testRouter } from "../routes";
2 | import { createContextInner } from "../routes/context";
3 |
4 | export const createTestCaller = async () => {
5 | const ctx = await createContextInner();
6 | return testRouter.createCaller(ctx);
7 | };
8 |
--------------------------------------------------------------------------------
/apps/web/components/HelloWorld.test.tsx:
--------------------------------------------------------------------------------
1 | import { HelloWorld } from "./HelloWorld";
2 | import { render, screen } from "@testing-library/react";
3 |
4 | test("Renders Hello World", () => {
5 | render();
6 | expect(screen.getByText("Hello World")).toBeTruthy();
7 | });
8 |
--------------------------------------------------------------------------------
/apps/web/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "isolatedModules": true,
4 | "types": ["jest"]
5 | },
6 | "extends": "tsconfig/nextjs.json",
7 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
8 | "exclude": ["node_modules", "**/*.spec.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/apps/api/src/app.ts:
--------------------------------------------------------------------------------
1 | import fastify, { FastifyServerOptions } from "fastify";
2 | import sensible from "@fastify/sensible";
3 |
4 | export const build = (opts?: FastifyServerOptions) => {
5 | const app = fastify(opts);
6 |
7 | app.register(sensible);
8 | return app;
9 | };
10 |
--------------------------------------------------------------------------------
/packages/ui/components/Button.test.tsx:
--------------------------------------------------------------------------------
1 | import { render, screen } from "@testing-library/react";
2 | import { Button } from "./Button";
3 |
4 | describe("Button", () => {
5 | test("Renders Button", () => {
6 | render();
7 | expect(screen.getByRole("button")).toBeTruthy();
8 | })
9 | })
--------------------------------------------------------------------------------
/apps/api/src/config/env.ts:
--------------------------------------------------------------------------------
1 | import z from "zod";
2 |
3 | export const envSchema = z.object({
4 | PORT: z.coerce.number().int().default(5000),
5 | NODE_ENV: z.string().default("development"),
6 | HOST: z.string().default("localhost"),
7 | });
8 |
9 | export const env = envSchema.parse(process.env);
10 |
--------------------------------------------------------------------------------
/packages/tsconfig/react-library.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "React Library",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "jsx": "react-jsx",
7 | "lib": ["ES2015"],
8 | "module": "ESNext",
9 | "target": "es6"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | // This tells ESLint to load the config from the package `eslint-config-custom`
4 | extends: ["custom"],
5 | settings: {
6 | next: {
7 | rootDir: ["apps/*/"],
8 | },
9 | },
10 | parserOptions: {
11 | sourceType: "module",
12 | },
13 | };
14 |
--------------------------------------------------------------------------------
/apps/api/src/routes/example.ts:
--------------------------------------------------------------------------------
1 | import { router, publicProcedure } from "./trpc";
2 | import { testSchema } from "schema";
3 |
4 | export const exampleRouter = router({
5 | example: publicProcedure.input(testSchema).query(({ ctx, input }) => {
6 | ctx.req.log.info(input, "example");
7 | return input;
8 | }),
9 | });
10 |
--------------------------------------------------------------------------------
/apps/web/jest.setup.js:
--------------------------------------------------------------------------------
1 | // Optional: configure or set up a testing framework before each test.
2 | // If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`
3 |
4 | // Used for __tests__/testing-library.js
5 | // Learn more: https://github.com/testing-library/jest-dom
6 | import "@testing-library/jest-dom/extend-expect";
7 |
--------------------------------------------------------------------------------
/apps/web/cypress.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "cypress";
2 |
3 | export default defineConfig({
4 | e2e: {
5 | baseUrl: "http://localhost:3000",
6 | setupNodeEvents(on, config) {
7 | // implement node event listeners here
8 | },
9 | specPattern: "cypress/e2e/**/*.spec.{js,jsx,ts,tsx}",
10 | },
11 | video: false,
12 | });
13 |
--------------------------------------------------------------------------------
/apps/web/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from "ui";
2 | import { trpc } from "../utils/trpc";
3 |
4 | export default function Web() {
5 | const health = trpc.health.health.useQuery();
6 |
7 | return (
8 |
9 | {health.data &&
TRPC Health: {health.data.health}
}
10 |
Web
11 |
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/apps/api/src/routes/health.test.ts:
--------------------------------------------------------------------------------
1 | import t from "tap";
2 | import { createTestCaller } from "../utils/testCaller";
3 |
4 | t.test("Health route", (t) => {
5 | t.test("Success", async (t) => {
6 | const caller = await createTestCaller();
7 | const res = await caller.health.health();
8 |
9 | t.ok(res.health);
10 | t.match(res, { health: "ok" });
11 | });
12 |
13 | t.end();
14 | });
15 |
--------------------------------------------------------------------------------
/packages/eslint-config-custom-server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eslint-config-custom-server",
3 | "version": "0.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "dependencies": {
7 | "eslint": "^8.35.0",
8 | "eslint-config-turbo": "latest"
9 | },
10 | "devDependencies": {
11 | "typescript": "^4.7.4"
12 | },
13 | "publishConfig": {
14 | "access": "public"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/apps/web/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import("next").NextConfig} */
2 | const config = {
3 | reactStrictMode: true,
4 | swcMinify: true,
5 | transpilePackages: ["ui"],
6 | typescript: {
7 | ignoreBuildErrors: true,
8 | },
9 | };
10 |
11 | const withBundleAnalyzer = require("@next/bundle-analyzer")({
12 | enabled: process.env.ANALYZE === "true",
13 | });
14 |
15 | module.exports = withBundleAnalyzer(config);
16 |
--------------------------------------------------------------------------------
/apps/api/src/routes/index.ts:
--------------------------------------------------------------------------------
1 | import { exampleRouter } from "./example";
2 | import { healthRouter } from "./health";
3 | import { router, _testRouter } from "./trpc";
4 |
5 | export const appRouter = router({
6 | health: healthRouter,
7 | example: exampleRouter,
8 | });
9 |
10 | export const testRouter = _testRouter({
11 | health: healthRouter,
12 | example: exampleRouter,
13 | });
14 |
15 | export type AppRouter = typeof appRouter;
16 |
--------------------------------------------------------------------------------
/apps/web/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | plugins: ["@typescript-eslint"],
4 | extends: [
5 | "custom",
6 | "next/core-web-vitals",
7 | "plugin:@typescript-eslint/recommended",
8 | ],
9 | rules: {
10 | "@typescript-eslint/consistent-type-imports": "warn",
11 | },
12 | parser: "@typescript-eslint/parser",
13 | parserOptions: {
14 | project: "./tsconfig.json",
15 | sourceType: "module",
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/packages/schema/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "schema",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "dist/index.js",
6 | "src": "index.ts",
7 | "scripts": {
8 | "build": "tsc"
9 | },
10 | "keywords": [],
11 | "author": "maybemaby",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "typescript": "^4.9.4",
15 | "tsconfig": "workspace:*"
16 | },
17 | "dependencies": {
18 | "zod": "^3.20.2"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/ui/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | plugins: ["@typescript-eslint"],
4 | extends: [
5 | "custom",
6 | "plugin:@typescript-eslint/recommended",
7 | "plugin:react/recommended",
8 | "plugin:jsx-a11y/recommended",
9 | ],
10 | rules: {
11 | "@typescript-eslint/consistent-type-imports": "warn",
12 | "react/react-in-jsx-scope": "off",
13 | },
14 | parser: "@typescript-eslint/parser",
15 | parserOptions: {
16 | project: "./tsconfig.json",
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/packages/eslint-config-custom/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eslint-config-custom",
3 | "version": "0.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "dependencies": {
7 | "eslint": "^8.35.0",
8 | "eslint-config-next": "13.1.6",
9 | "eslint-config-prettier": "^8.3.0",
10 | "eslint-plugin-react": "7.32.2",
11 | "eslint-config-turbo": "latest"
12 | },
13 | "devDependencies": {
14 | "typescript": "^4.7.4"
15 | },
16 | "publishConfig": {
17 | "access": "public"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/apps/api/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: [
4 | "custom-server",
5 | "plugin:@typescript-eslint/recommended",
6 | "plugin:@typescript-eslint/recommended-requiring-type-checking",
7 | ],
8 | parser: "@typescript-eslint/parser",
9 | plugins: ["@typescript-eslint"],
10 | rules: {
11 | "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
12 | "@typescript-eslint/no-floating-promises": "off",
13 | },
14 | parserOptions: {
15 | project: "./tsconfig.json",
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | #api
4 | dist
5 | .nyc_output
6 |
7 | # dependencies
8 | node_modules
9 | .pnp
10 | .pnp.js
11 |
12 | # testing
13 | coverage
14 |
15 | # next.js
16 | .next/
17 | out/
18 | build
19 |
20 | # misc
21 | .DS_Store
22 | *.pem
23 |
24 | # debug
25 | npm-debug.log*
26 | yarn-debug.log*
27 | yarn-error.log*
28 | .pnpm-debug.log*
29 |
30 | # local env files
31 | .env.local
32 | .env.development.local
33 | .env.test.local
34 | .env.production.local
35 | .env.dev
36 | .env.test
37 | .env
38 |
39 | # turbo
40 | .turbo
41 |
--------------------------------------------------------------------------------
/apps/api/src/routes/trpc.ts:
--------------------------------------------------------------------------------
1 | import { initTRPC } from "@trpc/server";
2 | import SuperJSON from "superjson";
3 | import { Context, InnerContext } from "./context";
4 |
5 | const t = initTRPC.context().create({
6 | transformer: SuperJSON,
7 | errorFormatter({ shape }) {
8 | return shape;
9 | },
10 | });
11 |
12 | const testT = initTRPC.context().create({
13 | transformer: SuperJSON,
14 | errorFormatter({ shape }) {
15 | return shape;
16 | },
17 | });
18 |
19 | export const _testRouter = testT.router;
20 | export const router = t.router;
21 | export const publicProcedure = t.procedure;
--------------------------------------------------------------------------------
/packages/tsconfig/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Default",
4 | "compilerOptions": {
5 | "composite": false,
6 | "declaration": true,
7 | "declarationMap": true,
8 | "esModuleInterop": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "inlineSources": false,
11 | "isolatedModules": true,
12 | "moduleResolution": "node",
13 | "noUnusedLocals": false,
14 | "noUnusedParameters": false,
15 | "preserveWatchOutput": true,
16 | "skipLibCheck": true,
17 | "strict": true
18 | },
19 | "exclude": ["node_modules"]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/ui/jest.config.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | testEnvironment: "jsdom",
3 | setupFilesAfterEnv: ["./jest.setup.ts"],
4 | moduleFileExtensions: ["ts", "tsx", "js"],
5 | testPathIgnorePatterns: ["node_modules/"],
6 | transform: {
7 | "^.+\\.tsx?$": "ts-jest",
8 | },
9 | testMatch: ["**/*.test.(ts|tsx)"],
10 | moduleNameMapper: {
11 | // Mocks out all these file formats when tests are run.
12 | "\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
13 | "identity-obj-proxy",
14 | "\\.(css|less|scss|sass)$": "/__mocks__/styles.js",
15 | },
16 | };
17 |
--------------------------------------------------------------------------------
/packages/tsconfig/nextjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Next.js",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "target": "es5",
7 | "lib": ["dom", "dom.iterable", "esnext"],
8 | "allowJs": true,
9 | "skipLibCheck": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "noEmit": true,
13 | "incremental": true,
14 | "esModuleInterop": true,
15 | "module": "esnext",
16 | "resolveJsonModule": true,
17 | "isolatedModules": true,
18 | "jsx": "preserve"
19 | },
20 | "include": ["src", "next-env.d.ts"],
21 | "exclude": ["node_modules"]
22 | }
23 |
--------------------------------------------------------------------------------
/apps/web/cypress/support/e2e.ts:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/e2e.ts is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import './commands'
18 |
19 | // Alternatively you can use CommonJS syntax:
20 | // require('./commands')
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 |
4 | "pipeline": {
5 | "build": {
6 | "env": ["VERCEL_URL", "RENDER_INTERNAL_HOSTNAME", "NEXT_PUBLIC_PORT"],
7 | "dependsOn": ["^build"],
8 | "outputs": ["dist/**", ".next/**"]
9 | },
10 | "lint": {
11 | "outputs": []
12 | },
13 | "dev": {
14 | "persistent": true,
15 | "cache": false
16 | },
17 | "start": {
18 | "persistent": true,
19 | "dependsOn": ["^build"]
20 | },
21 | "test": {
22 | "inputs": [
23 | "packages/ui/**/*.tsx",
24 | "packages/ui/**/*.ts",
25 | "apps/web/components/**/*.tsx",
26 | "apps/web/components/**/*.ts"
27 | ]
28 | },
29 | "test:e2e": {}
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/schema/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
4 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
5 | "moduleResolution": "node",
6 | "lib": [
7 | "ESNext"
8 | ] /* Specify library files to be included in the compilation. */,
9 | "outDir": "dist",
10 | "rootDir": ".",
11 | "declaration": true,
12 | "declarationMap": true,
13 | "sourceMap": true,
14 | "composite": true
15 | },
16 | "include": ["**/*.ts"],
17 | "exclude": ["node_modules", "dist"],
18 | "extends": "tsconfig/base.json"
19 | }
20 |
--------------------------------------------------------------------------------
/apps/api/src/routes/context.ts:
--------------------------------------------------------------------------------
1 | import { inferAsyncReturnType } from "@trpc/server";
2 | import { CreateFastifyContextOptions } from "@trpc/server/adapters/fastify";
3 | // Reference required for compilation
4 | import type fastify from "fastify";
5 |
6 | // eslint-disable-next-line @typescript-eslint/require-await
7 | export async function createContextInner() {
8 | return {};
9 | }
10 |
11 | // eslint-disable-next-line @typescript-eslint/require-await
12 | export async function createContext({ req, res }: CreateFastifyContextOptions) {
13 | const server = req.server;
14 |
15 | return {
16 | fastify: server,
17 | req,
18 | res,
19 | };
20 | }
21 |
22 | export type Context = inferAsyncReturnType;
23 | export type InnerContext = inferAsyncReturnType;
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fastify-trpc-next",
3 | "version": "0.0.0",
4 | "repository": "https://github.com/maybemaby/fastify-trpc-next",
5 | "private": true,
6 | "workspaces": [
7 | "apps/*",
8 | "packages/*"
9 | ],
10 | "scripts": {
11 | "build": "turbo run build",
12 | "dev": "turbo run dev --parallel --force",
13 | "lint": "turbo run lint --filter=!schema --filter=!ui",
14 | "test": "turbo run test",
15 | "test:e2e": "turbo run test:e2e",
16 | "format": "prettier --write \"**/*.{ts,tsx,md}\"",
17 | "start": "turbo run start"
18 | },
19 | "devDependencies": {
20 | "eslint-config-custom": "workspace:*",
21 | "prettier": "^2.8.4",
22 | "turbo": "^1.8.3"
23 | },
24 | "engines": {
25 | "node": ">=14.0.0"
26 | },
27 | "packageManager": "pnpm@7.20.0"
28 | }
29 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "npm" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "weekly"
12 | - package-ecosystem: "npm"
13 | directory: "/apps/web"
14 | schedule:
15 | interval: "weekly"
16 | - package-ecosystem: "npm"
17 | directory: "/apps/api"
18 | schedule:
19 | interval: "weekly"
20 | - package-ecosystem: "npm"
21 | directory: "/packages/ui"
22 | schedule:
23 | interval: "weekly"
24 | - package-ecosystem: "npm"
25 | directory: "/packages/schema"
26 | schedule:
27 | interval: "weekly"
28 |
--------------------------------------------------------------------------------
/packages/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ui",
3 | "version": "0.0.0",
4 | "main": "./index.tsx",
5 | "types": "./index.tsx",
6 | "license": "MIT",
7 | "scripts": {
8 | "lint": "eslint *.ts*",
9 | "test": "jest",
10 | "test:w": "jest --watch"
11 | },
12 | "devDependencies": {
13 | "@types/react": "^18.0.17",
14 | "@types/react-dom": "^18.0.6",
15 | "eslint": "^8.35.0",
16 | "eslint-config-custom": "workspace:*",
17 | "eslint-plugin-react": "^7.32.1",
18 | "@typescript-eslint/eslint-plugin": "^5.47.1",
19 | "@typescript-eslint/parser": "^5.47.1",
20 | "react": "^18.2.0",
21 | "tsconfig": "workspace:*",
22 | "typescript": "^4.5.2",
23 | "ts-jest": "^29.0.3",
24 | "jest": "^29.3.1",
25 | "jest-environment-jsdom": "^29.3.1",
26 | "@testing-library/dom": "^9.0.1",
27 | "@testing-library/jest-dom": "^5.16.5",
28 | "@testing-library/react": "^14.0.0",
29 | "@testing-library/user-event": "^14.4.3",
30 | "@types/jest": "^29.2.5"
31 | },
32 | "peerDependencies": {
33 | "react-dom": "18.2.0"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Brandon Ma
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/apps/web/jest.config.js:
--------------------------------------------------------------------------------
1 | const nextJest = require("next/jest");
2 |
3 | const createJestConfig = nextJest({
4 | // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
5 | dir: "./",
6 | });
7 |
8 | // Add any custom config to be passed to Jest
9 | const customJestConfig = {
10 | // Add more setup options before each test is run
11 | // setupFilesAfterEnv: ['/jest.setup.js'],
12 | // if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
13 | moduleDirectories: ["node_modules", "/"],
14 | testEnvironment: "jest-environment-jsdom",
15 | moduleNameMapper: {
16 | "^@components(.*)$": "/src/components/$1",
17 | "^@hooks(.*)$": "/src/hooks/$1",
18 | "^~(.*)$": "/src/$1",
19 | },
20 | setupFilesAfterEnv: ["@testing-library/jest-dom/extend-expect"],
21 | testRegex: "(/__tests__/.*|(\\.|/)(test))\\.[jt]sx?$",
22 | };
23 |
24 | // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
25 | module.exports = createJestConfig(customJestConfig);
26 |
--------------------------------------------------------------------------------
/apps/api/src/config/config.ts:
--------------------------------------------------------------------------------
1 | import { FastifyServerOptions } from "fastify";
2 |
3 | interface IConfig {
4 | logger: FastifyServerOptions["logger"];
5 | }
6 |
7 | // Define configs here based on NODE_ENV = "development" | "testing" | "production"
8 | export const config: Record = {
9 | development: {
10 | logger: {
11 | transport: {
12 | target: "pino-pretty",
13 | options: {
14 | colorize: true,
15 | translateTime: "yyyy-mm-dd HH:MM:ss.l",
16 | },
17 | },
18 | level: "debug",
19 | },
20 | },
21 | production: {
22 | logger: {
23 | serializers: {
24 | req(req) {
25 | return {
26 | method: req.method,
27 | url: req.url,
28 | };
29 | },
30 | },
31 | level: "info",
32 | transport: {
33 | targets: [
34 | {
35 | target: "pino/file",
36 | level: "info",
37 | options: {
38 | destination: `./logs/production.log`,
39 | mkdir: true,
40 | },
41 | },
42 | ],
43 | },
44 | },
45 | },
46 | testing: { logger: false },
47 | };
48 |
--------------------------------------------------------------------------------
/apps/api/src/server.ts:
--------------------------------------------------------------------------------
1 | import helmet from "@fastify/helmet";
2 | import cors from "@fastify/cors";
3 | import { fastifyTRPCPlugin } from "@trpc/server/adapters/fastify";
4 | import { build } from "./app";
5 | import { createContext } from "./routes/context";
6 | import { env } from "./config/env";
7 | import { config } from "./config/config";
8 | import { appRouter } from "./routes";
9 |
10 | const app = build({
11 | logger: config[env.NODE_ENV].logger,
12 | });
13 |
14 | app.register(fastifyTRPCPlugin, {
15 | prefix: "/api",
16 | trpcOptions: {
17 | router: appRouter,
18 | createContext,
19 | },
20 | });
21 |
22 | app.register(cors, {
23 | origin: "*",
24 | credentials: true,
25 | });
26 |
27 | app.register(helmet);
28 |
29 | if (env.HOST) {
30 | app.listen(
31 | {
32 | port: env.PORT,
33 | host: env.HOST,
34 | },
35 | (err, _address) => {
36 | if (err) {
37 | app.log.error(err);
38 | process.exit(1);
39 | }
40 | }
41 | );
42 | } else {
43 | app.listen(
44 | {
45 | port: env.PORT,
46 | },
47 | (err, _address) => {
48 | if (err) {
49 | app.log.error(err);
50 | process.exit(1);
51 | }
52 | }
53 | );
54 | }
55 |
--------------------------------------------------------------------------------
/.github/workflows/build-test-lint.yml:
--------------------------------------------------------------------------------
1 | name: Build, Test, and Lint
2 | on:
3 | push:
4 | branches: [dev**]
5 | paths-ignore:
6 | - "**.md"
7 | - .vscode/**
8 | pull_request_target:
9 | types:
10 | - opened
11 | branches:
12 | - main
13 | paths-ignore:
14 | - "**.md"
15 | - .vscode/**
16 |
17 | jobs:
18 | test:
19 | timeout-minutes: 30
20 | if: ${{ github.actor != 'dependabot[bot]' }}
21 | runs-on: ubuntu-latest
22 | env:
23 | TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
24 | TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
25 |
26 | steps:
27 | - name: Check out repository
28 | uses: actions/checkout@v3
29 | with:
30 | fetch-depth: 2
31 |
32 | - uses: pnpm/action-setup@v2.0.1
33 | with:
34 | version: 7.26.0
35 |
36 | - name: Setup Node
37 | uses: actions/setup-node@v2
38 | with:
39 | node-version: 18.x
40 | cache: "pnpm"
41 |
42 | - name: Install deps
43 | run: pnpm install
44 |
45 | - name: Run build
46 | run: pnpm build
47 |
48 | - name: Run lint
49 | run: pnpm lint
50 | continue-on-error: true
51 |
52 | - name: Run unit tests
53 | run: pnpm test
--------------------------------------------------------------------------------
/apps/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.ts",
6 | "scripts": {
7 | "build": "tsc",
8 | "dev": "dotenv -e .env.dev -- ts-node-dev ./src/server.ts",
9 | "lint": "tsc --noEmit && TIMING=1 eslint \"src/**/*.ts*\"",
10 | "test": "dotenv -e .env.test -- tap src/**/*.test.ts --ts --no-check-coverage",
11 | "start": "dotenv -e .env -- node ./dist/server.js"
12 | },
13 | "keywords": [],
14 | "author": "maybemaby",
15 | "license": "ISC",
16 | "dependencies": {
17 | "@fastify/cors": "^8.2.0",
18 | "@fastify/helmet": "^10.1.0",
19 | "@fastify/sensible": "^5.2.0",
20 | "@trpc/server": "^10.7.0",
21 | "dotenv-cli": "^6.0.0",
22 | "fastify": "^4.11.0",
23 | "fastify-plugin": "^4.5.0",
24 | "schema": "*",
25 | "superjson": "^1.12.1",
26 | "typescript": "^4.9.4",
27 | "zod": "^3.20.2"
28 | },
29 | "devDependencies": {
30 | "@types/node": "^18.14.6",
31 | "@types/tap": "^15.0.8",
32 | "@typescript-eslint/eslint-plugin": "^5.47.1",
33 | "@typescript-eslint/parser": "^5.47.1",
34 | "eslint": "^8.31.0",
35 | "eslint-config-custom-server": "*",
36 | "pino-pretty": "^10.0.0",
37 | "tap": "^16.3.4",
38 | "ts-node-dev": "^2.0.0",
39 | "tsconfig": "workspace:*"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/apps/web/cypress/support/commands.ts:
--------------------------------------------------------------------------------
1 | ///
2 | // ***********************************************
3 | // This example commands.ts shows you how to
4 | // create various custom commands and overwrite
5 | // existing commands.
6 | //
7 | // For more comprehensive examples of custom
8 | // commands please read more here:
9 | // https://on.cypress.io/custom-commands
10 | // ***********************************************
11 | //
12 | //
13 | // -- This is a parent command --
14 | // Cypress.Commands.add('login', (email, password) => { ... })
15 | //
16 | //
17 | // -- This is a child command --
18 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
19 | //
20 | //
21 | // -- This is a dual command --
22 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
23 | //
24 | //
25 | // -- This will overwrite an existing command --
26 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
27 | //
28 | // declare global {
29 | // namespace Cypress {
30 | // interface Chainable {
31 | // login(email: string, password: string): Chainable
32 | // drag(subject: string, options?: Partial): Chainable
33 | // dismiss(subject: string, options?: Partial): Chainable
34 | // visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
35 | // }
36 | // }
37 | // }
--------------------------------------------------------------------------------
/apps/web/README.md:
--------------------------------------------------------------------------------
1 | ## Getting Started
2 |
3 | First, run the development server:
4 |
5 | ```bash
6 | yarn dev
7 | ```
8 |
9 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
10 |
11 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
12 |
13 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
14 |
15 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
16 |
17 | ## Learn More
18 |
19 | To learn more about Next.js, take a look at the following resources:
20 |
21 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
22 | - [Learn Next.js](https://nextjs.org/learn/foundations/about-nextjs) - an interactive Next.js tutorial.
23 |
24 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
25 |
26 | ## Deploy on Vercel
27 |
28 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_source=github.com&utm_medium=referral&utm_campaign=turborepo-readme) from the creators of Next.js.
29 |
30 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Fastify tRPC Next.js Starter
2 |
3 | Turborepo setup for using:
4 | - Fastify
5 | - tRPC
6 | - Next.js
7 | - ESLint
8 |
9 | ## Getting Started
10 | ```bash
11 | git clone git@github.com:maybemaby/fastify-trpc-next.git
12 | pnpm i
13 | ```
14 |
15 | ## What's inside?
16 |
17 | This turborepo uses [pnpm](https://pnpm.io) as a package manager. It includes the following packages/apps:
18 |
19 | ### Apps and Packages
20 |
21 | - `api`: a Fastify + tRPC app
22 | - `web`: a [Next.js](https://nextjs.org/) + tRPC app
23 | - `schema` for sharing zod schemas between the `api` and `web` apps
24 | - `ui`: a stub React component library shared by the `web` application
25 | - `eslint-config-custom`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`)
26 | - `eslint-config-custom-server`: `eslint` configuration base for server apps
27 | - `tsconfig`: `tsconfig.json`s used throughout the monorepo
28 |
29 |
30 | Each package/app is 100% [TypeScript](https://www.typescriptlang.org/).
31 |
32 | ### Utilities
33 |
34 | This turborepo has some additional tools already setup for you:
35 |
36 | - [TypeScript](https://www.typescriptlang.org/) for static type checking
37 | - [ESLint](https://eslint.org/) for code linting
38 | - [Prettier](https://prettier.io) for code formatting
39 |
40 | ### Build
41 |
42 | To build all apps and packages, run the following command:
43 |
44 | ```bash
45 | pnpm run build
46 | ```
47 |
48 | ### Develop
49 |
50 | To develop all apps and packages, run the following command:
51 |
52 | ```bash
53 | pnpm run dev
54 | ```
55 | ### Test:E2E
56 |
57 | To run E2E tests with cypress and the api live
58 |
59 | ```bash
60 | pnpm -w run start
61 | pnpm -w run test:e2e
62 | ```
--------------------------------------------------------------------------------
/apps/web/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "web",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "test": "jest --passWithNoTests",
9 | "test:w": "jest --watch",
10 | "test:e2e": "cypress run -b chrome --headed",
11 | "cypress:open": "cypress open",
12 | "build:analyze": "ANALYZE=true next build",
13 | "start": "next start",
14 | "lint": "next lint"
15 | },
16 | "dependencies": {
17 | "@tanstack/react-query": "^4.20.4",
18 | "@trpc/client": "^10.7.0",
19 | "@trpc/next": "^10.7.0",
20 | "@trpc/react-query": "^10.7.0",
21 | "@trpc/server": "^10.7.0",
22 | "next": "^13.2.3",
23 | "react": "18.2.0",
24 | "react-dom": "18.2.0",
25 | "superjson": "^1.12.1",
26 | "ui": "workspace:*"
27 | },
28 | "devDependencies": {
29 | "@babel/core": "^7.0.0",
30 | "@next/bundle-analyzer": "^13.2.3",
31 | "@testing-library/dom": "^9.0.1",
32 | "@testing-library/jest-dom": "^5.16.5",
33 | "@testing-library/react": "^14.0.0",
34 | "@testing-library/user-event": "^14.4.3",
35 | "@types/jest": "^29.2.5",
36 | "@types/node": "^18.14.6",
37 | "@types/react": "^18.0.22",
38 | "@types/react-dom": "^18.0.7",
39 | "@typescript-eslint/eslint-plugin": "^5.47.1",
40 | "@typescript-eslint/parser": "^5.47.1",
41 | "api": "workspace:*",
42 | "cypress": "^12.3.0",
43 | "eslint": "8.35.0",
44 | "eslint-config-custom": "workspace:*",
45 | "eslint-plugin-testing-library": "^5.10.1",
46 | "fastify": "^4.11.0",
47 | "jest": "^29.4.2",
48 | "jest-environment-jsdom": "^29.4.2",
49 | "local-cypress": "^1.2.6",
50 | "tsconfig": "workspace:*",
51 | "typescript": "^4.5.3"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/apps/web/utils/trpc.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable turbo/no-undeclared-env-vars */
2 | import { httpBatchLink, loggerLink } from "@trpc/client";
3 | import type { inferRouterInputs } from "@trpc/server";
4 | import type { inferRouterOutputs } from "@trpc/server";
5 | import { createTRPCNext } from "@trpc/next";
6 | import superjson from "superjson";
7 | import type fastify from "fastify";
8 | import type { AppRouter } from "api/src/types";
9 |
10 | function getBaseUrl() {
11 | if (typeof window !== "undefined")
12 | // browser should use relative path
13 | return process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:5000";
14 | if (process.env.VERCEL_URL)
15 | // reference for vercel.com
16 | return `https://${process.env.VERCEL_URL}`;
17 | if (process.env.RENDER_INTERNAL_HOSTNAME)
18 | // reference for render.com
19 | return `http://${process.env.RENDER_INTERNAL_HOSTNAME}:${process.env.PORT}`;
20 | // assume localhost
21 | return `http://localhost:${process.env.PORT ?? 5000}`;
22 | }
23 |
24 | export const trpc = createTRPCNext({
25 | config({ ctx }) {
26 | return {
27 | queryClientConfig: {
28 | defaultOptions: {
29 | queries: {
30 | refetchOnWindowFocus: false,
31 | },
32 | },
33 | },
34 | transformer: superjson,
35 | links: [
36 | loggerLink({
37 | enabled: (opts) =>
38 | process.env.NODE_ENV === "development" ||
39 | (opts.direction === "down" && opts.result instanceof Error),
40 | }),
41 | httpBatchLink({ url: `${getBaseUrl()}/api` }),
42 | ],
43 | };
44 | },
45 | ssr: false,
46 | });
47 |
48 | export type RouterInputs = inferRouterInputs;
49 | export type RouterOutputs = inferRouterOutputs;
50 |
--------------------------------------------------------------------------------
/apps/api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
4 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
5 | "moduleResolution": "node",
6 | "lib": [
7 | "ESNext"
8 | ] /* Specify library files to be included in the compilation. */,
9 | // "allowJs": true, /* Allow javascript files to be compiled. */
10 | // "checkJs": true, /* Report errors in .js files. */
11 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
12 | "declaration": true /* Generates corresponding '.d.ts' file. */,
13 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
14 | "sourceMap": true /* Generates corresponding '.map' file. */,
15 | // "outFile": "./", /* Concatenate and emit output to single file. */
16 | "outDir": "./dist" /* Redirect output structure to the directory. */,
17 | "resolveJsonModule": true,
18 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
19 | // "composite": true, /* Enable project compilation */
20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
21 | // "removeComments": true, /* Do not emit comments to output. */
22 | // "noEmit": true, /* Do not emit outputs. */
23 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
26 |
27 | /* Strict Type-Checking Options */
28 | "strict": true /* Enable all strict type-checking options. */,
29 | "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
30 | "strictNullChecks": true /* Enable strict null checks. */,
31 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */
32 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
33 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
34 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
35 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
36 |
37 | /* Additional Checks */
38 | "noUnusedLocals": false /* Report errors on unused locals. */,
39 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
40 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
41 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
42 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
43 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
44 | // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
45 |
46 | /* Module Resolution Options */
47 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
48 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
49 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
50 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
51 | // "typeRoots": [], /* List of folders to include type definitions from. */
52 | // "types": [], /* Type declaration files to be included in compilation. */
53 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
54 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
55 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
56 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
57 |
58 | /* Source Map Options */
59 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
60 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
61 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
62 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
63 |
64 | /* Experimental Options */
65 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
66 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
67 |
68 | /* Advanced Options */
69 | "skipLibCheck": true /* Skip type checking of declaration files. */,
70 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
71 | },
72 | "extends": "tsconfig/base.json",
73 | "include": ["src/**/*.ts"],
74 | "exclude": ["./node_modules", "dist"]
75 | }
76 |
--------------------------------------------------------------------------------