Skip to content

Commit

Permalink
Merge pull request #41 from eliataylor/eli
Browse files Browse the repository at this point in the history
major upgrade of TypeScript definitions
  • Loading branch information
eliataylor authored Feb 14, 2025
2 parents 9fe8e25 + 382501c commit c838bcb
Show file tree
Hide file tree
Showing 72 changed files with 2,374 additions and 2,260 deletions.
18 changes: 9 additions & 9 deletions .env.public
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ TYPES_PATH=src/examples/object-fields-demo.csv
# Your Worksheet's "Permissions Matrix" sheet (optional)
PERMISSIONS_PATH=src/examples/permissions-matrix-demo.csv

# 'AllowAll', 'IsAuthenticated', 'IsAuthenticatedOrReadOnly'
# 'AllowAny', 'IsAuthenticated', 'IsAuthenticatedOrReadOnly'
DEFAULT_PERMS=IsAuthenticatedOrReadOnly

#### Your API Server protocol:host:port ####
REACT_APP_API_HOST=https://localapi.oaexample.com:8080
# REACT_APP_API_HOST=http://localhost:8080
# REACT_APP_API_HOST=https://localapi.oaexample.com:8080
REACT_APP_API_HOST=http://localhost:8080
# REACT_APP_API_HOST=https://api.oaexample.com

#### Your Webapp URL protocol:host:port ####
REACT_APP_APP_HOST=https://localhost.oaexample.com:3000
# REACT_APP_APP_HOST=http://localhost:3000
# REACT_APP_APP_HOST=https://localhost.oaexample.com:3000
REACT_APP_APP_HOST=http://localhost:3000
# REACT_APP_APP_HOST=https://oaexample.com

# Your API admin login
Expand All @@ -30,10 +30,10 @@ [email protected]
REACT_APP_LOGIN_PASS=APasswordYouShouldChange

# the location of mysql server: docker | local | gcp
OA_ENV_DB=gcp
OA_ENV_DB=docker

# how are emails sent: django | gmail | sendgrid
OA_ENV_EMAIL=gmail
# how are emails sent: console | files | gmail | sendgrid
OA_ENV_EMAIL=console

