Refactor node packages to yarn workspaces & ditch next.js for CRA. (#161)

* chore: restructure project into yarn workspaces, remove next

* fix tests, remove webapp from terraform

* remove more ui deployment bits

* remove pages, fix FUNDING.yml

* remove isomorphism

* remove next providers

* fix linting issues

* feat: start basis of new web ui system on CRA

* chore: move types to @roleypoly/types package

* chore: move src/common/utils to @roleypoly/misc-utils

* chore: remove roleypoly/ path remappers

* chore: renmove vercel config

* chore: re-add worker-types to api package

* chore: fix type linting scope for api

* fix(web): craco should include all of packages dir

* fix(ci): change api webpack path for wrangler

* chore: remove GAR actions from CI

* chore: update codeql job

* chore: test better github dar matcher in lint-staged
This commit is contained in:
41666 2021-03-12 18:04:49 -05:00 committed by GitHub
parent 49e308507e
commit 2ff6588030
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
328 changed files with 16624 additions and 3525 deletions

View file

@ -1,4 +1,3 @@
module.exports = {
presets: ['next/babel'],
plugins: [['styled-components', { ssr: true }]],
plugins: ['styled-components'],
};

2
.github/FUNDING.yml vendored
View file

@ -1,7 +1,7 @@
# These are supported funding model platforms
github: kayteh
patreon: kata
patreon: roleypoly
open_collective: # Replace with a single Open Collective username
ko_fi: roleypoly
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel

View file

@ -98,7 +98,7 @@ jobs:
- run: |
wrangler init
echo 'webpack_config = "src/backend-worker/webpack.config.js"' | tee -a wrangler.toml
echo 'webpack_config = "packages/api/webpack.config.js"' | tee -a wrangler.toml
wrangler build
if: steps.check.outputs.skip == '0'
@ -119,7 +119,6 @@ jobs:
strategy:
matrix:
dockerfile:
- ui
- bot
steps:
- uses: actions/checkout@master
@ -182,12 +181,6 @@ jobs:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Get UI digest
uses: actions/download-artifact@v2
with:
name: ui-digest
path: .digests/ui
- name: Get Bot digest
uses: actions/download-artifact@v2
with:
@ -197,7 +190,7 @@ jobs:
- name: Set digests as addressable
id: digests
env:
IMAGES: ui bot
IMAGES: bot
run: |
set_digest_output() {
echo ::set-output name=$1::@$(cat .digests/$1/digest.txt)

View file

@ -1,24 +1,25 @@
name: 'CodeQL'
name: 'Code Scanning - Action'
on:
push:
branches: [main]
pull_request:
# The branches below must be a subset of the branches above
branches: [main]
schedule:
- cron: '23 22 * * 4'
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
- cron: '30 1 * * 0'
jobs:
analyze:
name: Analyze
CodeQL-Build:
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: ['go', 'javascript']
steps:
- name: Checkout repository
uses: actions/checkout@v2
@ -26,24 +27,21 @@ jobs:
# 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
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# 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)
# 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
# ✏️ 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

View file

@ -7,10 +7,6 @@ on:
description: 'One of: stage, prod'
required: true
default: stage
ui_tag:
description: 'tag/digest reference to a UI container build'
required: false
default: ':main'
bot_tag:
description: 'tag/digest reference to a UI container build'
required: false
@ -21,115 +17,9 @@ on:
default: '' # Empty will try using current main branch hash
jobs:
docker_sync:
name: Docker Sync
runs-on: ubuntu-latest
outputs:
ui_tag: ${{ steps.tags.outputs.ui_tag }}
steps:
- uses: actions/checkout@master
- uses: docker/setup-buildx-action@v1
id: buildx
with:
install: true
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@master
with:
project_id: ${{ secrets.GCS_PROJECT_ID }}
service_account_key: ${{ secrets.GCS_TF_KEY }}
export_default_credentials: true
- name: Login to GHCR
uses: docker/login-action@v1
with:
registry: ghcr.io
username: roleypoly
password: ${{ secrets.GHCR_PAT }}
- name: Login to GAR US
uses: docker/login-action@v1
with:
registry: us-docker.pkg.dev
username: _json_key
password: ${{ secrets.GAR_JSON_KEY }}
- name: Login to GAR Europe
uses: docker/login-action@v1
with:
registry: europe-docker.pkg.dev
username: _json_key
password: ${{ secrets.GAR_JSON_KEY }}
- name: Login to GAR Asia
uses: docker/login-action@v1
with:
registry: asia-docker.pkg.dev
username: _json_key
password: ${{ secrets.GAR_JSON_KEY }}
- name: Retag
id: tags
run: |
retag_push() {
docker tag $1 $2
docker push $2
}
get_digest() {
# Finds the digest for any GAR-pushed artifact
docker inspect $1 --format='{{json .RepoDigests}}' | jq -r '[.[] | match("docker.pkg.*(sha256:.*)"; "g")] | .[0] | .captures | .[0] | .string'
}
UI_IMAGE_SRC=ghcr.io/roleypoly/ui${{github.event.inputs.ui_tag}}
UI_IMAGE_DEST_BASE=docker.pkg.dev/roleypoly/roleypoly/ui:${{github.event.inputs.environment}}
docker pull $UI_IMAGE_SRC
retag_push $UI_IMAGE_SRC us-$UI_IMAGE_DEST_BASE
retag_push $UI_IMAGE_SRC europe-$UI_IMAGE_DEST_BASE
retag_push $UI_IMAGE_SRC asia-$UI_IMAGE_DEST_BASE
echo ::set-output name=ui_tag::@$(get_digest $UI_IMAGE_SRC)
deploy_metadata:
name: Make Deployment Metadata
runs-on: ubuntu-latest
outputs:
url: ${{steps.metadata.outputs.url}}
env: ${{steps.metadata.outputs.env}}
steps:
- name: Create deployment metadata
id: metadata
run: |
ENV_URL=
ENV_NAME=
if [[ "${{github.event.inputs.environment}}" == "prod" ]]; then
ENV_URL="https://next.roleypoly.com"
ENV_NAME=Production
elif [[ "${{github.event.inputs.environment}}" == "stage" ]]; then
ENV_URL="https://stage.roleypoly.com"
ENV_NAME=Staging
else
ENV_URL="https://web-${{github.event.inputs.environment}}.roleypoly.com"
ENV_NAME=Preview-${{github.event.inputs.environment}}
fi
echo "url=$ENV_URL"
echo "env=$ENV_NAME"
echo ::set-output name=url::$ENV_URL
echo ::set-output name=env::$ENV_NAME
deploy_terraform:
name: Deploy Terraform
runs-on: ubuntu-latest
needs:
- docker_sync
- deploy_metadata
environment:
name: ${{ needs.deploy_metadata.outputs.env }}
url: ${{ needs.deploy_metadata.outputs.url }}
steps:
- uses: actions/checkout@master
@ -170,7 +60,7 @@ jobs:
working-directory: ./terraform
run: |
echo \
'{"ui_tag": "${{needs.docker_sync.outputs.ui_tag}}", "bot_tag": "${{github.event.inputs.bot_tag}}", "api_path_to_worker": "./worker-dist/backend-worker.js"}' \
'{"bot_tag": "${{github.event.inputs.bot_tag}}", "api_path_to_worker": "./worker-dist/backend-worker.js"}' \
| jq . \
| tee tags.auto.tfvars.json
@ -199,9 +89,8 @@ jobs:
DATA='{
"embeds": [
{
"title": "Roleypoly ${{ needs.deploy_metadata.outputs.env }} Deployment Success",
"description": "Roleypoly was successfully deployed to ${{ needs.deploy_metadata.outputs.env }} at '$(date)'",
"url": "${{ needs.deploy_metadata.outputs.url }}",
"title": "Roleypoly Deployment Success",
"description": "Roleypoly was successfully deployed at '$(date)'",
"color": 4634182,
"author": {
"name": "Deployment Notification",
@ -222,9 +111,8 @@ jobs:
DATA='{
"embeds": [
{
"title": "Roleypoly ${{ needs.deploy_metadata.outputs.env }} Deployment Failed",
"description": "Roleypoly failed to be deployed to ${{ needs.deploy_metadata.outputs.env }} at '$(date)'",
"url": "${{ needs.deploy_metadata.outputs.url }}",
"title": "Roleypoly Deployment Failed",
"description": "Roleypoly failed to be deployed at '$(date)'",
"color": 15291219,
"author": {
"name": "Deployment Notification",

View file

@ -1,45 +0,0 @@
name: GAR Cleanup
on:
schedule:
- cron: '30 6 * * *'
workflow_dispatch: {}
workflow_run:
workflows: ['Deploy']
types:
- completed
jobs:
docker_cleanup:
name: Cleanup Deployed Images
runs-on: ubuntu-latest
strategy:
matrix:
region: [us, europe, asia]
fail-fast: false
steps:
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@master
with:
project_id: ${{ secrets.GCS_PROJECT_ID }}
service_account_key: ${{ secrets.GCS_TF_KEY }}
export_default_credentials: true
- name: Delete stale artifacts
run: |
flags="--format=json --location=${{matrix.region}} --repository=roleypoly"
packagesToPrune=$(gcloud artifacts packages list $flags | jq -r '.[].name')
for package in $packagesToPrune; do
tagsToKeep=$(gcloud artifacts tags list --package=$package $flags | jq -r '.[].version')
versionsToCheck=$(gcloud artifacts versions list --package=$package $flags | jq -r '.[].name')
for version in $versionsToCheck; do
if [[ "$tagsToKeep" =~ .*"$version".* ]]; then
continue
fi
gcloud artifacts versions delete $version --package=$package $flags --quiet
done
done

1
.gitignore vendored
View file

@ -6,3 +6,4 @@ storybook-static
worker
wrangler.toml
.devdbs
dist

View file

@ -41,8 +41,8 @@ This is the fastest way to start. You must be using MacOS or Linux (WSL2 is ok!)
- Setup `.env` using [`.env.example`][envexample] as a template and guide.
- When setting up your Discord Application, be sure to set `http://localhost:6609/login-callback` as the OAuth2 callback URL.
- Run: `yarn install`
- Run both: `yarn ui` and `yarn worker`
- This starts the UI and API servers in hot-reload dev/emulation mode. All changes to TS/TSX files should be properly captured and reloaded for you!
- Run both: `yarn start`
- This starts the Web UI, Storybook, and API servers in hot-reload dev/emulation mode. All changes to TS/TSX files should be properly captured and reloaded for you!
- Develop you a Roleypoly!
#### Option 3 🐄🤠: Wrangler (No emulation)
@ -80,8 +80,8 @@ This is probably extremely painful and requires you to have a Cloudflare account
- Setup `.env` using [`.env.example`][envexample] as a template and guide.
- Run `yarn install`
- Run both `wrangler dev -e dev` and `yarn ui`
- This starts the UI and API servers in hot-reload dev mode. All changes to TS/TSX files should be properly captured and reloaded for you!
- Run both `wrangler dev -e dev` and `yarn start:web`
- This starts the Web UI and API servers in hot-reload dev mode. All changes to TS/TSX files should be properly captured and reloaded for you!
- Develop you a Roleypoly
- And get a beer or heated plant because oh no.
@ -92,7 +92,7 @@ For working with the [Roleypoly Design System](https://ui.roleypoly.com), use th
Run:
- `yarn` to install deps
- `yarn storybook` to open storybook
- `yarn start:design-system` to open storybook
- `yarn test` to test
### Developing Web UI
@ -102,7 +102,7 @@ For working with the Next.js frontend components, use the below steps as referen
Run:
- `yarn` to install deps
- `yarn ui` to run Next.js dev server
- `yarn start:web` to run Next.js dev server
- `yarn test` to test
### Developing API Components
@ -112,7 +112,7 @@ For working with the API, use the below steps as reference. Code lives in `src/b
Run:
- `yarn` to install deps
- `yarn worker` to start an emulated worker
- `yarn start:api` to start an emulated worker
- `yarn test` to test
[envexample]: .env.example

View file

@ -2,20 +2,13 @@
version: '3.8'
services:
worker:
dev:
image: node:14
volumes:
- '.:/src'
ports:
- 6609:6609
working_dir: /src
command: yarn worker
ui:
image: node:14
volumes:
- '.:/src'
ports:
- 6601:6601
- 6006:6006
working_dir: /src
command: yarn ui
command: yarn start

View file

@ -1,24 +0,0 @@
#
# Builder
#
FROM mhart/alpine-node:14 AS builder
WORKDIR /src
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile --ignore-scripts
COPY tsconfig.json .babelrc.js next.config.js next-env.d.ts ./
COPY src src
RUN yarn ui:build
RUN yarn install --frozen-lockfile --prod --ignore-scripts
#
# Output layer
#
FROM mhart/alpine-node:slim-14 AS output
COPY --from=builder /src .
ENV PORT=6601
ENTRYPOINT [ "/bin/sh", "-c", "/usr/bin/node node_modules/.bin/next start -p $PORT" ]

View file

@ -1,14 +1,8 @@
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig.json');
module.exports = {
preset: 'ts-jest/presets/js-with-babel',
testEnvironment: 'enzyme',
reporters: ['default'],
setupFilesAfterEnv: ['jest-enzyme', 'jest-styled-components', './hack/jestSetup.ts'],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
prefix: '<rootDir>/',
}),
snapshotSerializers: ['enzyme-to-json/serializer'],
globals: {
'ts-jest': {

2
next-env.d.ts vendored
View file

@ -1,2 +0,0 @@
/// <reference types="next" />
/// <reference types="next/types/global" />

View file

@ -1,7 +0,0 @@
module.exports = {
// target: 'serverless',
publicRuntimeConfig: {
apiPublicURI: process.env.API_PUBLIC_URI,
uiPublicURI: process.env.UI_PUBLIC_URI,
},
};

View file

@ -12,7 +12,14 @@
},
"author": "Katalina Okano <git@kat.cafe>",
"license": "MIT",
"private": true,
"workspaces": [
"packages/*"
],
"scripts": {
"build": "run-p -c build:*",
"build:design-system": "yarn workspace @roleypoly/design-system run build",
"build:web": "yarn workspace @roleypoly/web run build",
"lint": "run-p -c lint:* --",
"lint:eslint": "eslint",
"lint:go": "go fmt ./...",
@ -20,111 +27,50 @@
"lint:stylelint": "cross-env stylelint '**/*.{ts,tsx}'",
"lint:terraform": "terraform fmt -recursive -check ./terraform",
"lint:types": "tsc --noEmit",
"now-build": "run-s storybook:build",
"lint:types-api": "yarn workspace @roleypoly/api run lint:types",
"postinstall": "is-ci || husky install",
"storybook": "start-storybook -p 6006",
"storybook:build": "build-storybook",
"test": "jest",
"ui": "next dev -p 6601",
"ui:build": "next build",
"ui:prod": "cross-env next start -p ${PORT:-3000}",
"worker": "node src/backend-emulator/main.js"
},
"dependencies": {
"chroma-js": "^2.1.0",
"isomorphic-unfetch": "^3.1.0",
"ksuid": "^2.0.0",
"lodash": "^4.17.20",
"next": "^10.0.5",
"nookies": "^2.5.0",
"react": "^17.0.1",
"react-custom-scrollbars": "^4.2.1",
"react-dom": "^17.0.1",
"react-icons": "^4.1.0",
"react-is": "^17.0.1",
"react-tooltip": "^4.2.15",
"styled-components": "^5.2.1",
"styled-normalize": "^8.0.7",
"swr": "^0.4.0"
"start": "run-p -c start:*",
"start:design-system": "yarn workspace @roleypoly/design-system start",
"start:web": "yarn workspace @roleypoly/web start",
"start:worker": "yarn workspace @roleypoly/api start",
"test": "jest"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@cloudflare/workers-types": "^2.1.0",
"@icons/material": "^0.4.1",
"@peculiar/webcrypto": "^1.1.4",
"@storybook/addon-actions": "^6.1.14",
"@storybook/addon-essentials": "^6.1.14",
"@storybook/addon-links": "^6.1.14",
"@storybook/addons": "^6.1.14",
"@storybook/react": "^6.1.14",
"@storybook/theming": "^6.1.14",
"@types/chroma-js": "^2.1.3",
"@types/enzyme": "^3.10.8",
"@types/enzyme-adapter-react-16": "^1.0.6",
"@types/express": "^4.17.11",
"@types/jest": "^26.0.20",
"@types/lodash": "^4.14.167",
"@types/minimist": "^1.2.1",
"@types/node": "^14.14.31",
"@types/react": "^17.0.0",
"@types/react-custom-scrollbars": "^4.0.7",
"@types/react-dom": "^17.0.0",
"@types/styled-components": "^5.1.7",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^4.13.0",
"@typescript-eslint/eslint-plugin-tslint": "^4.13.0",
"@typescript-eslint/parser": "^4.13.0",
"@types/lodash": "^4.14.168",
"@wojtekmaj/enzyme-adapter-react-17": "^0.4.1",
"babel-jest": "^26.6.3",
"babel-loader": "^8.2.2",
"babel-plugin-styled-components": "^1.12.0",
"chokidar": "^3.5.1",
"dotenv": "^8.2.0",
"enzyme": "^3.11.0",
"enzyme-to-json": "^3.6.1",
"eslint": "^7.20.0",
"eslint-config-prettier": "^7.1.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsdoc": "^32.2.0",
"eslint-plugin-react": "^7.22.0",
"husky": "^5.0.6",
"is-ci": "^2.0.0",
"jest": "^26.6.3",
"jest-cli": "^26.6.3",
"jest-environment-enzyme": "^7.1.2",
"enzyme-adapter-react-16": "^1.15.6",
"husky": "^5.1.3",
"is-ci": "^3.0.0",
"jest-enzyme": "^7.1.2",
"jest-react-hooks-shallow": "^1.4.2",
"jest-react-hooks-shallow": "^1.5.1",
"jest-styled-components": "^7.0.3",
"level": "^6.0.1",
"lint-staged": "^10.5.3",
"minimist": "^1.2.5",
"node-fetch": "^2.6.1",
"lint-staged": "^10.5.4",
"npm-run-all": "^4.1.5",
"prettier": "^2.2.1",
"prettier-plugin-organize-imports": "^1.1.1",
"prettier-plugin-pkg": "^0.8.0",
"prettier-plugin-sh": "^0.6.0",
"stylelint": "^13.8.0",
"stylelint": "^13.12.0",
"stylelint-config-prettier": "^8.0.2",
"stylelint-config-standard": "^20.0.0",
"stylelint-config-standard": "^21.0.0",
"stylelint-config-styled-components": "^0.1.1",
"stylelint-prettier": "^1.1.2",
"ts-jest": "^26.4.4",
"ts-loader": "^8.0.14",
"tsconfig-paths-webpack-plugin": "^3.3.0",
"tslint": "^6.1.3",
"typescript": "^4.1.3",
"webpack": "^4.46.0"
"stylelint-prettier": "^1.2.0",
"ts-jest": "^26.5.3",
"typescript": "^4.2.3"
},
"lint-staged": {
"*.{ts,tsx,js,jsx}": [
"stylelint --fix",
"prettier --write"
],
"*.go": [
"go fmt"
],
"*.{json,Dockerfile,sh,md,gitignore,env,mdx,yml,html}": [
"*.{json,Dockerfile,sh,md,env,mdx,yml,html}": [
"prettier --write"
],
".*/*.{json,Dockerfile,sh,md,env,mdx,yml,html}": [
"prettier --write"
],
".husky/pre-commit": [

View file

@ -1,5 +1,5 @@
import { CategoryType, Features, GuildData as GuildDataT } from '@roleypoly/types';
import KSUID from 'ksuid';
import { CategoryType, Features, GuildData as GuildDataT } from 'roleypoly/common/types';
import { onlyRootUsers, respond } from '../utils/api-tools';
import { GuildData } from '../utils/kv';

View file

@ -1,9 +1,4 @@
import {
DiscordUser,
GuildSlug,
PresentableGuild,
SessionData,
} from 'roleypoly/common/types';
import { DiscordUser, GuildSlug, PresentableGuild, SessionData } from '@roleypoly/types';
import { respond, withSession } from '../utils/api-tools';
import { getGuild, getGuildData, getGuildMemberRoles } from '../utils/guild';

View file

@ -1,4 +1,4 @@
import { SessionData } from 'roleypoly/common/types';
import { SessionData } from '@roleypoly/types';
import { respond, withSession } from '../utils/api-tools';
export const GetSession = withSession((session?: SessionData) => (): Response => {

View file

@ -1,4 +1,4 @@
import { GuildSlug } from 'roleypoly/common/types';
import { GuildSlug } from '@roleypoly/types';
import { respond } from '../utils/api-tools';
import { getGuild } from '../utils/guild';

View file

@ -1,10 +1,5 @@
import { AuthTokenResponse, DiscordUser, GuildSlug, SessionData } from '@roleypoly/types';
import KSUID from 'ksuid';
import {
AuthTokenResponse,
DiscordUser,
GuildSlug,
SessionData,
} from '../../common/types';
import {
AuthType,
discordFetch,

View file

@ -1,4 +1,4 @@
import { SessionData } from 'roleypoly/common/types';
import { SessionData } from '@roleypoly/types';
import { formData, respond, userAgent, withSession } from '../utils/api-tools';
import { botClientID, botClientSecret } from '../utils/config';
import { Sessions } from '../utils/kv';

View file

@ -1,4 +1,3 @@
import { difference, groupBy, keyBy, union } from 'lodash';
import {
GuildData,
Member,
@ -8,7 +7,8 @@ import {
RoleUpdate,
SessionData,
TransactionType,
} from 'roleypoly/common/types';
} from '@roleypoly/types';
import { difference, groupBy, keyBy, union } from 'lodash';
import { AuthType, discordFetch, respond, withSession } from '../utils/api-tools';
import { botToken } from '../utils/config';
import {

19
packages/api/package.json Normal file
View file

@ -0,0 +1,19 @@
{
"name": "@roleypoly/api",
"version": "0.1.0",
"scripts": {
"build": "yarn workspace @roleypoly/worker-emulator build --basePath `pwd`",
"lint:types": "tsc --noEmit",
"start": "yarn workspace @roleypoly/worker-emulator start --basePath `pwd`"
},
"devDependencies": {
"@cloudflare/workers-types": "^2.1.0",
"@roleypoly/misc-utils": "*",
"@roleypoly/types": "*",
"@roleypoly/worker-emulator": "*",
"ksuid": "^2.0.0",
"lodash": "^4.17.21",
"ts-loader": "^8.0.18",
"tsconfig-paths-webpack-plugin": "^3.3.0"
}
}

View file

@ -1,8 +1,8 @@
import { SessionData, UserGuildPermissions } from '../../common/types';
import {
evaluatePermission,
permissions as Permissions,
} from '../../common/utils/hasPermission';
} from '@roleypoly/misc-utils/hasPermission';
import { SessionData, UserGuildPermissions } from '@roleypoly/types';
import { Handler } from '../router';
import { rootUsers, uiPublicURI } from './config';
import { Sessions, WrappedKVNamespace } from './kv';

View file

@ -1,3 +1,4 @@
import { evaluatePermission, permissions } from '@roleypoly/misc-utils/hasPermission';
import {
Features,
Guild,
@ -5,8 +6,7 @@ import {
OwnRoleInfo,
Role,
RoleSafety,
} from 'roleypoly/common/types';
import { evaluatePermission, permissions } from 'roleypoly/common/utils/hasPermission';
} from '@roleypoly/types';
import { AuthType, cacheLayer, discordFetch } from './api-tools';
import { botClientID, botToken } from './config';
import { GuildData, Guilds } from './kv';

View file

@ -1,5 +1,4 @@
const path = require('path');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const mode = process.env.NODE_ENV || 'production';
@ -13,11 +12,6 @@ module.exports = {
mode,
resolve: {
extensions: ['.ts', '.tsx', '.js'],
plugins: [
new TsconfigPathsPlugin({
configFile: path.resolve(__dirname, './tsconfig.json'),
}),
],
},
module: {
rules: [

View file

@ -1,22 +1,29 @@
require('dotenv').config();
const path = require('path');
require('dotenv').config({ path: path.resolve(__dirname, '../../.env') });
const vm = require('vm');
const http = require('http');
const fs = require('fs');
const path = require('path');
const chokidar = require('chokidar');
const webpack = require('webpack');
const { Crypto } = require('@peculiar/webcrypto');
const roleypolyConfig = require('../backend-worker/roleypoly.config');
const { KVShim } = require('./kv');
const crypto = new Crypto();
const fetch = require('node-fetch');
const args = require('minimist')(process.argv.slice(2));
const basePath = args.basePath;
if (!basePath) {
throw new Error('--basePath is not set.');
}
const workerConfig = require(`${basePath}/worker.config.js`);
const getKVs = (namespaces = []) =>
namespaces.reduce((acc, ns) => ({ ...acc, [ns]: new KVShim(ns) }), {});
const workerShims = {
...roleypolyConfig.environment,
...getKVs(roleypolyConfig.kv),
...workerConfig.environment,
...getKVs(workerConfig.kv),
};
let listeners = [];
@ -133,7 +140,7 @@ const reload = () => {
// Fork and re-run
fork(async () =>
vm.runInContext(
fs.readFileSync(path.resolve(__dirname, '../backend-worker/dist/worker.js')),
fs.readFileSync(path.resolve(__dirname, `${basePath}/dist/worker.js`)),
context(),
{
displayErrors: true,
@ -145,7 +152,7 @@ const reload = () => {
const rebuild = () =>
new Promise((resolve, reject) => {
const webpackConfig = require('../backend-worker/webpack.config.js');
const webpackConfig = require(`${basePath}/webpack.config.js`);
webpackConfig.output.filename = 'worker.js';
webpack(webpackConfig).run((err, stats) => {
if (err) {
@ -163,7 +170,7 @@ const rebuild = () =>
});
});
const watcher = chokidar.watch(path.resolve(__dirname, '../backend-worker'), {
const watcher = chokidar.watch(path.resolve(__dirname, basePath), {
ignoreInitial: true,
ignore: '**/dist',
});

View file

@ -0,0 +1,17 @@
{
"name": "@roleypoly/worker-emulator",
"version": "0.1.0",
"scripts": {
"build": "node main.js --build",
"start": "node main.js"
},
"devDependencies": {
"@peculiar/webcrypto": "^1.1.6",
"chokidar": "^3.5.1",
"dotenv": "^8.2.0",
"level": "^6.0.1",
"minimist": "^1.2.5",
"node-fetch": "^2.6.1",
"webpack": "^4.x"
}
}

View file

@ -0,0 +1,8 @@
const path = require('path');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const { NormalModuleReplacementPlugin } = require('webpack');
module.exports = {
stories: ['../**/*.stories.mdx', '../**/*.stories.@(js|jsx|ts|tsx)'],
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
};

View file

@ -0,0 +1,6 @@
import { addons } from '@storybook/addons';
import { roleypolyTheme } from './theme';
addons.setConfig({
theme: roleypolyTheme,
});

View file

@ -0,0 +1,8 @@
import * as React from 'react';
type Props = {
children: React.ReactNode;
};
const Link = (props: Props) => <>{props.children}</>;
export default Link;

View file

@ -0,0 +1,39 @@
<script>
(function (d) {
var config = {
kitId: 'bck0pci',
scriptTimeout: 3000,
async: true,
},
h = d.documentElement,
t = setTimeout(function () {
h.className = h.className.replace(/\bwf-loading\b/g, '') + ' wf-inactive';
}, config.scriptTimeout),
tk = d.createElement('script'),
f = false,
s = d.getElementsByTagName('script')[0],
a;
h.className += ' wf-loading';
tk.src = 'https://use.typekit.net/' + config.kitId + '.js';
tk.async = true;
tk.onload = tk.onreadystatechange = function () {
a = this.readyState;
if (f || (a && a != 'complete' && a != 'loaded')) return;
f = true;
clearTimeout(t);
try {
Typekit.load(config);
} catch (e) {}
};
s.parentNode.insertBefore(tk, s);
})(document);
</script>
<style>
body {
font-family: 'source-han-sans-japanese', 'Source Sans Pro', sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol' !important;
color: #f2efef;
background-color: #453e3d;
margin: 0;
}
</style>

View file

@ -0,0 +1,10 @@
import { roleypolyTheme } from './theme';
import { mdxComponents } from '../atoms/typography/mdx';
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
docs: {
theme: roleypolyTheme,
components: mdxComponents,
},
};

View file

@ -0,0 +1,34 @@
import { create } from '@storybook/theming';
import { palette } from '../atoms/colors';
export const roleypolyTheme = create({
base: 'dark',
colorPrimary: palette.green400,
colorSecondary: palette.taupe200,
// UI
appBg: palette.taupe300,
appContentBg: palette.taupe200,
appBorderColor: palette.taupe100,
appBorderRadius: 0,
// Typography
fontBase: 'system-ui, sans-serif',
fontCode: 'monospace',
// Text colors
textColor: palette.grey600,
textInverseColor: palette.grey100,
// Toolbar default and active colors
barTextColor: palette.taupe500,
barSelectedColor: palette.taupe600,
barBg: palette.taupe100,
// Form colors
inputBg: 'rgba(0,0,0,0.24)',
inputBorder: palette.taupe100,
inputTextColor: palette.grey600,
inputBorderRadius: 0,
});

View file

@ -1,7 +1,7 @@
import { Meta } from '@storybook/addon-docs/blocks';
import { Logotype } from 'roleypoly/design-system/atoms/branding';
import { Space } from 'roleypoly/design-system/atoms/space';
import { palette } from 'roleypoly/design-system/atoms/colors';
import { Logotype } from '@roleypoly/design-system/atoms/branding';
import { Space } from '@roleypoly/design-system/atoms/space';
import { palette } from '@roleypoly/design-system/atoms/colors';
<Meta title="Roleypoly Design System" />

View file

@ -1,4 +1,4 @@
import { palette } from 'roleypoly/design-system/atoms/colors';
import { palette } from '@roleypoly/design-system/atoms/colors';
import styled, { css } from 'styled-components';
import { AvatarProps } from './Avatar';

View file

@ -1,5 +1,5 @@
import { palette } from '@roleypoly/design-system/atoms/colors';
import * as React from 'react';
import { palette } from 'roleypoly/design-system/atoms/colors';
export type LogoProps = {
fill: string;

View file

@ -1,6 +1,6 @@
import { Text } from '@roleypoly/design-system/atoms/typography';
import * as React from 'react';
import ReactTooltip from 'react-tooltip';
import { Text } from 'roleypoly/design-system/atoms/typography';
import styled from 'styled-components';
import { palette } from '../colors';
import { Logomark, Logotype } from './Branding';

View file

@ -1,5 +1,5 @@
import { withContext } from '@roleypoly/misc-utils/withContext';
import * as React from 'react';
import { withContext } from 'roleypoly/common/utils/withContext';
export type ScreenSize = {
onSmallScreen: boolean;

View file

@ -1,6 +1,6 @@
import { palette } from 'roleypoly/design-system/atoms/colors';
import { fontCSS } from 'roleypoly/design-system/atoms/fonts';
import { text300, text400 } from 'roleypoly/design-system/atoms/typography';
import { palette } from '@roleypoly/design-system/atoms/colors';
import { fontCSS } from '@roleypoly/design-system/atoms/fonts';
import { text300, text400 } from '@roleypoly/design-system/atoms/typography';
import styled, { css } from 'styled-components';
export const IconContainer = styled.div`

View file

@ -1,4 +1,4 @@
import { SmallTitle } from 'roleypoly/design-system/atoms/typography';
import { SmallTitle } from '@roleypoly/design-system/atoms/typography';
import { Collapse } from './Collapse';
export default {

View file

@ -1,6 +1,6 @@
import { AmbientSmall } from '@roleypoly/design-system/atoms/typography';
import chroma from 'chroma-js';
import * as React from 'react';
import { AmbientSmall } from 'roleypoly/design-system/atoms/typography';
import styled from 'styled-components';
import { palette } from './colors';

View file

@ -1,6 +1,6 @@
import { Button } from '@roleypoly/design-system/atoms/button';
import { action } from '@storybook/addon-actions';
import * as React from 'react';
import { Button } from 'roleypoly/design-system/atoms/button';
import { FaderOpacity, FaderSlide } from './Fader';
export default {

View file

@ -1,5 +1,5 @@
import { FeatureFlagDecorator } from '@roleypoly/misc-utils/featureFlags/react/storyDecorator';
import * as React from 'react';
import { FeatureFlagDecorator } from 'roleypoly/common/utils/featureFlags/react/storyDecorator';
import { FeatureGate } from './FeatureGate';
export default {

View file

@ -1,8 +1,8 @@
import * as React from 'react';
import {
FeatureFlag,
FeatureFlagsContext,
} from 'roleypoly/common/utils/featureFlags/react';
} from '@roleypoly/misc-utils/featureFlags/react';
import * as React from 'react';
export type FeatureGateProps = {
featureFlag: FeatureFlag;

View file

@ -1,5 +1,8 @@
import {
MediumTitle,
Text as TextBlock,
} from '@roleypoly/design-system/atoms/typography';
import * as React from 'react';
import { MediumTitle, Text as TextBlock } from 'roleypoly/design-system/atoms/typography';
import styled from 'styled-components';
import { UseFontStyled } from './fonts';

View file

@ -0,0 +1,10 @@
import styled, { css } from 'styled-components';
export const fontCSS = css`
font-family: 'source-han-sans-japanese', 'Source Sans Pro', sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol' !important;
`;
export const UseFontStyled = styled.div`
${fontCSS}
`;

View file

@ -1,4 +1,4 @@
import { onTablet } from 'roleypoly/design-system/atoms/breakpoints';
import { onTablet } from '@roleypoly/design-system/atoms/breakpoints';
import styled, { css } from 'styled-components';
export const HalfsiesContainer = styled.div`

View file

@ -1,5 +1,5 @@
import { palette } from 'roleypoly/design-system/atoms/colors';
import { transitions } from 'roleypoly/design-system/atoms/timings';
import { palette } from '@roleypoly/design-system/atoms/colors';
import { transitions } from '@roleypoly/design-system/atoms/timings';
import styled, { css } from 'styled-components';
export const Item = styled.div<{ selected: boolean }>`

Some files were not shown because too many files have changed in this diff Show more