2
0

🛂 Add backup and restore database scripts

This commit is contained in:
Baptiste Arnaud
2022-11-23 11:40:57 +01:00
parent d80cc1b248
commit 3645607ed4
10 changed files with 107 additions and 43 deletions

1
.gitignore vendored
View File

@ -27,5 +27,6 @@ firebaseServiceAccount.json
tags tags
dump.sql dump.sql
dump.tar
__env.js __env.js

View File

@ -0,0 +1,22 @@
import { exec } from 'child_process'
import { promptAndSetEnvironment } from './utils'
const backupDatabase = async () => {
await promptAndSetEnvironment()
exec(
`pg_dump ${process.env.DATABASE_URL} -F c > dump.tar`,
(error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`)
return
}
if (stderr) {
console.log(`stderr: ${stderr}`)
return
}
console.log(`stdout: ${stdout}`)
}
)
}
backupDatabase()

View File

@ -1,22 +0,0 @@
import { PrismaClient } from 'db'
import path from 'path'
import { setCustomPlan } from './setCustomPlan'
require('dotenv').config({
path: path.join(
__dirname,
process.env.NODE_ENV === 'production'
? '.env.production'
: process.env.NODE_ENV === 'staging'
? '.env.staging'
: '.env.local'
),
})
const prisma = new PrismaClient({ log: ['query', 'info', 'warn', 'error'] })
const main = async () => {
setCustomPlan()
}
main().then()

View File

@ -5,17 +5,19 @@
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"private": true, "private": true,
"scripts": { "scripts": {
"start:local": "tsx index.ts", "playground": "tsx playground.ts",
"start:staging": "NODE_ENV=staging tsx index.ts", "db:backup": "tsx backupDatabase.ts",
"start:prod": "NODE_ENV=production tsx index.ts" "db:restore": "tsx restoreDatabase.ts",
"db:setCustomPlan": "tsx setCustomPlan.ts"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "18.11.9", "@types/node": "18.11.9",
"axios": "^1.1.3", "@types/prompts": "^2.4.1",
"db": "workspace:*", "db": "workspace:*",
"emails": "workspace:*", "emails": "workspace:*",
"got": "12.5.3", "got": "12.5.3",
"models": "workspace:*", "models": "workspace:*",
"prompts": "^2.4.2",
"stripe": "11.1.0", "stripe": "11.1.0",
"tsx": "3.12.1", "tsx": "3.12.1",
"typescript": "4.9.3", "typescript": "4.9.3",

View File

@ -0,0 +1,9 @@
import { PrismaClient } from 'db'
import { promptAndSetEnvironment } from './utils'
const executePlayground = async () => {
await promptAndSetEnvironment()
const prisma = new PrismaClient({ log: ['query', 'info', 'warn', 'error'] })
}
executePlayground()

View File

@ -0,0 +1,23 @@
import { exec } from 'child_process'
import { promptAndSetEnvironment } from './utils'
const restoreDatabase = async () => {
await promptAndSetEnvironment()
exec(
`pg_restore -d ${process.env.DATABASE_URL} -c dump.tar`,
(error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`)
return
}
if (stderr) {
console.log(`stderr: ${stderr}`)
return
}
console.log(`stdout: ${stdout}`)
}
)
}
restoreDatabase()

View File

@ -1,9 +1,10 @@
import { Plan, PrismaClient } from 'db' import { Plan, PrismaClient } from 'db'
import Stripe from 'stripe' import Stripe from 'stripe'
import { promptAndSetEnvironment } from './utils'
const prisma = new PrismaClient() const setCustomPlan = async () => {
await promptAndSetEnvironment()
export const setCustomPlan = async () => { const prisma = new PrismaClient()
if ( if (
!process.env.STRIPE_SECRET_KEY || !process.env.STRIPE_SECRET_KEY ||
!process.env.STRIPE_PRODUCT_ID || !process.env.STRIPE_PRODUCT_ID ||
@ -81,3 +82,5 @@ export const setCustomPlan = async () => {
console.log('Claimable plan updated!') console.log('Claimable plan updated!')
} }
setCustomPlan()

27
packages/scripts/utils.ts Normal file
View File

@ -0,0 +1,27 @@
import { join } from 'path'
import prompts from 'prompts'
import { isEmpty } from 'utils'
export const promptAndSetEnvironment = async () => {
const response = await prompts({
type: 'select',
name: 'env',
message: 'Pick an environment',
choices: [
{
title: 'Local',
value: 'local',
},
{ title: 'Staging', value: 'staging' },
{ title: 'Production', value: 'production' },
],
initial: 0,
})
if (isEmpty(response.env)) process.exit()
require('dotenv').config({
override: true,
path: join(__dirname, `.env.${response.env}`),
})
}

23
pnpm-lock.yaml generated
View File

@ -554,22 +554,24 @@ importers:
packages/scripts: packages/scripts:
specifiers: specifiers:
'@types/node': 18.11.9 '@types/node': 18.11.9
axios: ^1.1.3 '@types/prompts': ^2.4.1
db: workspace:* db: workspace:*
emails: workspace:* emails: workspace:*
got: 12.5.3 got: 12.5.3
models: workspace:* models: workspace:*
prompts: ^2.4.2
stripe: 11.1.0 stripe: 11.1.0
tsx: 3.12.1 tsx: 3.12.1
typescript: 4.9.3 typescript: 4.9.3
utils: workspace:* utils: workspace:*
devDependencies: devDependencies:
'@types/node': 18.11.9 '@types/node': 18.11.9
axios: 1.1.3 '@types/prompts': 2.4.1
db: link:../db db: link:../db
emails: link:../emails emails: link:../emails
got: 12.5.3 got: 12.5.3
models: link:../models models: link:../models
prompts: 2.4.2
stripe: 11.1.0 stripe: 11.1.0
tsx: 3.12.1 tsx: 3.12.1
typescript: 4.9.3 typescript: 4.9.3
@ -5784,6 +5786,12 @@ packages:
resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==} resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==}
dev: true dev: true
/@types/prompts/2.4.1:
resolution: {integrity: sha512-1Mqzhzi9W5KlooNE4o0JwSXGUDeQXKldbGn9NO4tpxwZbHXYd+WcKpCksG2lbhH7U9I9LigfsdVsP2QAY0lNPA==}
dependencies:
'@types/node': 18.11.9
dev: true
/@types/prop-types/15.7.5: /@types/prop-types/15.7.5:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
@ -7025,16 +7033,6 @@ packages:
- debug - debug
dev: false dev: false
/axios/1.1.3:
resolution: {integrity: sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==}
dependencies:
follow-redirects: 1.15.2
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
dev: true
/axobject-query/2.2.0: /axobject-query/2.2.0:
resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==}
dev: false dev: false
@ -15062,6 +15060,7 @@ packages:
/proxy-from-env/1.1.0: /proxy-from-env/1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: false
/pseudomap/1.0.2: /pseudomap/1.0.2:
resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}

View File

@ -5,11 +5,11 @@
"outputs": [] "outputs": []
}, },
"dev": { "dev": {
"dependsOn": ["^dev", "^db:generate", "^db:push"], "dependsOn": ["^dev", "db#db:generate", "db#db:push"],
"cache": false "cache": false
}, },
"build": { "build": {
"dependsOn": ["^build", "^db:generate"], "dependsOn": ["^build", "db#db:generate"],
"outputs": [".next/**", "dist/**", "build/**"], "outputs": [".next/**", "dist/**", "build/**"],
"outputMode": "new-only" "outputMode": "new-only"
}, },