Skip to content

Commit

Permalink
Merge pull request #353 from Vandivier/338-init-custom-instructions
Browse files Browse the repository at this point in the history
338 init custom instructions
  • Loading branch information
Vandivier authored Dec 8, 2024
2 parents 37aff1c + cb0be06 commit 6572fab
Show file tree
Hide file tree
Showing 42 changed files with 16,002 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"orta.vscode-jest",
"prisma.prisma",
"stylelint.vscode-stylelint",
"jmkrivocapich.drawfolderstructure"
"jmkrivocapich.drawfolderstructure",
"DavidAnson.vscode-markdownlint"
],
"unwantedRecommendations": []
}
5 changes: 4 additions & 1 deletion ladderly-io/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,7 @@ yarn-error.log*
*.tsbuildinfo

# idea files
.idea
.idea

# python
.venv
4 changes: 2 additions & 2 deletions ladderly-io/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ladderly-io",
"version": "0.1.0",
"private": true,
"version": "0.1.1",
"private": false,
"type": "module",
"scripts": {
"build": "next build",
Expand Down
101 changes: 101 additions & 0 deletions ladderly-io/scripts/backupChecklists.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
const fs = require('fs-extra')
const path = require('path')

require('dotenv').config({ path: path.resolve(__dirname, '../.env.local') })

const { PrismaClient } = require('@prisma/client')

const prisma = new PrismaClient()

const backup = async () => {
const checklistNames = await prisma.checklist.groupBy({
by: ['name'],
})

let checklists = []

for (const { name } of checklistNames) {
const checklist = await prisma.checklist.findFirst({
where: { name },
orderBy: { createdAt: 'desc' },
include: {
checklistItems: {
orderBy: {
displayIndex: 'asc',
},
},
},
})
checklists.push(checklist)
}

const existingChecklistsRaw = fs.readFileSync(
path.resolve(__dirname, '../db/checklists.json')
)
let existingChecklists = JSON.parse(existingChecklistsRaw.toString())
const existingChecklistNames = existingChecklists.map(
(checklist) => checklist.name
)

const premiumChecklistsPath = path.resolve(
__dirname,
'../db/premium-checklists.json'
)
let premiumChecklists = []

if (fs.existsSync(premiumChecklistsPath)) {
const premiumChecklistsRaw = fs.readFileSync(premiumChecklistsPath)
premiumChecklists = JSON.parse(premiumChecklistsRaw.toString())
}

for (const checklist of checklists) {
const { name, version, checklistItems } = checklist
const items = checklistItems.map((item) => {
if (
item.linkText === '' &&
item.linkUri === '' &&
item.isRequired === true &&
item.detailText === ''
) {
return item.displayText
} else {
return {
detailText: item.detailText,
displayText: item.displayText,
isRequired: item.isRequired,
linkText: item.linkText,
linkUri: item.linkUri,
}
}
})

const checklistData = { name, version, items }

if (existingChecklistNames.includes(name)) {
existingChecklists = existingChecklists.map((checklist) =>
checklist.name === name ? checklistData : checklist
)
} else {
premiumChecklists.push(checklistData)
}
}

fs.writeFileSync(
path.resolve(__dirname, '../db/checklists.json'),
JSON.stringify(existingChecklists, null, 2)
)
fs.writeFileSync(
premiumChecklistsPath,
JSON.stringify(premiumChecklists, null, 2)
)

console.log('Checklist backup completed!')
}

backup()
.catch((e) => {
throw e
})
.finally(async () => {
await prisma.$disconnect()
})
26 changes: 26 additions & 0 deletions ladderly-io/scripts/backupUsers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const fs = require('fs-extra')
const path = require('path')

require('dotenv').config({ path: path.resolve(__dirname, '../.env.local') })

const { PrismaClient } = require('@prisma/client')

const prisma = new PrismaClient()

async function backupUsers() {
const users = await prisma.user.findMany()
const jsonUsers = JSON.stringify(users, null, 2)
const date = new Date()
const isoDate = date.toISOString().replace(/:/g, '-')
const fileName = `./db/bak.users.${isoDate}.json`
await fs.writeFile(fileName, jsonUsers)
console.log(`Backup of ${users.length} users completed!`)
}

backupUsers()
.catch((e) => {
throw e
})
.finally(async () => {
await prisma.$disconnect()
})
81 changes: 81 additions & 0 deletions ladderly-io/scripts/cascadeDeleteChecklist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import path from 'path'

require('dotenv').config({ path: path.resolve(__dirname, '../.env.local') })

import db from '../db'

async function deleteChecklist(checklistId: number) {
const checklist = await db.checklist.findUnique({
where: { id: checklistId },
})

if (!checklist) {
throw new Error(`Checklist with ID ${checklistId} not found.`)
}

// Cascade delete userChecklistItems related to this checklist
await db.userChecklistItem.deleteMany({
where: {
userChecklist: {
checklistId: checklistId,
},
},
})

// Cascade delete userChecklists related to this checklist
await db.userChecklist.deleteMany({
where: { checklistId },
})

// Cascade delete checklistItems related to this checklist
await db.checklistItem.deleteMany({
where: { checklistId },
})

// Finally, delete the checklist itself
await db.checklist.delete({
where: { id: checklistId },
})

console.log(
`Checklist with ID ${checklistId} and all related entities have been deleted.`
)
}

// Main script execution
const main = async () => {
const checklistIdAsStr =
process.argv
.find((arg) => arg.startsWith('--checklistId='))
?.split('=')[1] || ''
const checklistId = parseInt(checklistIdAsStr, 10)

if (!checklistId) {
console.log(
'Did not receive a valid checklistId. \n' +
'Received: ' +
checklistIdAsStr +
'\n' +
'From the scripts/ dir, call this script like:\n' +
'`npx ts-node -P tsconfig.script.json scripts/cascadeDeleteChecklist.ts --checklistId=123`\n' +
'Exiting.'
)
process.exit(1)
}

try {
await deleteChecklist(checklistId)
process.exit(0)
} catch (error) {
console.error('An error occurred:', error)
process.exit(1)
}
}

main()
.catch((e) => {
throw e
})
.finally(async () => {
await db.$disconnect()
})
123 changes: 123 additions & 0 deletions ladderly-io/scripts/ci/custom-blog-lint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// run this from the root dir, `ladderly-3/`
// optionally pass the autofix flag, like so:
// `node scripts/ci/custom-blog-lint.js --autofix`

const fs = require('fs')
const path = require('path')
const matter = require('gray-matter')

const BLOG_DIR = path.join(process.cwd(), 'src', 'app', 'blog')
const VOTABLES_PATH = path.join(
process.cwd(),
'db',
'seed-utils',
'votables.json'
)

/**
* @typedef {Object} BlogInfo
* @property {string} filename
* @property {string} title
*/

/**
* @typedef {Object} Votable
* @property {string} type
* @property {string} name
* @property {string} website
* @property {string[]} tags
*/

/**
* @returns {BlogInfo[]}
*/
function getBlogInfo() {
return fs
.readdirSync(BLOG_DIR)
.filter((file) => file.endsWith('.md'))
.map((file) => {
const content = fs.readFileSync(path.join(BLOG_DIR, file), 'utf-8')
const { data } = matter(content)
return {
filename: file.replace('.md', ''),
title: data.title || '',
}
})
}

/**
* @returns {Votable[]}
*/
function getVotables() {
const votablesContent = fs.readFileSync(VOTABLES_PATH, 'utf-8')
return JSON.parse(votablesContent)
}

/**
* @param {Votable[]} votables
*/
function saveVotables(votables) {
fs.writeFileSync(VOTABLES_PATH, JSON.stringify(votables, null, 2))
}

/**
* @param {boolean} autofix
*/
function checkBlogArticlesInVotables(autofix) {
const blogInfo = getBlogInfo()
const votables = getVotables()

/** @type {BlogInfo[]} */
const missingArticles = []

for (const info of blogInfo) {
const isInVotables = votables.some(
(votable) =>
votable.type === 'CONTENT' &&
votable.website === `https://www.ladderly.io/blog/${info.filename}`
)

if (!isInVotables) {
missingArticles.push(info)
}
}

if (missingArticles.length > 0) {
console.error('The following blog articles are missing from votables.json:')
missingArticles.forEach((article) => {
console.error(`- ${article.filename}`)
const newVotable = {
type: 'CONTENT',
name: article.title,
website: `https://www.ladderly.io/blog/${article.filename}`,
tags: ['Ladderly.io Article'],
}

if (autofix) {
votables.push(newVotable)
console.log(`Added ${article.filename} to votables.json`)
} else {
console.error('Suggested JSON snippet to add:')
console.error(JSON.stringify(newVotable, null, 2))
console.error('\n')
}
})

if (autofix) {
saveVotables(votables)
console.log('votables.json has been updated.')
} else {
console.error(
'Run with --autofix to automatically add missing articles to votables.json'
)
process.exit(1) // Exit with an error code
}
} else {
console.log('All blog articles are included in votables.json')
}
}

// Check if --autofix flag is provided
const autofix = process.argv.includes('--autofix')

checkBlogArticlesInVotables(autofix)
Loading

0 comments on commit 6572fab

Please sign in to comment.