Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

338 init custom instructions #353

Merged
merged 7 commits into from
Dec 8, 2024
Merged
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
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
Loading