# where to store static files: gcp | local
OA_ENV_STORAGE=gcp
OA_ENV_STORAGE=local
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Offer Sign-in / Sign-up from any of these [AllAuth Providers](https://docs.allau


# TO RUN:
Follow [oaexample.com/oa/install](https://oaexample.com/oa/install)
Follow [oaexample.com/oa/install](https://oaexample.com/oa/install)

# TO CUSTOMIZE:
Follow [oaexample.com/oa/customize](https://oaexample.com/oa/customize)
Expand All @@ -34,6 +34,5 @@ Follow [oaexample.com/oa/extend](https://oaexample.com/oa/extend)
# TO CONTRIBUTE:
Follow [oaexample.com/oa/contribute](https://oaexample.com/oa/contribute)

# TO SPONSOR:

# TO SPONSOR:
Donate [github.com/sponsors/eliataylor](https://github.com/sponsors/eliataylor)
4 changes: 2 additions & 2 deletions docker-compose.yml
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ services:
mysqlv8:
condition: service_healthy
ports:
- "8080:8080"
- "8081:8081"
extra_hosts:
- "localapi.oaexample.com:127.0.0.1"

Expand All @@ -52,7 +52,7 @@ services:
django:
condition: service_started
ports:
- "3000:3000"
- "3001:3001"
extra_hosts:
- "localhost.oaexample.com:127.0.0.1"

Expand Down
8 changes: 5 additions & 3 deletions docs/os-hosts-install.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#!/bin/bash

source "$(pwd)/docs/common.sh"

# parse from .env
API_HOST=$(echo "$REACT_APP_API_HOST" | sed -E 's|^https?://([^:/]+).*|\1|')
APP_HOST=$(echo "$REACT_APP_APP_HOST" | sed -E 's|^https?://([^:/]+).*|\1|')

desired_entries=(
"127.0.0.1 localhost.oaexample.com"
"127.0.0.1 localapi.oaexample.com"
"127.0.0.1 $APP_HOST"
"127.0.0.1 $API_HOST"
)

# Check and inject entries
Expand Down
5 changes: 3 additions & 2 deletions load-sheets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ source "$(pwd)/docs/common.sh"

cd "$SCRIPT_DIR/src"


if [ ! -d .venv ]; then
python -m venv .venv
echo "First run. Creating new virtual environment."
Expand All @@ -28,9 +29,9 @@ fi
# Check if permissions path is a valid file path
permissions_arg=""
if [[ -f "$PERMISSIONS_PATH" ]]; then
permissions_arg="--permissions=$PERMISSIONS_PATH"
permissions_arg="--permissions=$PERMISSIONS_PATH --default_perm=$DEFAULT_PERMS"
else
permissions_arg="--default_perm=IsAuthenticatedOrReadOnly"
permissions_arg="--default_perm=$DEFAULT_PERMS"
fi


Expand Down
209 changes: 209 additions & 0 deletions set-env-vars.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
#!/bin/sh

set -e

# Define root .env file and public templates
ROOT_ENV_FILE=".env"
PUBLIC_ENV_FILE=".env.public"
PUBLIC_JSON_FILE="stack/cypress/cypress.public.json"

# Ensure root .env file exists
if [ ! -f "$ROOT_ENV_FILE" ]; then
cp "$PUBLIC_ENV_FILE" "$ROOT_ENV_FILE"
echo "Created $ROOT_ENV_FILE from $PUBLIC_ENV_FILE"
fi

# Load root .env variables into memory
load_env() {
while IFS='=' read -r KEY VALUE || [ -n "$KEY" ]; do
case "$KEY" in
""|\#*) continue ;; # Ignore empty lines and comments
esac
eval "ROOT_$KEY=\"$VALUE\""
done < "$ROOT_ENV_FILE"
}

# Mapping of target files and variables to update
MAPPING="
stack/django/.env:DJANGO_SUPERUSER_PASSWORD:REACT_APP_LOGIN_PASS
stack/django/.env:DJANGO_SUPERUSER_EMAIL:REACT_APP_LOGIN_EMAIL
stack/django/.env:REACT_APP_APP_HOST:REACT_APP_APP_HOST
stack/django/.env:REACT_APP_API_HOST:REACT_APP_API_HOST
stack/django/.env:OA_ENV_STORAGE:OA_ENV_STORAGE
stack/django/.env:OA_ENV_EMAIL:OA_ENV_EMAIL
stack/django/.env:OA_ENV_DB:OA_ENV_DB
stack/databuilder/.env:REACT_APP_API_HOST:REACT_APP_API_HOST
stack/databuilder/.env:REACT_APP_APP_HOST:REACT_APP_APP_HOST
stack/databuilder/.env:REACT_APP_LOGIN_EMAIL:REACT_APP_LOGIN_EMAIL
stack/databuilder/.env:REACT_APP_LOGIN_PASS:REACT_APP_LOGIN_PASS
stack/reactjs/.env:REACT_APP_API_HOST:REACT_APP_API_HOST
stack/reactjs/.env:REACT_APP_APP_HOST:REACT_APP_APP_HOST
stack/reactjs/.env:REACT_APP_TITLE:PROJECT_NAME
stack/reactjs/.env:REACT_APP_LOGIN_EMAIL:REACT_APP_LOGIN_EMAIL
stack/reactjs/.env:REACT_APP_LOGIN_PASS:REACT_APP_LOGIN_PASS
stack/reactjs/.env:DEFAULT_PERMS:DEFAULT_PERMS
stack/cypress/cypress.env.json:email:REACT_APP_LOGIN_EMAIL
stack/cypress/cypress.env.json:password:REACT_APP_LOGIN_PASS
stack/cypress/cypress.env.json:REACT_APP_APP_HOST:REACT_APP_APP_HOST
stack/cypress/cypress.env.json:REACT_APP_API_HOST:REACT_APP_API_HOST
"

# Ensure missing .env files are created from .env.public
ensure_env_file() {
FILE="$1"
if [ ! -f "$FILE" ]; then
cp "$PUBLIC_ENV_FILE" "$FILE"
echo "Created $FILE from $PUBLIC_ENV_FILE"
fi
}

# Ensure missing .json files are created from cypress.public.json
ensure_json_file() {
FILE="$1"
if [ ! -f "$FILE" ]; then
cp "$PUBLIC_JSON_FILE" "$FILE"
echo "Created $FILE from $PUBLIC_JSON_FILE"
fi
}

# Function to update .env files
update_env_file() {
FILE="$1"
VAR="$2"
ROOT_KEY="$3"
ROOT_VALUE=$(eval "echo \${ROOT_$ROOT_KEY}")

[ -z "$ROOT_VALUE" ] && return # Skip if root value is empty

TMP_FILE=$(mktemp)
UPDATED=0

while IFS= read -r LINE || [ -n "$LINE" ]; do
case "$LINE" in
\#*|"") echo "$LINE" >> "$TMP_FILE" ;; # Preserve comments and blank lines
"$VAR="*) echo "$VAR=$ROOT_VALUE" >> "$TMP_FILE"; UPDATED=1 ;;
*) echo "$LINE" >> "$TMP_FILE" ;;
esac
done < "$FILE"

if [ "$UPDATED" -eq 0 ]; then
echo "$VAR=$ROOT_VALUE" >> "$TMP_FILE"
fi

mv "$TMP_FILE" "$FILE"
echo "Updated $VAR in $FILE"
}

# Function to update JSON files manually
update_json_file() {
FILE="$1"
VAR="$2"
ROOT_KEY="$3"
ROOT_VALUE=$(eval "echo \${ROOT_$ROOT_KEY}")

[ -z "$ROOT_VALUE" ] && return # Skip if root value is empty

TMP_FILE=$(mktemp)
UPDATED=0

while IFS= read -r LINE || [ -n "$LINE" ]; do
KEY=$(echo "$LINE" | awk -F: '{print $1}' | tr -d ' ",')

if [ "$KEY" = "$VAR" ]; then
echo " \"$VAR\": \"$ROOT_VALUE\"," >> "$TMP_FILE"
UPDATED=1
else
echo "$LINE" >> "$TMP_FILE"
fi
done < "$FILE"

if [ "$UPDATED" -eq 0 ]; then
echo " \"$VAR\": \"$ROOT_VALUE\"," >> "$TMP_FILE"
fi

mv "$TMP_FILE" "$FILE"
echo "Updated $VAR in $FILE"
}

# Load root .env variables
load_env

# Iterate over mapping and update files
echo "$MAPPING" | while IFS=: read -r FILE VAR ROOT_KEY; do
case "$FILE" in
*.json)
ensure_json_file "$FILE"
update_json_file "$FILE" "$VAR" "$ROOT_KEY"
;;
*.env)
ensure_env_file "$FILE"
update_env_file "$FILE" "$VAR" "$ROOT_KEY"
;;
esac
done

# Function to update ports in docker-compose.yml based on REACT_APP_API_HOST and REACT_APP_APP_HOST
update_docker_compose_ports() {
[ ! -f "$DOCKER_COMPOSE_FILE" ] && return

# Extract host and port from REACT_APP_API_HOST (for Django)
API_HOST=$(echo "$ROOT_REACT_APP_API_HOST" | awk -F[/:] '{print $4}')
API_PORT=$(echo "$ROOT_REACT_APP_API_HOST" | awk -F[/:] '{print $5}')
[ -z "$API_PORT" ] && API_PORT="80" # Default port if not specified

# Extract host and port from REACT_APP_APP_HOST (for ReactJS)
APP_HOST=$(echo "$ROOT_REACT_APP_APP_HOST" | awk -F[/:] '{print $4}')
APP_PORT=$(echo "$ROOT_REACT_APP_APP_HOST" | awk -F[/:] '{print $5}')
[ -z "$APP_PORT" ] && APP_PORT="80" # Default port if not specified

TMP_FILE=$(mktemp)
while IFS= read -r LINE || [ -n "$LINE" ]; do
case "$LINE" in
*"django:"*)
IN_DJANGO=1
echo "$LINE" >> "$TMP_FILE"
;;
*"reactjs:"*)
IN_DJANGO=0
IN_REACTJS=1
echo "$LINE" >> "$TMP_FILE"
;;
" ports:"*)
echo "$LINE" >> "$TMP_FILE"
;;
*"- \"8080:8080\""*)
if [ "$IN_DJANGO" -eq 1 ]; then
echo " - \"$API_PORT:$API_PORT\"" >> "$TMP_FILE"
echo "Updated Django container to use port $API_PORT"
else
echo "$LINE" >> "$TMP_FILE"
fi
;;
*"- \"3000:3000\""*)
if [ "$IN_REACTJS" -eq 1 ]; then
echo " - \"$APP_PORT:$APP_PORT\"" >> "$TMP_FILE"
echo "Updated ReactJS container to use port $APP_PORT"
else
echo "$LINE" >> "$TMP_FILE"
fi
;;
*)
echo "$LINE" >> "$TMP_FILE"
;;
esac
done < "$DOCKER_COMPOSE_FILE"

