feat(create-turbo): apply official-starter transform

This commit is contained in:
Turbobot
2025-02-08 13:41:40 -08:00
committed by ryan
parent 9fe2818df8
commit c158dda08f
48 changed files with 5621 additions and 24 deletions
+5
View File
@@ -0,0 +1,5 @@
/** @type {import("eslint").Linter.Config} */
module.exports = {
root: true,
extends: ["@repo/eslint-config/server.js"],
};
+47
View File
@@ -0,0 +1,47 @@
FROM node:18-alpine AS base
# The web Dockerfile is copy-pasted into our main docs at /docs/handbook/deploying-with-docker.
# Make sure you update this Dockerfile, the Dockerfile in the web workspace and copy that over to Dockerfile in the docs.
FROM base AS builder
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk update
RUN apk add --no-cache libc6-compat
# Set working directory
WORKDIR /app
RUN yarn global add turbo
COPY . .
RUN turbo prune api --docker
# Add lockfile and package.json's of isolated subworkspace
FROM base AS installer
RUN apk update
RUN apk add --no-cache libc6-compat
WORKDIR /app
# First install dependencies (as they change less often)
COPY --from=builder /app/out/json/ .
RUN yarn install
# Build the project and its dependencies
COPY --from=builder /app/out/full/ .
# Uncomment and use build args to enable remote caching
# ARG TURBO_TEAM
# ENV TURBO_TEAM=$TURBO_TEAM
# ARG TURBO_TOKEN
# ENV TURBO_TOKEN=$TURBO_TOKEN
RUN yarn turbo build
FROM base AS runner
WORKDIR /app
# Don't run production as root
RUN addgroup --system --gid 1001 expressjs
RUN adduser --system --uid 1001 expressjs
USER expressjs
COPY --from=installer /app .
CMD node apps/api/dist/index.js
+42
View File
@@ -0,0 +1,42 @@
{
"name": "api",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "tsc",
"clean": "rm -rf dist",
"dev": "nodemon --exec \"node -r esbuild-register ./src/index.ts\" -e .ts",
"lint": "tsc --noEmit && eslint \"src/**/*.ts*\" --max-warnings 0",
"start": "node -r esbuild-register ./src/index.ts",
"test": "jest --detectOpenHandles"
},
"jest": {
"preset": "@repo/jest-presets/node"
},
"dependencies": {
"@repo/logger": "*",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.18.3",
"morgan": "^1.10.0"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@repo/eslint-config": "*",
"@repo/jest-presets": "*",
"@repo/typescript-config": "*",
"@types/body-parser": "^1.19.5",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/morgan": "^1.9.9",
"@types/node": "^20.11.24",
"@types/supertest": "^6.0.2",
"esbuild": "^0.20.1",
"esbuild-register": "^3.5.0",
"eslint": "^8.57.0",
"jest": "^29.7.0",
"nodemon": "^3.1.0",
"supertest": "^6.3.3",
"typescript": "5.5.4"
}
}
@@ -0,0 +1,23 @@
import supertest from "supertest";
import { describe, it, expect } from "@jest/globals";
import { createServer } from "../server";
describe("server", () => {
it("status check returns 200", async () => {
await supertest(createServer())
.get("/status")
.expect(200)
.then((res) => {
expect(res.body.ok).toBe(true);
});
});
it("message endpoint says hello", async () => {
await supertest(createServer())
.get("/message/jared")
.expect(200)
.then((res) => {
expect(res.body.message).toBe("hello jared");
});
});
});
+9
View File
@@ -0,0 +1,9 @@
import { createServer } from "./server";
import { log } from "@repo/logger";
const port = process.env.PORT || 3001;
const server = createServer();
server.listen(port, () => {
log(`api running on ${port}`);
});
+22
View File
@@ -0,0 +1,22 @@
import { json, urlencoded } from "body-parser";
import express, { type Express } from "express";
import morgan from "morgan";
import cors from "cors";
export const createServer = (): Express => {
const app = express();
app
.disable("x-powered-by")
.use(morgan("dev"))
.use(urlencoded({ extended: true }))
.use(json())
.use(cors())
.get("/message/:name", (req, res) => {
return res.json({ message: `hello ${req.params.name}` });
})
.get("/status", (_, res) => {
return res.json({ ok: true });
});
return app;
};
+10
View File
@@ -0,0 +1,10 @@
{
"extends": "@repo/typescript-config/base.json",
"compilerOptions": {
"lib": ["ES2015"],
"outDir": "./dist",
"rootDir": "./src"
},
"exclude": ["node_modules"],
"include": ["src"]
}