Skip to content

Commit

Permalink
Merge branch 'main' of github.com:redwoodjs/redwood into fix/prerende…
Browse files Browse the repository at this point in the history
…r-rwt-link

* 'main' of github.com:redwoodjs/redwood: (26 commits)
  Router: Fix auth (redwoodjs#2038)
  Steps towards a11y for Redwood Router (redwoodjs#1817)
  Router: <Set wrap={}> (redwoodjs#1898)
  Pass event and context into getCurrentUser (redwoodjs#1908)
  Implement Redwood API side Logger (redwoodjs#1937)
  Fixed path on windows to allow for pages under subdirectories (redwoodjs#2022)
  Add experimental ESBuild for api side (redwoodjs#1948)
  Upgrade to Prisma 2.19.0 (Prisma Migrate GA) (redwoodjs#2021)
  Fix lint breaking when deleting a side (redwoodjs#2017)
  Refactor: Converted Prisma.ts to js (redwoodjs#1958)
  Fix issue with verify email redirect using Auth0 (redwoodjs#1990)
  add GitHub Action CodeQL Analysis (redwoodjs#1951)
  fix: correct var name for grabbing user config (redwoodjs#2002)
  Create functions to fs calls (redwoodjs#2007)
  Return signup Output (redwoodjs#1992)
  Add makeExecSchema options (redwoodjs#1964)
  upgrade gotrue-js to 0.9.29 (redwoodjs#2011)
  Azure Active Directory Auth: Adding try-catch block on callback to capture empty key (redwoodjs#2010)
  withCellHOC: Fix TS error (redwoodjs#1967)
  Update error message in tasks/publish-local to point to tasks/run-local-npm when Verdaccio isn't running (redwoodjs#2004)
  ...
  • Loading branch information
dac09 committed Mar 19, 2021
2 parents 2141ed0 + 44608cc commit 62e6bec
Show file tree
Hide file tree
Showing 88 changed files with 4,704 additions and 2,950 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '42 5 * * 3'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed

steps:
- name: Checkout repository
uses: actions/checkout@v2

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl

# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language

#- run: |
# make bootstrap
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use:
- [React](https://reactjs.org/)
- [GraphQL](https://graphql.org/) ([Apollo](https://github.com/apollographql))
- [Prisma](https://www.prisma.io/)
- [Jest](https://jestjs.io/) (coming soon)
- [Jest](https://jestjs.io/)
- [Storybook](https://storybook.js.org/)
- [Babel](https://babeljs.io/)
- [Webpack](https://webpack.js.org/)
Expand Down
23 changes: 11 additions & 12 deletions __fixtures__/example-todo-main/api/src/functions/graphql.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ import {
makeMergedSchema,
makeServices,
} from '@redwoodjs/api'
import importAll from '@redwoodjs/api/importAll.macro'

import schemas from 'src/graphql/**/*.{js,ts}'
import { db } from 'src/lib/db'
import services from 'src/services/**/*.{js,ts}'

const schemas = importAll('api', 'graphql')
const services = importAll('api', 'services')

export const handler = createGraphQLHandler(
{
schema: makeMergedSchema({
schemas,
services: makeServices({ services }),
}),
export const handler = createGraphQLHandler({
schema: makeMergedSchema({
schemas,
services: makeServices({ services }),
}),
onException: () => {
// Disconnect from your database with an unhandled exception.
db.$disconnect()
},
db
)
})
6 changes: 6 additions & 0 deletions __fixtures__/example-todo-main/api/src/lib/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// See https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/constructor
// for options.

import { PrismaClient } from '@prisma/client'

export const db = new PrismaClient()
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.26.2",
"version": "0.27.1",
"npmClient": "yarn",
"useWorkspaces": true,
"command": {
Expand Down
4 changes: 0 additions & 4 deletions packages/api-server/ambient.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
declare module '@babel/register' {
export default function (options: unknown): void
}

declare module 'youch-terminal' {
export default function (json: Record<string, unknown>): string
}
16 changes: 10 additions & 6 deletions packages/api-server/package.json
Original file line number Diff line number Diff line change
@@ -1,39 +1,43 @@
{
"name": "@redwoodjs/api-server",
"description": "Redwood's HTTP server for Serverless Functions",
"version": "0.26.2",
"version": "0.27.1",
"bin": {
"api-server": "./dist/index.js"
"api-server": "./dist/index.js",
"rw-api-server": "./dist/index.js",
"rw-api-server-watch": "./dist/watch.js"
},
"files": [
"dist"
],
"license": "MIT",
"dependencies": {
"@babel/register": "^7.9.0",
"body-parser": "^1.19.0",
"chokidar": "3.5.1",
"dotenv-defaults": "2.0.1",
"express": "^4.17.1",
"glob": "7.1.6",
"lodash.escape": "^4.0.1",
"morgan": "^1.10.0",
"qs": "^6.9.3",
"require-dir": "^1.2.0",
"yargs": "^16.0.3",
"youch": "^2.1.1",
"youch-terminal": "^1.0.1"
},
"devDependencies": {
"@types/aws-lambda": "^8.10.46",
"@types/express": "^4.17.3",
"@types/lodash.escape": "^4.0.6",
"@types/morgan": "^1.9.0",
"@types/qs": "^6.9.1",
"@types/require-dir": "^1.0.1",
"@types/stack-trace": "^0.0.29"
},
"scripts": {
"build": "yarn build:js",
"prepublishOnly": "yarn cross-env NODE_ENV=production yarn build",
"build:js": "babel src -d dist --extensions \".js,.ts,.tsx\"",
"build:watch": "nodemon --watch src --ext \"js,ts,tsx\" --ignore dist --exec \"yarn build && yarn fix:permissions\"",
"fix:permissions": "chmod +x dist/index.js"
"fix:permissions": "chmod +x dist/index.js; chmod +x dist/watch.js"
},
"gitHead": "c235e7d7186e5e258764699c0e0e1d5cc0fdd0b5"
}
88 changes: 65 additions & 23 deletions packages/api-server/src/http.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,91 @@
import fs from 'fs'
import path from 'path'

import type { Handler } from 'aws-lambda'
import bodyParser from 'body-parser'
import type { Response, Request } from 'express'
import express from 'express'
import glob from 'glob'
import escape from 'lodash.escape'
import morgan from 'morgan'

export interface Lambdas {
[path: string]: any
import { getPaths } from '@redwoodjs/internal'
const rwjsPaths = getPaths()

import { requestHandler } from './requestHandlers/awsLambda'

export type Lambdas = Record<string, Handler>
const LAMBDA_FUNCTIONS: Lambdas = {}
export const setLambdaFunctions = (foundFunctions: string[]) => {
for (const fnPath of foundFunctions) {
const routeName = path.basename(fnPath).replace('.js', '')
const { handler } = require(fnPath)
LAMBDA_FUNCTIONS[routeName] = handler
if (!handler) {
console.warn(
routeName,
'at',
fnPath,
'does not have a function called handler defined.'
)
}
}
}
let LAMBDA_FUNCTIONS: Lambdas = {}
export const setLambdaFunctions = (functions: Lambdas): void => {
LAMBDA_FUNCTIONS = functions

const lambdaRequestHandler = async (req: Request, res: Response) => {
const { routeName } = req.params
if (!LAMBDA_FUNCTIONS[routeName]) {
const errorMessage = `Function "${routeName}" was not found.`
console.error(errorMessage)
res.status(404).send(escape(errorMessage))
return
}
return requestHandler(req, res, LAMBDA_FUNCTIONS[routeName])
}

export const server = ({
requestHandler,
export const http = ({
port = 8911,
socket,
}: {
requestHandler: (req: Request, res: Response, lambdaFunction: any) => void
}): any => {
port: number
socket?: string
}) => {
const app = express()

app.use(
bodyParser.text({
type: ['text/*', 'application/json', 'multipart/form-data'],
})
)

app.use(
bodyParser.raw({
type: '*/*',
limit: process.env.BODY_PARSER_LIMIT,
})
)

app.use(morgan<Request, Response>('dev'))

const lambdaHandler = async (req: Request, res: Response): Promise<void> => {
const { routeName } = req.params
const lambdaFunction = LAMBDA_FUNCTIONS[routeName]
if (!lambdaFunction) {
const errorMessage = `Function "${routeName}" was not found.`
console.error(errorMessage)
res.status(404).send(errorMessage)
return
}
await requestHandler(req, res, lambdaFunction)
}
app.all('/:routeName', lambdaRequestHandler)
app.all('/:routeName/*', lambdaRequestHandler)

app.all('/:routeName', lambdaHandler)
app.all('/:routeName/*', lambdaHandler)
const server = app
.listen(socket || port, () => {
const ts = Date.now()
console.log('Importing API... ')
const apiFunctions = glob.sync('dist/functions/*.{ts,js}', {
cwd: rwjsPaths.api.base,
absolute: true,
})
setLambdaFunctions(apiFunctions)
console.log('Imported in', Date.now() - ts, 'ms')
})
.on('close', () => {
if (socket) {
fs.rmSync(socket)
}
})

return app
return server
}
71 changes: 18 additions & 53 deletions packages/api-server/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,25 @@
#!/usr/bin/env node
import { rmSync } from 'fs'
import path from 'path'

import requireDir from 'require-dir'
import yargs from 'yargs'

import { server, setLambdaFunctions } from './http'
import { requestHandler } from './requestHandlers/awsLambda'

const { port, functions, socket } = yargs
.option('port', { default: 8911, type: 'number' })
.option('socket', { type: 'string' })
.option('functions', {
alias: 'f',
required: true,
type: 'string',
desc: 'The path where your Serverless Functions are stored',
}).argv
import { http } from './http'

if (process.env.NODE_ENV !== 'production') {
console.info(`NODE_ENV ${process.env.NODE_ENV}`)
// Transpile files during development,
// this command has to be run from the "api" directory.
const babelRequireHook = require('@babel/register')
babelRequireHook({
extends: path.join(process.cwd(), '.babelrc.js'),
extensions: ['.js', '.ts'],
only: [process.cwd()],
ignore: ['node_modules'],
cache: false,
})
if (process.argv0 === 'api-server') {
console.log()
console.warn(
'"api-server" is deprecated, please use "rw-api-server" instead.'
)
console.log()
}

const serverlessFunctions = requireDir(path.join(process.cwd(), functions), {
recurse: false,
extensions: ['.js', '.ts'],
})

try {
const app = server({ requestHandler }).listen(socket || port, () => {
if (socket) {
console.log(socket)
} else {
console.log(`http://localhost:${port}`)
}
setLambdaFunctions(serverlessFunctions)
})
const { port, socket } = yargs
.option('port', { default: 8911, type: 'number', alias: 'p' })
.option('socket', { type: 'string' }).argv

process.on('exit', () => {
app.close(() => {
if (socket) {
rmSync(socket)
}
})
})
} catch (e) {
console.error(e)
process.exit(1)
}
http({ port, socket }).on('listening', () => {
if (socket) {
console.log(`Listening on ${socket}`)
} else {
console.log(`Listening on http://localhost:${port}`)
}
console.log()
})
Loading

0 comments on commit 62e6bec

Please sign in to comment.