mv "$TMP_FILE" "$DOCKER_COMPOSE_FILE"
}

# Ensure docker-compose.yml exists
if [ ! -f "$DOCKER_COMPOSE_FILE" ]; then
echo "Warning: $DOCKER_COMPOSE_FILE not found. Skipping port updates."
else
update_docker_compose_ports
fi

echo "Environment variable and Docker Compose setup complete."
2 changes: 1 addition & 1 deletion src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ python -m generate <command> --types=<csv_path> [options]

- `--permissions` - Path to CSV file defining access control matrix
- `--default_perm` - Default permission level when no matches found:
- `AllowAll`
- `AllowAny`
- `IsAuthenticated`
- `IsAuthenticatedOrReadOnly` (default)

Expand Down
2 changes: 1 addition & 1 deletion src/django/ModelBuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ def infer_field_type(self, field_type, field_name, field):
return "models.SlugField(unique=True)"
elif field_type == "boolean":
return "models.BooleanField()"
elif field_type == "image" or field_type == 'video' or field_type == 'media':
elif field_type == "image" or field_type == 'video' or field_type == 'audio' or field_type == 'media':

self.append_import("from django.utils import timezone")
self.append_import("import os")
Expand Down
2 changes: 1 addition & 1 deletion src/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
help="Target command for the generation.")
parser.add_argument('--types', required=True, help="Path to the Object Types CSV file.")
parser.add_argument('--permissions', required=False, help="Path to the Permissions Matrix CSV file.")
parser.add_argument('--default_perm', required=False, choices=['AllowAll', 'IsAuthenticated', 'IsAuthenticatedOrReadOnly'], default='IsAuthenticatedOrReadOnly', help="Default permission when matches are not found in permissions matrix")
parser.add_argument('--default_perm', required=False, choices=['AllowAny', 'IsAuthenticated', 'IsAuthenticatedOrReadOnly'], default='IsAuthenticatedOrReadOnly', help="Default permission when matches are not found in permissions matrix")
parser.add_argument('--output_dir', required=True, help="Path to the output directory.")

