Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ jobs:
with:
useLockFile: false

- name: ⚙️ Build
run: npm run build

- name: 🐳 Docker compose
# the sleep is just there to give time for postgres to get started
run: docker-compose up -d && sleep 3
Expand All @@ -111,9 +114,6 @@ jobs:
- name: 🛠 Setup Database
run: npx prisma migrate reset --force

- name: ⚙️ Build
run: npm run build

- name: 🌳 Cypress run
uses: cypress-io/github-action@v4
with:
Expand Down
31 changes: 31 additions & 0 deletions nx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"extends": "nx/presets/core.json",
"npmScope": "remix",
"tasksRunnerOptions": {
"default": {
"runner": "nx/tasks-runners/default",
"options": {
"cacheableOperations": [
"build-all",
"validate-all",
"build:css",
"build:remix",
"build:server",
"typecheck",
"test:run",
"lint",
"test:e2e:run"
]
}
}
},
"cli": {
"defaultProjectName": "blues-stack-template"
},
"pluginsConfig": {
"@nrwl/js": {
"analyzeSourceFiles": true,
"analyzePackageJson": true
}
}
}
19 changes: 9 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,26 @@
"private": true,
"sideEffects": false,
"scripts": {
"build": "run-s build:*",
"build:css": "npm run generate:css -- --minify",
"build:css": "tailwindcss -o ./app/styles/tailwind.css --minify",
"build:remix": "remix build",
"build:server": "esbuild --platform=node --format=cjs ./server.ts --outdir=build --bundle",
"dev": "run-p dev:*",
"dev:server": "cross-env NODE_ENV=development node --inspect --require ./node_modules/dotenv/config --require ./mocks ./build/server.js",
"dev:build": "cross-env NODE_ENV=development npm run build:server -- --watch",
"dev:server": "cross-env NODE_ENV=development nodemon --inspect --require ./node_modules/dotenv/config --require ./mocks ./build/server.js --watch ./build/server.js",
"dev:build": "cross-env NODE_ENV=development esbuild --platform=node --format=cjs ./server.ts --outdir=build --bundle --sourcemap --watch",
"dev:remix": "cross-env NODE_ENV=development remix watch",
"dev:css": "cross-env NODE_ENV=development npm run generate:css -- --watch",
"dev:css": "cross-env NODE_ENV=development tailwindcss -o ./app/styles/tailwind.css --watch",
"docker": "docker-compose up -d",
"format": "prettier --write .",
"generate:css": "tailwindcss -o ./app/styles/tailwind.css",
"lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .",
"setup": "prisma generate && prisma migrate deploy && prisma db seed",
"start": "cross-env NODE_ENV=production node ./build/server.js",
"start:mocks": "cross-env NODE_ENV=production node --require ./mocks --require dotenv/config ./build/server.js",
"test": "vitest",
"test:e2e:dev": "start-server-and-test dev http://localhost:3000 \"npx cypress open\"",
"pretest:e2e:run": "npm run build",
"test:e2e:run": "cross-env PORT=8811 start-server-and-test start:mocks http://localhost:8811 \"npx cypress run\"",
"typecheck": "tsc -b && tsc -b cypress",
"validate": "run-p \"test -- --run\" lint typecheck test:e2e:run"
"build": "nx build-all",
"dev": "nx dev-all",
"validate": "nx validate-all"
},
"prettier": {},
"eslintIgnore": [
Expand Down Expand Up @@ -74,7 +72,8 @@
"eslint-config-prettier": "^8.5.0",
"happy-dom": "^5.2.0",
"msw": "^0.42.1",
"npm-run-all": "^4.1.5",
"nodemon": "^2.0.18",
"nx": "^14.3.6",
"postcss": "^8.4.14",
"prettier": "^2.6.2",
"prettier-plugin-tailwindcss": "^0.1.11",
Expand Down
121 changes: 121 additions & 0 deletions project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
{
"name": "blues-stack-template",
"targets": {
"dev-all": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "nx dev:server blues-stack-template",
"prefix": "[SERVER]",
"color": "blue"
},
{
"command": "nx dev:build blues-stack-template",
"prefix": "[BUILD-]",
"color": "green"
},
{
"command": "nx dev:remix blues-stack-template",
"prefix": "[REMIX-]",
"color": "yellow"
},
{
"command": "nx dev:css blues-stack-template",
"prefix": "[CSS---]",
"color": "cyan"
}
],
"__unparsed__": []
}
},
"validate-all": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "nx test blues-stack-template --run",
"prefix": "[test-----]",
"color": "blue"
},
{
"command": "nx lint blues-stack-template",
"prefix": "[lint-----]",
"color": "green"
},
{
"command": "nx typecheck blues-stack-template",
"prefix": "[typecheck]",
"color": "yellow"
},
{
"command": "nx test:e2e:run blues-stack-template",
"prefix": "[e2e------]",
"color": "cyan"
}
],
"__unparsed__": []
}
},
"build-all": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "nx build:server blues-stack-template",
"prefix": "[SERVER]",
"color": "blue"
},
{
"command": "nx build:remix blues-stack-template",
"prefix": "[REMIX-]",
"color": "yellow"
}
],
"__unparsed__": []
}
},
"build:remix": {
"executor": "nx:run-script",
"options": {
"script": "build:remix",
"__unparsed__": []
},
"outputs": ["/build/index.js", "/public/build"],
"dependsOn": ["build:css"]
},
"dev:build": {
"executor": "nx:run-script",
"options": {
"script": "dev:build",
"__unparsed__": []
},
"outputs": ["/build/server.js"]
},
"build:css": {
"executor": "nx:run-script",
"options": {
"script": "build:css",
"__unparsed__": []
},
"outputs": ["/app/styles/tailwind.css"]
},
"test:e2e:run": {
"executor": "nx:run-script",
"options": {
"script": "test:e2e:run",
"__unparsed__": []
},
"outputs": ["/cypress/screenshots", "/cypress/videos"],
"dependsOn": ["build-all"]
},
"test:e2e:dev": {
"executor": "nx:run-script",
"options": {
"script": "test:e2e:dev",
"__unparsed__": []
},
"dependsOn": ["build-all"]
}
}
}
95 changes: 39 additions & 56 deletions remix.init/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,58 @@ const crypto = require("crypto");
const fs = require("fs/promises");
const path = require("path");

