Skip to content

Commit

Permalink
init repo
Browse files Browse the repository at this point in the history
  • Loading branch information
aecorredor committed Mar 16, 2024
0 parents commit d70eade
Show file tree
Hide file tree
Showing 88 changed files with 20,333 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dist/**/*
dist-post-ts/**/*
build/**/*
node_modules/**/*
src/generated/**/*
44 changes: 44 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module.exports = {
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:prettier/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
project: `${__dirname}/tsconfig.eslint.json`,
},
plugins: ['import', '@typescript-eslint', 'prettier'],
settings: {
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx'],
},
'import/resolver': {
typescript: {},
node: {
extensions: ['.js', '.ts'],
},
},
},
rules: {
'@typescript-eslint/camelcase': 0,
'@typescript-eslint/no-use-before-define': 0,
'import/no-cycle': ['error', { ignoreExternal: true }],
'import/extensions': 0,
'import/prefer-default-export': 0,
// 'acc' is disabled because that is the convention we use in reducer
// functions, and that value can usually be safely mutated.
// 'req' is disabled because we can attach props to an express request.
// 'draft' is disabled because we use it as the name for immer's draft state
// argument.
'no-param-reassign': [
'error',
{ props: true, ignorePropertyModificationsFor: ['acc', 'req', 'draft'] },
],
'prettier/prettier': 'error',
'no-underscore-dangle': 0,
'no-void': 0,
},
ignorePatterns: ['.eslintrc.js'],
};
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
123 changes: 123 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: deploy

on:
push:
branches:
- main

jobs:
lint-and-test:
runs-on: ubuntu-latest
timeout-minutes: 5

services:
dynamodb:
image: amazon/dynamodb-local
ports:
- "8000:8000"

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Test
run: npm run test:ci
deploy-dev:
runs-on: ubuntu-latest
timeout-minutes: 10
needs: lint-and-test
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Install Pulumi CLI
uses: pulumi/setup-pulumi@v2

- name: Deploy to dev
uses: pulumi/actions@v3
with:
command: up
stack-name: dev
work-dir: ./deploy
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
deploy-prod:
runs-on: ubuntu-latest
timeout-minutes: 10
needs: deploy-dev
steps:
- uses: trstringer/manual-approval@v1
with:
secret: ${{ github.TOKEN }}
approvers: aecorredor
minimum-approvals: 1
issue-title: "Deploying to prod"
issue-body: "Please approve or deny the deployment."

- name: Checkout code
uses: actions/checkout@v3

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.PROD_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.PROD_AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-2

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Build
run: npm run build

- name: Install Pulumi CLI
uses: pulumi/setup-pulumi@v2

- name: Deploy to prod
uses: pulumi/actions@v3
with:
command: up
stack-name: prod
work-dir: ./deploy
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
30 changes: 30 additions & 0 deletions .github/workflows/maintenance-job.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: maintenance-job

on: workflow_dispatch

jobs:
run-job:
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run maintenance jobs
env:
SPORTMONKS_TOKEN: ${{ secrets.SPORTMONKS_TOKEN }}
DEV_AWS_ACCESS_KEY_ID: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }}
DEV_AWS_SECRET_ACCESS_KEY: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}
PROD_AWS_ACCESS_KEY_ID: ${{ secrets.PROD_AWS_ACCESS_KEY_ID }}
PROD_AWS_SECRET_ACCESS_KEY: ${{ secrets.PROD_AWS_SECRET_ACCESS_KEY }}
run: npm run maintenance-job
35 changes: 35 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: pull-request

on:
pull_request:
branches:
- main

jobs:
lint-and-test:
runs-on: ubuntu-latest
timeout-minutes: 5

services:
dynamodb:
image: amazon/dynamodb-local
ports:
- "8000:8000"
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Test
run: npm run test:ci
21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Logs
/logs
*.log
npm-debug.log*

# Dependency directories
/node_modules

# dotenv environment variables file
.env

# misc
.DS_Store

/src/generated/tmp-resolvers

/dist
/dist-post-ts
/build

/dynamodb-local-data
11 changes: 11 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"search.exclude": {
"**/.git": true,
"**/node_modules": true,
"**/generated": true,
},
"yaml.schemas": {
"https://json.schemastore.org/github-workflow.json": "${workspaceFolder}/.github/workflows/*.yml"
},
}
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# serverless-fastify-starter

Starter repo for a TypeScript Node.js serverless service powered by Fastify and
DynamoDB. It includes the base for deploying the service to AWS using
Infrastructure as Code (IaC) with Pulumi. The service is deployed to AWS Lambda
and the API is exposed through AWS API Gateway.

Pretty basic setup so far. I crated this because I got tired of copying and
replacing the same code every time I started a new serverless API. Let's
see where it goes.
14 changes: 14 additions & 0 deletions bin/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as esbuild from 'esbuild';

const build = async () => {
await esbuild.build({
entryPoints: ['dist-post-ts/handlers/api.js'],
bundle: true,
platform: 'node',
minifyWhitespace: true,
target: ['es2020', 'node18'],
outdir: 'dist',
});
};

void build();
23 changes: 23 additions & 0 deletions codegen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
schema: ./src/schemas/**/*
documents: ./src/test/test-operations/**/*
generates:
src/generated/resolvers.ts:
plugins:
- typescript
- typescript-resolvers
config:
enumsAsConst: true
internalResolversPrefix: ''
contextType: mercurius#MercuriusContext
mappers:
# Add custom database mappers here.
# ExampleEntity: ../typings/resolver-mappers#ExampleEntityMapper
src/generated/operations.ts:
plugins:
- typescript
- typescript-operations
- typescript-graphql-request
config:
enumsAsConst: true
dedupeOperationSuffix: true
exportFragmentSpreadSubTypes: true
9 changes: 9 additions & 0 deletions deploy/Pulumi.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
config:
aws:region: us-east-1
serverless-fastify-starter:accessTokenSecret:
secure: create-new-one
serverless-fastify-starter:apiEndpoint: dev.api.addyourdomain.com
serverless-fastify-starter:deployedBy: pulumi
serverless-fastify-starter:project: serverless-fastify-starter
serverless-fastify-starter:sesDomain: addyourdomain.com
pulumi:template: serverless-aws-typescript
9 changes: 9 additions & 0 deletions deploy/Pulumi.prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
config:
aws:region: us-east-2
serverless-fastify-starter:accessTokenSecret:
secure: create-new-one
serverless-fastify-starter:apiEndpoint: api.addyourdomain.com
serverless-fastify-starter:deployedBy: pulumi
serverless-fastify-starter:project: serverless-fastify-starter
serverless-fastify-starter:sesDomain: addyourdomain.com
pulumi:template: serverless-aws-typescript
3 changes: 3 additions & 0 deletions deploy/Pulumi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: serverless-fastify-starter
runtime: nodejs
description: backend service for serverless-fastify-starter
23 changes: 23 additions & 0 deletions deploy/api-gateway.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as apigateway from '@pulumi/aws-apigateway';

import { handler } from './api-handler';

export const apiGateway = new apigateway.RestAPI('serverless-fastify-starter', {
routes: [
{
path: '/graphql',
method: 'GET',
eventHandler: handler,
},
{
path: '/graphql',
method: 'POST',
eventHandler: handler,
},
{
path: '/graphql',
method: 'OPTIONS',
eventHandler: handler,
},
],
});
Loading

0 comments on commit d70eade

Please sign in to comment.