args = parser.parse_args()
Expand Down
6 changes: 3 additions & 3 deletions src/templates/reactjs/access.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EntityTypes, NewEntity } from "./types";
import permissions from "./permissions.json";
import { ModelName, ModelType } from "./types";

export interface MySession {
id: number;
Expand All @@ -18,7 +18,7 @@ export type CRUDVerb = 'view_list' | 'view_profile' | 'add' | 'edit' | 'delete'

//---OBJECT-ACTIONS-PERMS-ROLES-STARTS---//

export const DEFAULT_PERM: 'AllowAny' | 'IsAuthenticated' | 'IsAuthenticatedOrReadOnly' = 'IsAuthenticatedOrReadOnly';
export const DEFAULT_PERM: 'AllowAny' | 'IsAuthenticated' | 'IsAuthenticatedOrReadOnly' = 'AllowAny';

export type PermRoles = 'anonymous' | 'authenticated' | 'verified' | 'paid user' | 'admin' | 'rally attendee' | 'city sponsor' | 'city official' | 'rally speaker' | 'rally moderator';
//---OBJECT-ACTIONS-PERMS-ROLES-ENDS---//
Expand Down Expand Up @@ -46,7 +46,7 @@ function getPermsByTypeAndVerb(type: string, verb: string) {
// returns error string or true if passes
export function canDo(
verb: CRUDVerb,
obj: EntityTypes | NewEntity,
obj: ModelType<ModelName>,
me?: MySession | null
): boolean | string {
const perms = getPermsByTypeAndVerb(obj._type, verb);
Expand Down
Loading

0 comments on commit c838bcb

Please sign in to comment.