const toml = require("@iarna/toml");
const sort = require("sort-package-json");

function escapeRegExp(string) {
// $& means the whole matched string
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}

function getRandomString(length) {
return crypto.randomBytes(length).toString("hex");
}

async function main({ rootDirectory }) {
const README_PATH = path.join(rootDirectory, "README.md");
const FLY_TOML_PATH = path.join(rootDirectory, "fly.toml");
const EXAMPLE_ENV_PATH = path.join(rootDirectory, ".env.example");
const ENV_PATH = path.join(rootDirectory, ".env");
const PACKAGE_JSON_PATH = path.join(rootDirectory, "package.json");

const REPLACER = "blues-stack-template";

const DIR_NAME = path.basename(rootDirectory);
const SUFFIX = getRandomString(2);

const APP_NAME = (DIR_NAME + "-" + SUFFIX)
const APP_NAME = path.basename(rootDirectory);
const APP_ID = (APP_NAME + "-" + getRandomString(2))
// get rid of anything that's not allowed in an app name
.replace(/[^a-zA-Z0-9-_]/g, "-");

const [prodContent, readme, env, packageJson] = await Promise.all([
fs.readFile(FLY_TOML_PATH, "utf-8"),
fs.readFile(README_PATH, "utf-8"),
fs.readFile(EXAMPLE_ENV_PATH, "utf-8"),
fs.readFile(PACKAGE_JSON_PATH, "utf-8"),
]);
// copy files
const filesToCopy = [["remix.init/gitignore", ".gitignore"]];
for (const [from, to] of filesToCopy) {
await fs.copyFile(
path.join(rootDirectory, from),
path.join(rootDirectory, to)
);
}

// update env to have SESSION_SECRET
const EXAMPLE_ENV_PATH = path.join(rootDirectory, ".env.example");
const ENV_PATH = path.join(rootDirectory, ".env");
const env = await fs.readFile(EXAMPLE_ENV_PATH, "utf-8");
const newEnv = env.replace(
/^SESSION_SECRET=.*$/m,
`SESSION_SECRET="${getRandomString(16)}"`
);

const prodToml = toml.parse(prodContent);
prodToml.app = prodToml.app.replace(REPLACER, APP_NAME);

const newReadme = readme.replace(
new RegExp(escapeRegExp(REPLACER), "g"),
APP_NAME
);

const newPackageJson =
JSON.stringify(
sort({ ...JSON.parse(packageJson), name: APP_NAME }),
null,
2
) + "\n";

await Promise.all([
fs.writeFile(FLY_TOML_PATH, toml.stringify(prodToml)),
fs.writeFile(README_PATH, newReadme),
fs.writeFile(ENV_PATH, newEnv),
fs.writeFile(PACKAGE_JSON_PATH, newPackageJson),
fs.copyFile(
path.join(rootDirectory, "remix.init", "gitignore"),
path.join(rootDirectory, ".gitignore")
),
fs.rm(path.join(rootDirectory, ".github/ISSUE_TEMPLATE"), {
recursive: true,
}),
fs.rm(path.join(rootDirectory, ".github/PULL_REQUEST_TEMPLATE.md")),
]);
await fs.writeFile(ENV_PATH, newEnv);

// delete files only needed for the template
const filesToDelete = [
".github/ISSUE_TEMPLATE",
".github/PULL_REQUEST_TEMPLATE.md",
];
for (const file of filesToDelete) {
await fs.rm(path.join(rootDirectory, file), { recursive: true });
}

// replace "blues-stack-template" in all files with the app name
const filesToReplaceIn = [
"README.md",
"package.json",
"fly.toml",
"project.json",
"nx.json",
];
for (const file of filesToReplaceIn) {
const filePath = path.join(rootDirectory, file);
const contents = await fs.readFile(filePath, "utf-8");
const newContents = contents.replace(/blues-stack-template/g, APP_ID);
await fs.writeFile(filePath, newContents);
}

console.log(
`
Expand Down
10 changes: 0 additions & 10 deletions remix.init/package.json

This file was deleted.