First commit
@ -0,0 +1,10 @@
|
||||
# editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
@ -0,0 +1,19 @@
|
||||
# These environment variables will be used by default if you do not create any
|
||||
# yourself in .env. This file should be safe to check into your version control
|
||||
# system. Any custom values should go in .env and .env should *not* be checked
|
||||
# into version control.
|
||||
|
||||
# schema.prisma defaults
|
||||
DATABASE_URL=file:./dev.db
|
||||
|
||||
# location of the test database for api service scenarios (defaults to ./.redwood/test.db if not set)
|
||||
# TEST_DATABASE_URL=file:./.redwood/test.db
|
||||
|
||||
# disables Prisma CLI update notifier
|
||||
PRISMA_HIDE_UPDATE_MESSAGE=true
|
||||
|
||||
# Option to override the current environment's default api-side log level
|
||||
# See: https://redwoodjs.com/docs/logger for level options, defaults to "trace" otherwise.
|
||||
# Most applications want "debug" or "info" during dev, "trace" when you have issues and "warn" in production.
|
||||
# Ordered by how verbose they are: trace | debug | info | warn | error | silent
|
||||
# LOG_LEVEL=debug
|
@ -0,0 +1,4 @@
|
||||
# DATABASE_URL=file:./dev.db
|
||||
# TEST_DATABASE_URL=file:./.redwood/test.db
|
||||
# PRISMA_HIDE_UPDATE_MESSAGE=true
|
||||
# LOG_LEVEL=trace
|
@ -1,132 +1,22 @@
|
||||
# ---> Node
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.idea
|
||||
.DS_Store
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
.netlify
|
||||
.redwood/*
|
||||
!.redwood/README.md
|
||||
dev.db*
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
dist-babel
|
||||
node_modules
|
||||
yarn-error.log
|
||||
web/public/mockServiceWorker.js
|
||||
web/types/graphql.d.ts
|
||||
api/types/graphql.d.ts
|
||||
api/src/lib/generateGraphiQLHeader.*
|
||||
.pnp.*
|
||||
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
@ -0,0 +1,18 @@
|
||||
datasource db {
|
||||
provider = "sqlite"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
binaryTargets = "native"
|
||||
}
|
||||
|
||||
// Define your own datamodels here and run `yarn redwood prisma migrate dev`
|
||||
// to create migrations for them and apply to your dev DB.
|
||||
// TODO: Please remove the following example:
|
||||
model UserExample {
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique
|
||||
name String?
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
// More info at https://redwoodjs.com/docs/project-configuration-dev-test-build
|
||||
|
||||
const config = {
|
||||
rootDir: '../',
|
||||
preset: '@redwoodjs/testing/config/jest/api',
|
||||
}
|
||||
|
||||
module.exports = config
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "api",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@redwoodjs/api": "6.0.6",
|
||||
"@redwoodjs/graphql-server": "6.0.6"
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* This file allows you to configure the Fastify Server settings
|
||||
* used by the RedwoodJS dev server.
|
||||
*
|
||||
* It also applies when running RedwoodJS with `yarn rw serve`.
|
||||
*
|
||||
* For the Fastify server options that you can set, see:
|
||||
* https://www.fastify.io/docs/latest/Reference/Server/#factory
|
||||
*
|
||||
* Examples include: logger settings, timeouts, maximum payload limits, and more.
|
||||
*
|
||||
* Note: This configuration does not apply in a serverless deploy.
|
||||
*/
|
||||
|
||||
/** @type {import('fastify').FastifyServerOptions} */
|
||||
const config = {
|
||||
requestTimeout: 15_000,
|
||||
logger: {
|
||||
// Note: If running locally using `yarn rw serve` you may want to adjust
|
||||
// the default non-development level to `info`
|
||||
level: process.env.NODE_ENV === 'development' ? 'debug' : 'warn',
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* You can also register Fastify plugins and additional routes for the API and Web sides
|
||||
* in the configureFastify function.
|
||||
*
|
||||
* This function has access to the Fastify instance and options, such as the side
|
||||
* (web, api, or proxy) that is being configured and other settings like the apiRootPath
|
||||
* of the functions endpoint.
|
||||
*
|
||||
* Note: This configuration does not apply in a serverless deploy.
|
||||
*/
|
||||
|
||||
/** @type {import('@redwoodjs/api-server/dist/fastify').FastifySideConfigFn} */
|
||||
const configureFastify = async (fastify, options) => {
|
||||
if (options.side === 'api') {
|
||||
fastify.log.trace({ custom: { options } }, 'Configuring api side')
|
||||
}
|
||||
|
||||
if (options.side === 'web') {
|
||||
fastify.log.trace({ custom: { options } }, 'Configuring web side')
|
||||
}
|
||||
|
||||
return fastify
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
config,
|
||||
configureFastify,
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
import { mockRedwoodDirective, getDirectiveName } from '@redwoodjs/testing/api'
|
||||
|
||||
import requireAuth from './requireAuth'
|
||||
|
||||
describe('requireAuth directive', () => {
|
||||
it('declares the directive sdl as schema, with the correct name', () => {
|
||||
expect(requireAuth.schema).toBeTruthy()
|
||||
expect(getDirectiveName(requireAuth.schema)).toBe('requireAuth')
|
||||
})
|
||||
|
||||
it('requireAuth has stub implementation. Should not throw when current user', () => {
|
||||
// If you want to set values in context, pass it through e.g.
|
||||
// mockRedwoodDirective(requireAuth, { context: { currentUser: { id: 1, name: 'Lebron McGretzky' } }})
|
||||
const mockExecution = mockRedwoodDirective(requireAuth, { context: {} })
|
||||
|
||||
expect(mockExecution).not.toThrowError()
|
||||
})
|
||||
})
|
@ -0,0 +1,27 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
import {
|
||||
createValidatorDirective,
|
||||
ValidatorDirectiveFunc,
|
||||
} from '@redwoodjs/graphql-server'
|
||||
|
||||
import { requireAuth as applicationRequireAuth } from 'src/lib/auth'
|
||||
|
||||
export const schema = gql`
|
||||
"""
|
||||
Use to check whether or not a user is authenticated and is associated
|
||||
with an optional set of roles.
|
||||
"""
|
||||
directive @requireAuth(roles: [String]) on FIELD_DEFINITION
|
||||
`
|
||||
|
||||
type RequireAuthValidate = ValidatorDirectiveFunc<{ roles?: string[] }>
|
||||
|
||||
const validate: RequireAuthValidate = ({ directiveArgs }) => {
|
||||
const { roles } = directiveArgs
|
||||
applicationRequireAuth({ roles })
|
||||
}
|
||||
|
||||
const requireAuth = createValidatorDirective(schema, validate)
|
||||
|
||||
export default requireAuth
|
@ -0,0 +1,10 @@
|
||||
import { getDirectiveName } from '@redwoodjs/testing/api'
|
||||
|
||||
import skipAuth from './skipAuth'
|
||||
|
||||
describe('skipAuth directive', () => {
|
||||
it('declares the directive sdl as schema, with the correct name', () => {
|
||||
expect(skipAuth.schema).toBeTruthy()
|
||||
expect(getDirectiveName(skipAuth.schema)).toBe('skipAuth')
|
||||
})
|
||||
})
|
@ -0,0 +1,16 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
import { createValidatorDirective } from '@redwoodjs/graphql-server'
|
||||
|
||||
export const schema = gql`
|
||||
"""
|
||||
Use to skip authentication checks and allow public access.
|
||||
"""
|
||||
directive @skipAuth on FIELD_DEFINITION
|
||||
`
|
||||
|
||||
const skipAuth = createValidatorDirective(schema, () => {
|
||||
return
|
||||
})
|
||||
|
||||
export default skipAuth
|
@ -0,0 +1,19 @@
|
||||
import { createGraphQLHandler } from '@redwoodjs/graphql-server'
|
||||
|
||||
import directives from 'src/directives/**/*.{js,ts}'
|
||||
import sdls from 'src/graphql/**/*.sdl.{js,ts}'
|
||||
import services from 'src/services/**/*.{js,ts}'
|
||||
|
||||
import { db } from 'src/lib/db'
|
||||
import { logger } from 'src/lib/logger'
|
||||
|
||||
export const handler = createGraphQLHandler({
|
||||
loggerConfig: { logger, options: {} },
|
||||
directives,
|
||||
sdls,
|
||||
services,
|
||||
onException: () => {
|
||||
// Disconnect from your database with an unhandled exception.
|
||||
db.$disconnect()
|
||||
},
|
||||
})
|
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Once you are ready to add authentication to your application
|
||||
* you'll build out requireAuth() with real functionality. For
|
||||
* now we just return `true` so that the calls in services
|
||||
* have something to check against, simulating a logged
|
||||
* in user that is allowed to access that service.
|
||||
*
|
||||
* See https://redwoodjs.com/docs/authentication for more info.
|
||||
*/
|
||||
export const isAuthenticated = () => {
|
||||
return true
|
||||
}
|
||||
|
||||
export const hasRole = ({ roles }) => {
|
||||
return roles !== undefined
|
||||
}
|
||||
|
||||
// This is used by the redwood directive
|
||||
// in ./api/src/directives/requireAuth
|
||||
|
||||
// Roles are passed in by the requireAuth directive if you have auth setup
|
||||
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
||||
export const requireAuth = ({ roles }) => {
|
||||
return isAuthenticated()
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// See https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/constructor
|
||||
// for options.
|
||||
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
|
||||
import { emitLogLevels, handlePrismaLogging } from '@redwoodjs/api/logger'
|
||||
|
||||
import { logger } from './logger'
|
||||
|
||||
/*
|
||||
* Instance of the Prisma Client
|
||||
*/
|
||||
export const db = new PrismaClient({
|
||||
log: emitLogLevels(['info', 'warn', 'error']),
|
||||
})
|
||||
|
||||
handlePrismaLogging({
|
||||
db,
|
||||
logger,
|
||||
logLevels: ['info', 'warn', 'error'],
|
||||
})
|
@ -0,0 +1,17 @@
|
||||
import { createLogger } from '@redwoodjs/api/logger'
|
||||
|
||||
/**
|
||||
* Creates a logger with RedwoodLoggerOptions
|
||||
*
|
||||
* These extend and override default LoggerOptions,
|
||||
* can define a destination like a file or other supported pino log transport stream,
|
||||
* and sets whether or not to show the logger configuration settings (defaults to false)
|
||||
*
|
||||
* @param RedwoodLoggerOptions
|
||||
*
|
||||
* RedwoodLoggerOptions have
|
||||
* @param {options} LoggerOptions - defines how to log, such as redaction and format
|
||||
* @param {string | DestinationStream} destination - defines where to log, such as a transport stream or file
|
||||
* @param {boolean} showConfig - whether to display logger configuration on initialization
|
||||
*/
|
||||
export const logger = createLogger({})
|
@ -0,0 +1,35 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": false,
|
||||
"baseUrl": "./",
|
||||
"rootDirs": [
|
||||
"./src",
|
||||
"../.redwood/types/mirror/api/src"
|
||||
],
|
||||
"paths": {
|
||||
"src/*": [
|
||||
"./src/*",
|
||||
"../.redwood/types/mirror/api/src/*"
|
||||
],
|
||||
"types/*": ["./types/*", "../types/*"],
|
||||
"@redwoodjs/testing": ["../node_modules/@redwoodjs/testing/api"]
|
||||
},
|
||||
"typeRoots": [
|
||||
"../node_modules/@types",
|
||||
"./node_modules/@types"
|
||||
],
|
||||
"types": ["jest"]
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
"../.redwood/types/includes/all-*",
|
||||
"../.redwood/types/includes/api-*",
|
||||
"../types"
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 965 B |
@ -0,0 +1,22 @@
|
||||
const Jimp = require("jimp")
|
||||
|
||||
async function generateColorbar() {
|
||||
const base = await Jimp.create(300, 8, '#e7e2dc')
|
||||
const pixel = await Jimp.create(1, 8, '#788ea5')
|
||||
for (let i=0; i < 300; i++) {
|
||||
const hue = i
|
||||
base.composite(
|
||||
pixel.color([
|
||||
{apply: 'spin', params: [1]}
|
||||
]),
|
||||
i,
|
||||
0,
|
||||
{ mode: Jimp.BLEND_SOURCE_OVER }
|
||||
)
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
generateColorbar().then( (result) => {
|
||||
result.write('./web/public/img/colorbar.png')
|
||||
})
|
@ -0,0 +1,5 @@
|
||||
const { getPaths } = require('@redwoodjs/internal')
|
||||
|
||||
module.exports = {
|
||||
schema: getPaths().generated.schema,
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
// This the Redwood root jest config
|
||||
// Each side, e.g. ./web/ and ./api/ has specific config that references this root
|
||||
// More info at https://redwoodjs.com/docs/project-configuration-dev-test-build
|
||||
|
||||
module.exports = {
|
||||
rootDir: '.',
|
||||
projects: ['<rootDir>/{*,!(node_modules)/**/}/jest.config.js'],
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
{
|
||||
"private": true,
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"api",
|
||||
"web"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@redwoodjs/core": "6.0.6"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "@redwoodjs/eslint-config",
|
||||
"root": true
|
||||
},
|
||||
"engines": {
|
||||
"node": "=18.x",
|
||||
"yarn": ">=1.15"
|
||||
},
|
||||
"prisma": {
|
||||
"seed": "yarn rw exec seed"
|
||||
},
|
||||
"packageManager": "yarn@3.6.1",
|
||||
"dependencies": {
|
||||
"browserify-zlib": "^0.2.0",
|
||||
"https-browserify": "^1.0.0",
|
||||
"jimp": "^0.16.2",
|
||||
"js-file-download": "^0.4.12",
|
||||
"node-polyfill-webpack-plugin": "^2.0.1",
|
||||
"path-browserify": "^1.0.1",
|
||||
"process": "^0.11.10",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"stream-http": "^3.2.0"
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
// https://prettier.io/docs/en/options.html
|
||||
/** @type {import('prettier').RequiredOptions} */
|
||||
module.exports = {
|
||||
trailingComma: 'es5',
|
||||
bracketSpacing: true,
|
||||
tabWidth: 2,
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
arrowParens: 'always',
|
||||
overrides: [
|
||||
{
|
||||
files: 'Routes.*',
|
||||
options: {
|
||||
printWidth: 999,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
source ~/.nvm/nvm.sh
|
||||
nvm use 18
|
||||
if [ "$1" == "build" ]; then
|
||||
yarn rw build
|
||||
fi
|
||||
yarn rw serve -p 8969
|
@ -0,0 +1,22 @@
|
||||
# This file contains the configuration settings for your Redwood app.
|
||||
# This file is also what makes your Redwood app a Redwood app.
|
||||
# If you remove it and try to run `yarn rw dev`, you'll get an error.
|
||||
#
|
||||
# For the full list of options, see the "App Configuration: redwood.toml" doc:
|
||||
# https://redwoodjs.com/docs/app-configuration-redwood-toml
|
||||
|
||||
[web]
|
||||
bundler = "webpack"
|
||||
title = "Redwood App"
|
||||
port = 8910
|
||||
apiUrl = "/.redwood/functions" # You can customize graphql and dbauth urls individually too: see https://redwoodjs.com/docs/app-configuration-redwood-toml#api-paths
|
||||
includeEnvironmentVariables = [
|
||||
# Add any ENV vars that should be available to the web side to this array
|
||||
# See https://redwoodjs.com/docs/environment-variables#web
|
||||
]
|
||||
[api]
|
||||
port = 8911
|
||||
[browser]
|
||||
open = true
|
||||
[notifications]
|
||||
versionUpdates = ["latest"]
|
@ -0,0 +1,63 @@
|
||||
import type { Prisma } from '@prisma/client'
|
||||
import { db } from 'api/src/lib/db'
|
||||
|
||||
export default async () => {
|
||||
try {
|
||||
//
|
||||
// Manually seed via `yarn rw prisma db seed`
|
||||
// Seeds automatically with `yarn rw prisma migrate dev` and `yarn rw prisma migrate reset`
|
||||
//
|
||||
// Update "const data = []" to match your data model and seeding needs
|
||||
//
|
||||
const data: Prisma.UserExampleCreateArgs['data'][] = [
|
||||
// To try this example data with the UserExample model in schema.prisma,
|
||||
// uncomment the lines below and run 'yarn rw prisma migrate dev'
|
||||
//
|
||||
// { name: 'alice', email: 'alice@example.com' },
|
||||
// { name: 'mark', email: 'mark@example.com' },
|
||||
// { name: 'jackie', email: 'jackie@example.com' },
|
||||
// { name: 'bob', email: 'bob@example.com' },
|
||||
]
|
||||
console.log(
|
||||
"\nUsing the default './scripts/seed.{js,ts}' template\nEdit the file to add seed data\n"
|
||||
)
|
||||
|
||||
// Note: if using PostgreSQL, using `createMany` to insert multiple records is much faster
|
||||
// @see: https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#createmany
|
||||
Promise.all(
|
||||
//
|
||||
// Change to match your data model and seeding needs
|
||||
//
|
||||
data.map(async (data: Prisma.UserExampleCreateArgs['data']) => {
|
||||
const record = await db.userExample.create({ data })
|
||||
console.log(record)
|
||||
})
|
||||
)
|
||||
|
||||
// If using dbAuth and seeding users, you'll need to add a `hashedPassword`
|
||||
// and associated `salt` to their record. Here's how to create them using
|
||||
// the same algorithm that dbAuth uses internally:
|
||||
//
|
||||
// import { hashPassword } from '@redwoodjs/auth-dbauth-api'
|
||||
//
|
||||
// const users = [
|
||||
// { name: 'john', email: 'john@example.com', password: 'secret1' },
|
||||
// { name: 'jane', email: 'jane@example.com', password: 'secret2' }
|
||||
// ]
|
||||
//
|
||||
// for (const user of users) {
|
||||
// const [hashedPassword, salt] = hashPassword(user.password)
|
||||
// await db.user.create({
|
||||
// data: {
|
||||
// name: user.name,
|
||||
// email: user.email,
|
||||
// hashedPassword,
|
||||
// salt
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
} catch (error) {
|
||||
console.warn('Please define your seed data.')
|
||||
console.error(error)
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"$api/*": [
|
||||
"../api/*"
|
||||
],
|
||||
"api/*": [
|
||||
"../api/*"
|
||||
],
|
||||
"$web/*": [
|
||||
"../web/*"
|
||||
],
|
||||
"web/*": [
|
||||
"../web/*"
|
||||
],
|
||||
"$web/src/*": [
|
||||
"../web/src/*",
|
||||
"../.redwood/types/mirror/web/src/*"
|
||||
],
|
||||
"web/src/*": [
|
||||
"../web/src/*",
|
||||
"../.redwood/types/mirror/web/src/*"
|
||||
],
|
||||
"types/*": ["../types/*", "../web/types/*", "../api/types/*"]
|
||||
},
|
||||
"typeRoots": ["../node_modules/@types"],
|
||||
"jsx": "preserve"
|
||||
},
|
||||
"include": [
|
||||
".",
|
||||
"../.redwood/types/includes/all-*",
|
||||
"../.redwood/types/includes/web-*",
|
||||
"../types"
|
||||
]
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
// This object will be used to override Chakra-UI theme defaults.
|
||||
// See https://chakra-ui.com/docs/styled-system/theming/theme for theming options
|
||||
const theme = {}
|
||||
export default theme
|
@ -0,0 +1,23 @@
|
||||
import * as React from 'react'
|
||||
import { ChakraProvider, extendTheme } from '@chakra-ui/react'
|
||||
import * as theme from 'config/chakra.config'
|
||||
/** @type { import("@storybook/csf").GlobalTypes } */
|
||||
export const globalTypes = {}
|
||||
/**
|
||||
* An example, no-op storybook decorator. Use a function like this to create decorators.
|
||||
* @param { import("@storybook/addons").StoryFn} StoryFn
|
||||
* @param { import("@storybook/addons").StoryContext} context
|
||||
* @returns StoryFn, unmodified.
|
||||
*/
|
||||
const _exampleDecorator = (StoryFn, _context) => {
|
||||
return <StoryFn />
|
||||
}
|
||||
const extendedTheme = extendTheme(theme)
|
||||
const withChakra = (StoryFn) => {
|
||||
return (
|
||||
<ChakraProvider theme={extendedTheme}>
|
||||
<StoryFn />
|
||||
</ChakraProvider>
|
||||
)
|
||||
}
|
||||
export const decorators = [withChakra]
|
@ -0,0 +1,40 @@
|
||||
/** @returns {import('webpack').Configuration} Webpack Configuration */
|
||||
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
|
||||
var webpack = require('webpack')
|
||||
|
||||
module.exports = (config, { mode }) => {
|
||||
if (mode === 'development') {
|
||||
// Add dev plugin
|
||||
}
|
||||
|
||||
config.module.rules.push({
|
||||
resolve: {
|
||||
fallback: {
|
||||
fs: false,
|
||||
path: require.resolve('path-browserify'),
|
||||
http: require.resolve('stream-http'),
|
||||
https: require.resolve('https-browserify'),
|
||||
zlib: require.resolve('browserify-zlib'),
|
||||
stream: require.resolve('stream-browserify'),
|
||||
querystring: require.resolve('querystring-es3')
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
config.plugins.push(
|
||||
// fix "process is not defined" error:
|
||||
// (do "npm install process" before running the build)
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser.js',
|
||||
Buffer: ['buffer', 'Buffer'],
|
||||
})
|
||||
)
|
||||
|
||||
// Add custom rules for your project
|
||||
// config.module.rules.push(YOUR_RULE)
|
||||
|
||||
// Add custom plugins for your project
|
||||
// config.plugins.push(YOUR_PLUGIN)
|
||||
|
||||
return config
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
// More info at https://redwoodjs.com/docs/project-configuration-dev-test-build
|
||||
|
||||
const config = {
|
||||
rootDir: '../',
|
||||
preset: '@redwoodjs/testing/config/jest/web',
|
||||
}
|
||||
|
||||
module.exports = config
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "web",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"browserslist": {
|
||||
"development": [
|
||||
"last 1 version"
|
||||
],
|
||||
"production": [
|
||||
"defaults"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@chakra-ui/react": "^2",
|
||||
"@emotion/react": "^11",
|
||||
"@emotion/styled": "^11",
|
||||
"@redwoodjs/forms": "6.0.6",
|
||||
"@redwoodjs/router": "6.0.6",
|
||||
"@redwoodjs/web": "6.0.6",
|
||||
"framer-motion": "^9",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@redwoodjs/vite": "6.0.6"
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
# Static Assets
|
||||
Use this folder to add static files directly to your app. All included files and folders will be copied directly into the `/dist` folder (created when Vite builds for production). They will also be available during development when you run `yarn rw dev`.
|
||||
>Note: files will *not* hot reload while the development server is running. You'll need to manually stop/start to access file changes.
|
||||
|
||||
### Example Use
|
||||
A file like `favicon.png` will be copied to `/dist/favicon.png`. A folder containing a file such as `static-files/my-logo.jpg` will be copied to `/dist/static-files/my-logo.jpg`. These can be referenced in your code directly without any special handling, e.g.
|
||||
```
|
||||
<link rel="icon" type="image/png" href="/favicon.png" />
|
||||
```
|
||||
and
|
||||
```
|
||||
<img src="/static-files/my-logo.jpg"> alt="Logo" />
|
||||
```
|
||||
|
||||
|
||||
## Best Practices
|
||||
Because assets in this folder are bypassing the javascript module system, **this folder should be used sparingly** for assets such as favicons, robots.txt, manifests, libraries incompatible with Vite, etc.
|
||||
|
||||
In general, it's best to import files directly into a template, page, or component. This allows Vite to include that file in the bundle when small enough, or to copy it over to the `dist` folder with a hash.
|
||||
|
||||
### Example Asset Import with Vite
|
||||
Instead of handling our logo image as a static file per the example above, we can do the following:
|
||||
```
|
||||
import React from "react"
|
||||
import logo from "./my-logo.jpg"
|
||||
|
||||
|
||||
function Header() {
|
||||
return <img src={logo} alt="Logo" />
|
||||
}
|
||||
|
||||
export default Header
|
||||
```
|
||||
|
||||
See Vite's docs for [static asset handling](https://vitejs.dev/guide/assets.html)
|
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 329 B |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 5.6 KiB |
@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow:
|
@ -0,0 +1,27 @@
|
||||
import { FatalErrorBoundary, RedwoodProvider } from '@redwoodjs/web'
|
||||
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'
|
||||
|
||||
import { ChakraProvider, ColorModeScript, extendTheme } from '@chakra-ui/react'
|
||||
import * as theme from 'config/chakra.config'
|
||||
|
||||
import FatalErrorPage from 'src/pages/FatalErrorPage'
|
||||
import Routes from 'src/Routes'
|
||||
|
||||
import './index.css'
|
||||
|
||||
const extendedTheme = extendTheme(theme)
|
||||
|
||||
const App = () => (
|
||||
<FatalErrorBoundary page={FatalErrorPage}>
|
||||
<RedwoodProvider titleTemplate="%PageTitle | %AppTitle">
|
||||
<ColorModeScript />
|
||||
<ChakraProvider theme={extendedTheme}>
|
||||
<RedwoodApolloProvider>
|
||||
<Routes />
|
||||
</RedwoodApolloProvider>
|
||||
</ChakraProvider>
|
||||
</RedwoodProvider>
|
||||
</FatalErrorBoundary>
|
||||
)
|
||||
|
||||
export default App
|
@ -0,0 +1,21 @@
|
||||
// In this file, all Page components from 'src/pages` are auto-imported. Nested
|
||||
// directories are supported, and should be uppercase. Each subdirectory will be
|
||||
// prepended onto the component name.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// 'src/pages/HomePage/HomePage.js' -> HomePage
|
||||
// 'src/pages/Admin/BooksPage/BooksPage.js' -> AdminBooksPage
|
||||
|
||||
import { Router, Route } from '@redwoodjs/router'
|
||||
|
||||
const Routes = () => {
|
||||
return (
|
||||
<Router>
|
||||
<Route path="/" page={HomePage} name="home" />
|
||||
<Route notfound page={NotFoundPage} />
|
||||
</Router>
|
||||
)
|
||||
}
|
||||
|
||||
export default Routes
|
@ -0,0 +1,17 @@
|
||||
import { hydrateRoot, createRoot } from 'react-dom/client'
|
||||
|
||||
import App from './App'
|
||||
/**
|
||||
* When `#redwood-app` isn't empty then it's very likely that you're using
|
||||
* prerendering. So React attaches event listeners to the existing markup
|
||||
* rather than replacing it.
|
||||
* https://reactjs.org/docs/react-dom-client.html#hydrateroot
|
||||
*/
|
||||
const redwoodAppElement = document.getElementById('redwood-app')
|
||||
|
||||
if (redwoodAppElement.children?.length > 0) {
|
||||
hydrateRoot(redwoodAppElement, <App />)
|
||||
} else {
|
||||
const root = createRoot(redwoodAppElement)
|
||||
root.render(<App />)
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/png" href="/favicon.png" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Please keep this div empty -->
|
||||
<div id="redwood-app"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -0,0 +1,57 @@
|
||||
// This page will be rendered when an error makes it all the way to the top of the
|
||||
// application without being handled by a Javascript catch statement or React error
|
||||
// boundary.
|
||||
//
|
||||
// You can modify this page as you wish, but it is important to keep things simple to
|
||||
// avoid the possibility that it will cause its own error. If it does, Redwood will
|
||||
// still render a generic error page, but your users will prefer something a bit more
|
||||
// thoughtful :)
|
||||
|
||||
// This import will be automatically removed when building for production
|
||||
import { DevFatalErrorPage } from '@redwoodjs/web/dist/components/DevFatalErrorPage'
|
||||
|
||||
export default DevFatalErrorPage ||
|
||||
(() => (
|
||||
<main>
|
||||
<style
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
html, body {
|
||||
margin: 0;
|
||||
}
|
||||
html * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
|
||||
text-align: center;
|
||||
background-color: #E2E8F0;
|
||||
height: 100vh;
|
||||
}
|
||||
section {
|
||||
background-color: white;
|
||||
border-radius: 0.25rem;
|
||||
width: 32rem;
|
||||
padding: 1rem;
|
||||
margin: 0 auto;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
line-height: 1;
|
||||
color: #2D3748;
|
||||
}
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
<section>
|
||||
<h1>
|
||||
<span>Something went wrong</span>
|
||||
</h1>
|
||||
</section>
|
||||
</main>
|
||||
))
|
@ -0,0 +1,13 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import HomePage from './HomePage'
|
||||
|
||||
const meta: Meta<typeof HomePage> = {
|
||||
component: HomePage,
|
||||
}
|
||||
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof HomePage>
|
||||
|
||||
export const Primary: Story = {}
|
@ -0,0 +1,14 @@
|
||||
import { render } from '@redwoodjs/testing/web'
|
||||
|
||||
import HomePage from './HomePage'
|
||||
|
||||
// Improve this test with help from the Redwood Testing Doc:
|
||||
// https://redwoodjs.com/docs/testing#testing-pages-layouts
|
||||
|
||||
describe('HomePage', () => {
|
||||
it('renders successfully', () => {
|
||||
expect(() => {
|
||||
render(<HomePage />)
|
||||
}).not.toThrow()
|
||||
})
|
||||
})
|
@ -0,0 +1,44 @@
|
||||
export default () => (
|
||||
<main>
|
||||
<style
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
html, body {
|
||||
margin: 0;
|
||||
}
|
||||
html * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
|
||||
text-align: center;
|
||||
background-color: #E2E8F0;
|
||||
height: 100vh;
|
||||
}
|
||||
section {
|
||||
background-color: white;
|
||||
border-radius: 0.25rem;
|
||||
width: 32rem;
|
||||
padding: 1rem;
|
||||
margin: 0 auto;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
line-height: 1;
|
||||
color: #2D3748;
|
||||
}
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
<section>
|
||||
<h1>
|
||||
<span>404 Page Not Found</span>
|
||||
</h1>
|
||||
</section>
|
||||
</main>
|
||||
)
|
@ -0,0 +1,39 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": "./",
|
||||
"skipLibCheck": false,
|
||||
"rootDirs": [
|
||||
"./src",
|
||||
"../.redwood/types/mirror/web/src",
|
||||
"../api/src",
|
||||
"../.redwood/types/mirror/api/src"
|
||||
],
|
||||
"paths": {
|
||||
"src/*": [
|
||||
"./src/*",
|
||||
"../.redwood/types/mirror/web/src/*",
|
||||
"../api/src/*",
|
||||
"../.redwood/types/mirror/api/src/*"
|
||||
],
|
||||
"$api/*": [ "../api/*" ],
|
||||
"types/*": ["./types/*", "../types/*"],
|
||||
"@redwoodjs/testing": ["../node_modules/@redwoodjs/testing/web"]
|
||||
},
|
||||
"typeRoots": ["../node_modules/@types", "./node_modules/@types"],
|
||||
"types": ["jest", "@testing-library/jest-dom"],
|
||||
"jsx": "preserve"
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
"../.redwood/types/includes/all-*",
|
||||
"../.redwood/types/includes/web-*",
|
||||
"../types",
|
||||
"./types"
|
||||
]
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
import dns from 'dns'
|
||||
|
||||
import { defineConfig, UserConfig } from 'vite'
|
||||
|
||||
// See: https://vitejs.dev/config/server-options.html#server-host
|
||||
// So that Vite will load on local instead of 127.0.0.1
|
||||
dns.setDefaultResultOrder('verbatim')
|
||||
|
||||
import redwood from '@redwoodjs/vite'
|
||||
|
||||
const viteConfig: UserConfig = {
|
||||
plugins: [redwood()],
|
||||
}
|
||||
|
||||
export default defineConfig(viteConfig)
|